I have calibrated a set of cameras using my own custom software and stored the parameters in a json file.
I am using the python api to load my camera calibration from json files into agisoft and attempting to build a dense point cloud. The script loads the cameras in the correct positions, builds the sparse point cloud which again looks reasonable but then fails on the dense reconstruction giving a 'Zero Resolution Error'. I included a regionReset before building the builddensecloud as this error often relates to incorrect region size. I have also checked that there are enough features and matches approximately 3500 points per image and 5865 tie points.
In an attempt to debug this error i exported the camera parameters from agisoft (see below). I noticed that the camera sensor resolution is of width and height 0 despite being set. Also from the documentation, cx and cy parameters are relative to the image centre, but the sparse reconstruction only looks correct if these are set to the absolute value. This suggests that the sensor size is not being correctly initialised through the python api.
Any help with this would be appreciated.
Here is the script:
#!/usr/bin/python
import json
from pprint import pprint
import PhotoScan
camera_file = 'camera.%02d.json'
camera_image = 'image.%02d.png'
camera_start = 1
camera_stop = 20
chunk = PhotoScan.app.document.addChunk()
for camera_index in range(camera_start, camera_stop+1):
with open(camera_file%camera_index) as data_file:
data = json.load(data_file)
#Create Camera
camera = chunk.addCamera();
#Add Image
camera.label = "Camera %02d"%camera_index
photo_file = camera_image%camera_index
camera.open(photo_file)
#Get Rotation
matrix = PhotoScan.Matrix().Diag([1,1,1,1])
for i in range(0, 3):
for j in range(0, 3):
matrix[i,j] = float(data["camera"]["r"][i*3+j])
# Translation
matrix[0,3] = float(data["camera"]["t"][0])
matrix[1,3] = float(data["camera"]["t"][1])
matrix[2,3] = float(data["camera"]["t"][2])
# invert matrix
camera.transform = matrix.inv()
#Create Calibration
calibration = PhotoScan.Calibration()
calibration.width = int(data["camera"]["width"])
calibration.height = int(data["camera"]["height"])
calibration.cx = float(data["camera"]["cx"])
calibration.cy = float(data["camera"]["cy"])
calibration.f = float(data["camera"]["fy"])
calibration.b1 = float(data["camera"]["fx"])-float(data["camera"]["fy"])
calibration.b2 = float(data["camera"]["skew"])
calibration.k1 = float(data["camera"]["distortion"][0])
calibration.k2 = float(data["camera"]["distortion"][1])
calibration.p1 = float(data["camera"]["distortion"][2])
calibration.p2 = float(data["camera"]["distortion"][3])
calibration.k3 = float(data["camera"]["distortion"][4])
#Create Sensor
camera.sensor = chunk.addSensor();
camera.sensor.user_calib = calibration
camera.sensor.calibration = calibration
camera.sensor.label = camera.label
camera.sensor.type = PhotoScan.Sensor.Type.Frame
camera.sensor.width = int(data["camera"]["width"])
camera.sensor.height = int(data["camera"]["height"])
camera.sensor.fixed = True
# Match Photos
chunk.matchPhotos(accuracy=PhotoScan.HighQuality, preselection=PhotoScan.NoPreselection,keypoint_limit=40000,tiepoint_limit=4000, filter_mask=False)
#Build Sparse Reconstruction
chunk.buildPoints()
# Reset Region
chunk.resetRegion()
#Build Point Cloud
chunk.buildDenseCloud(quality=PhotoScan.HighQuality)
Here is a snippet from the exported calibration
<?xml version="1.0" encoding="UTF-8"?>
<document version="1.2.0">
<chunk>
<sensors>
<sensor id="0" label="Camera 01" type="frame">
<resolution width="2448" height="2048"/>
<property name="fixed" value="true"/>
<calibration type="frame" class="initial">
<resolution width="0" height="0"/>
<fx>2259.2257678318952</fx>
<fy>2258.0792439942561</fy>
<cx>1244.9551486807138</cx>
<cy>1035.0740703194135</cy>
<k1>-0.078427925999999995</k1>
<k2>0.15065549</k2>
<k3>-0.12147871</k3>
<p1>0.0013411323</p1>
<p2>-6.7674315000000005e-05</p2>
</calibration>
<calibration type="frame" class="adjusted">
<resolution width="0" height="0"/>
<fx>2259.2257678318952</fx>
<fy>2258.0792439942561</fy>
<cx>1244.9551486807138</cx>
<cy>1035.0740703194135</cy>
<k1>-0.078427925999999995</k1>
<k2>0.15065549</k2>
<k3>-0.12147871</k3>
<p1>0.0013411323</p1>
<p2>-6.7674315000000005e-05</p2>
</calibration>
</sensor>