I want to be able to compute projected CRS X,Y,Z from an image pixel coordinates (x,y). I dug around and found CV formulas for doing this and also found some nice code in this forum for generating much of the necessary pieces. I put together the following code to compare the difference between the Estimated Marker Coordinates in a CRS to those computed using the CV formulas (i.e. x = uZ/f).
The differences were much greater than I expected, especially in the marker's Z value. I would have anticipated some variation due to things like not using an undistorted photo and bundle adjustment but I'd like to understand the difference more fully if someone can explain it.
Below values are in iFT:
CV formula crs coords (1 cam): Vector([595046.6607458998, 1078727.1350278414, 215.01010265754007])
Estimated marker crs coords: Vector([595033.9718577337, 1078666.6464214365, 241.21929559608662])
#Compare Marker Coords Calculated from Depth Versus Estimated From Model Alignment
import PhotoScan
chunk = PhotoScan.app.document.chunk #active chunk
scale = chunk.transform.scale
camera = chunk.cameras[0] #first camera in the chunk
depth = chunk.model.renderDepth(camera.transform, camera.sensor.calibration) #unscaled depth
depth_scaled = PhotoScan.Image(depth.width, depth.height, " ", "F32")
v_min = 10E10
v_max = -10E10
#create array of distance values
for y in range(depth.height):
for x in range(depth.width):
depth_scaled[x,y] = (depth[x,y][0] * scale, )
marker = curr_chunk.markers[0] #first marker
x0,y0 = marker.projections[camera].coord
x1 = int(x0) #marker pixel coords in first camera
y1 = int(y0)
cam_Z = depth_scaled[x1,y1][0] #marker distance from camera
focal_length = chunk.sensors[0].calibration.f #camera focal length
cX = chunk.sensors[0].calibration.cx #camera center
cY = chunk.sensors[0].calibration.cy
u = x1 - cX #col offset from image center
v = y1 - cY #row offset from image center
cam_X = u*cam_Z/focal_length #camera coordinates X
cam_Y = v*cam_Z/focal_length #camera coordinates Y
cam_vector = PhotoScan.Vector([cam_X, cam_Y, cam_Z]) #convert to vector
chunk_matrix = chunk.transform.matrix
coord_geoc = chunk_matrix.mulp(cam_vector) #geocentric coordinates
coord_proj = chunk.crs.project(coord_geoc) #projected coordinates
print ('CV formula crs coords (1 cam): ',coord_proj)
coord_proj2 = chunk.crs.project(chunk_matrix.mulp(marker.position)) #compute projected coordinates (estimated)
print ('Estimated marker crs coords: ',coord_proj2)