Forum

Author Topic: Setting bounding box relative to world grid coordinates  (Read 3120 times)

talldrinks

  • Newbie
  • *
  • Posts: 13
    • View Profile
Setting bounding box relative to world grid coordinates
« on: January 22, 2018, 06:09:27 PM »
Hello.
When I reconstruct, I also import a camera position CSV file as reference. This properly scales and orients the scene to the Agisoft grid axes reliably.

My issue is that I want programmatically scale and orient the build region after this step. My script below is run after alignment and importing the CSV file (which does correctly scale and orient the entire camera rig).
It appears that the region parameters are always in relation to one of the aligned cameras, and doesn't seem to be the same camera every time, so I'm having trouble reliably placing the build region box at the center of the rig on the ground plane where I need it. I can offset and rotate the box, but since its relative to some camera each build, it's not reliable.

How can I best place the region in my chunk at an absolute position in world space (for instance, at 0.0,0.0,2.0 and scaled to 3.5,3.5,4.0)?

Thank you!

My script: (apologies, the code tag button is not working in Edge browser)
<code>
#load CSV reference file
   try:
      #import csv reference for scale and orientation
      csvFilePath = (path+"/CameraData/CamData.csv")
      print("Loading references from "+csvFilePath)
      chunk.loadReference(csvFilePath,PhotoScan.ReferenceFormat.ReferenceFormatCSV,'nxyzXYZ',',')
      chunk.updateTransform()
      print("loaded references!")
   except:
      print("couldn't load references")
   
   #set volume bounding box
   print("===Setting Bounding Box Volume===")
   new_region = PhotoScan.Region()

   new_center = PhotoScan.Vector([0.0,0.0,2.0]) #this offsets relative to some cameras Z axis, undesired
   #new_center = offset + new_rot * new_center

   x_scale = 3.5
   y_scale = 3.5
   z_scale = 4.0

   new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])

   T = PhotoScan.app.document.chunk.transform.matrix
   v_t = T * PhotoScan.Vector( [0,0,0,1] )
   m = PhotoScan.Matrix.Diag( (1,1,1,1) )

   m = m * T
   s = math.sqrt(m[0,0] ** 2 + m[0,1] ** 2 + m[0,2] ** 2) #scale factor

   R = PhotoScan.Matrix( [[m[0,0],m[0,1],m[0,2]], [m[1,0],m[1,1],m[1,2]], [m[2,0],m[2,1],m[2,2]]])
   R = R * (1.0 / s)

   new_region.size = new_size
   new_region.center = new_center
   new_region.rot = R.t()

   PhotoScan.app.document.chunk.region = new_region
   PhotoScan.app.update()
</code>

talldrinks

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Setting bounding box relative to world grid coordinates
« Reply #1 on: January 22, 2018, 06:35:52 PM »
I understand that the chunk coordinate space is local to the chunk, but I'm not clear on how to convert and position everything within real world coordinate space.

I'm confused, since the measurement tool gives me exact accurate measurements and everything is located around the 0,0,0 point of the 3D grid and aligned as expected along the XYZ view axes as well.

talldrinks

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Setting bounding box relative to world grid coordinates
« Reply #2 on: January 23, 2018, 01:31:12 AM »
Figured this out based on these posts and examples. Thanks!

http://www.agisoft.com/forum/index.php?topic=7543.0

talldrinks

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Setting bounding box relative to world grid coordinates
« Reply #3 on: January 23, 2018, 05:29:05 PM »
This snippet ended up as the solution to place the region box relative to world coordinates, thanks again:

<code>
#Switch to Local Coordinates
if chunk.crs:
   chunk.crs = None
   
crs = chunk.crs
region = chunk.region
T = chunk.transform.matrix

m = PhotoScan.Vector([10E+10, 10E+10, 10E+10])
M = -m

x_scale = 3.0
y_scale = 3.0
z_scale = 4.0
new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])
new_center = PhotoScan.Vector([0.0,0.0,2.0])

region.center = T.inv().mulp(crs.unproject(new_center))
region.size = new_size

v_t = T.mulp(region.center)
R = crs.localframe(v_t) * T
region.rot = R.rotation().t()

chunk.region = region
</code>
« Last Edit: January 23, 2018, 06:30:43 PM by talldrinks »