Forum

Author Topic: Camera coordinates to world coordinates using 4x4 matrix  (Read 33962 times)

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15710
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #15 on: December 01, 2016, 05:59:35 PM »
Hello callahb,

It looks like you are using scaled depth (real world dimensions) in combination with the internal coordinate system values, when calculating the intersection of the ray with the "depth plane".
Best regards,
Alexey Pasumansky,
Agisoft LLC

callahb

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #16 on: December 01, 2016, 06:10:52 PM »
It seems that removing the scale from the depth like below does not help:
Code: [Select]

#depth_scaled[x,y] = (depth[x,y][0] * scale, ) #old method

depth_scaled[x,y] = (depth[x,y][0] , ) #new method


Did I implement this incorrectly?

callahb

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #17 on: December 05, 2016, 05:12:48 PM »
I just can't seem to get this to work. Perhaps Alexey is correct in that there is something wrong with the Depth since the reported value doesn't correspond to the real depth from the camera which I have measured in the field.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15710
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #18 on: December 05, 2016, 05:21:36 PM »
Hello callahb,

Can you send a sample project in PSZ format to support@agisoft.com for testing? Just with the alignment results and low-poly mesh model (no need of dense cloud).
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15710
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #19 on: December 05, 2016, 07:31:29 PM »
Hello callahb,

I've got it working in the following way. So when calculating the point position I'm taking the camera center and adding the depth distance (in the internal units) along the ray from that point. Also I've added print statement for the distance between the estimated locations of marker and camera:

Code: [Select]
#Compare Marker Coords Calculated from Depth Versus Estimated From Model Alignment
import PhotoScan

chunk = PhotoScan.app.document.chunk #active chunk
T = chunk.transform.matrix
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 = chunk.markers[0] #first marker
x0, y0 = marker.projections[camera].coord

image_x = int(x0) #marker pixel coords in first camera
image_y = int(y0)

depth = depth_scaled[image_x,image_y][0] #marker distance from camera in meters
print("depth: " + str(depth))
vect = T.mulv(camera.center - marker.position) * scale
vect = vect.norm() #distance between estimated positions in meters
print("distance_est: " + str(vect))

cam_matrix = camera.transform
cam_calib = camera.sensor.calibration
chunk_matrix = chunk.transform.matrix
point_2D = PhotoScan.Vector([image_x, image_y])
vect = cam_calib.unproject(point_2D) #vector in camera crs
ray = cam_matrix.mulv(vect) #ray in chunk crs

point_chunk = camera.center + ray * depth / scale #find point

point_geoc = chunk_matrix.mulp(point_chunk)
point_crs = chunk.crs.project(point_geoc)
print ('point_crs: ',point_crs)

marker_est = chunk.crs.project(chunk_matrix.mulp(marker.position)) #compute projected coordinates (estimated)
print ('Estimated marker crs coords: ',marker_est)
« Last Edit: December 05, 2016, 08:05:31 PM by Alexey Pasumansky »
Best regards,
Alexey Pasumansky,
Agisoft LLC

callahb

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #20 on: December 05, 2016, 07:57:30 PM »
Hi Alexey,

What is the "T" object here? Its not referenced in the script.

Code: [Select]
vect = T.mulv(camera.center - marker.position) * scale

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15710
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #21 on: December 05, 2016, 08:04:57 PM »
T = chunk.transform.matrix
Best regards,
Alexey Pasumansky,
Agisoft LLC

callahb

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #22 on: December 06, 2016, 05:27:23 PM »
Alexey,

Thank you for the assistance, this seems to work very well.

I'm having a little trouble understanding the geocentric coordinate system used by PhotoScan and it's relationship to the Chunk CRS.

Is the geocentric coordinate system supposed to honor the ellipsoid from the Chunk CRS if the chunk is georeferenced? For example, if my Chunk was georeferenced using NAD83(2011) does the geocentric coordinate system use the GRS80 ellipsoid?

If so, the values appear to be offset from those generated from the US National Geodetic Survey tool XYZ Conversion. https://www.ngs.noaa.gov/TOOLS/XYZ/xyz.html

Can you help explain this?

Thanks!

callahb

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Camera coordinates to world coordinates using 4x4 matrix
« Reply #23 on: December 07, 2016, 05:42:35 PM »
My error. The values are indeed the same. So this confirms that the Geocentric coordinates do indeed honor the Ellipsoid from the Projected CRS.