Forum

Author Topic: Exporting object with camera as origin of the coordinate system  (Read 5993 times)

daxils

  • Newbie
  • *
  • Posts: 4
    • View Profile
Hi,
I am trying to export a model I reconstructed in a way that when I import it in other software I get it positioned such that a specific camera is at point (0,0,0) and the mesh is positioned relative to that.

Right now what I can do is export the mesh but I get it positioned in a seemingly random point in space when I import it in blender (while the axis are positioned at point 0).

I can't seem to do this because I'm not sure whether the chunk's transform (chunk.transform.matrix) is actually the mesh's center of mass's position or something else. I am also not sure what the doc.chunk.cameras.transform is relative to.

The endgoal for me is to be able to import the model in let's say blender and have it positioned and oriented such that a specific camera is at point 0. So basically I'm trying to find the pose of the object in the camera's reference frame.

I hope that this was clear,  but if you have any questions please do ask me and I will try to clarify.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #1 on: July 09, 2019, 02:57:09 PM »
Hello daxils,

Do you think, if the script that applies the translation to the model would be sufficient, if it keeps current model scale and orientation (rotation), while the new origin point (0,0,0) is defined by the 3D point shape, marker or assigned to any aligned camera?
Best regards,
Alexey Pasumansky,
Agisoft LLC

daxils

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #2 on: July 09, 2019, 05:51:52 PM »
Hello Alexey,

Thank you for your reply.

While I will indeed need to have the origin point at a specific location (camera's center), and to keep the scale, the orientation of the model needs to correspond to its relative rotation compared to the camera.

In other words, I need my model's frame of coordinates to be the camera.


Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #3 on: July 10, 2019, 03:22:36 PM »
Hello daxils,

Please check if the following script performs the desired operation. It moves the coordinate system origin to the center of the selected camera (only one camera should be selected) and transforms the orientation of the system, according to the camera orientation.

Code: [Select]
import Metashape

def CS_to_camera():

print("Script started...")
chunk = Metashape.app.document.chunk
if not chunk:
print("Empty project, script aborted")
return
selected = [camera for camera in chunk.cameras if camera.selected and camera.transform and (camera.type == Metashape.Camera.Type.Regular)]
if len(selected) != 1:
print("Select only one aligned camera to procees. Script aborted.")
return
camera = selected[0]
T = chunk.transform.matrix
origin = (-1) * camera.center

R = Metashape.Matrix().Rotation(camera.transform.rotation()*Metashape.Matrix().Diag([1,-1,1]))
origin = R.inv().mulp(origin)
chunk.transform.matrix = T.scale() * Metashape.Matrix().Translation(origin) * R.inv()

Metashape.app.update()


print("System set to " + camera.label + ". Script finished.")
return 1
CS_to_camera()

Metashape.app.addMenuItem("Custom menu/Coordinate system to camera", CS_to_camera)
Best regards,
Alexey Pasumansky,
Agisoft LLC

daxils

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #4 on: July 12, 2019, 11:05:12 AM »
Thank you Alexey for taking the time to code this script.
Could you explain to me the reasoning behind Diag([1,-1,1])?
« Last Edit: July 12, 2019, 12:38:33 PM by daxils »

daxils

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #5 on: July 12, 2019, 12:56:54 PM »
I think I found the solution to my problem:

Intuitively, all you need to do is

Code: [Select]
chunk.transform.matrix = chunk.transform.matrix * camera.transform.inv()

However the results for me seemed like they were incoherent with what I expected.
It turned out that this puts the camera where the chunk was previously (and orients it correctly). So if I want it to be at the origin of the coordinates system, I just have to move the chunk to the point (0,0,0) first.

Code: [Select]
chunk.transform.translation = PhotoScan.Vector((0,0,0))


I just tried this and it works like a charm.

So here is the full script (utilizing your very nice touch of adding it as a  menu option) so that other users can find it later
Code: [Select]
import PhotoScan

def CS_to_camera():

print("Script started...")
chunk = PhotoScan.app.document.chunk
if not chunk:
print("Empty project, script aborted")
return
selected = [camera for camera in chunk.cameras if camera.selected and camera.transform]
if len(selected) != 1:
print("Select only one aligned camera to procees. Script aborted.")
return
camera = selected[0]

R = camera.transform

chunk.transform.translation = PhotoScan.Vector((0,0,0))
chunk.transform.matrix = chunk.transform.matrix * R.inv()

print("System set to " + camera.label + " coordinates. Script finished.")
return 1
CS_to_camera()
PhotoScan.app.addMenuItem("Custom menu/Coordinate system to camera", CS_to_camera)


Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #6 on: July 12, 2019, 01:15:01 PM »
Could you explain to me the reasoning behind Diag([1,-1,1])?

It was meant to invert the orientation of some axis of the newly assigned coordinate system.
Best regards,
Alexey Pasumansky,
Agisoft LLC

andyroo

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #7 on: August 09, 2019, 06:02:53 AM »
I am trying to do the same I think - I have a model in a local coordinate system derived from scale bars on a calibration plate, and I am trying to get the model in the frame of reference of one camera (camera at origin and zero the pitch/roll/yaw).

I didn't have much luck with could only rotate the coordinate system to the camera orientation with Alexey's code, and I could only translate the coordinate system to the camera origin with daxils code (with minor tweak):
Code: [Select]
chunk.transform.translation = Metashape.Vector([0,0,0])But can't figure out how to integrate both!

Looking at the two different chunk.transform.matrices I can see that the T.scale() factor is changing the scale, but I'm unclear exactly what that's for - it looks like it makes the rotations work but breaks the translation? Sorry linear algebra and rotation matrices aren't my forte.  Any help is appreciated.

My code:
Code: [Select]
doc = Metashape.app.document
chunk = doc.chunk
camera = chunk.cameras[2]
#below moves coordinate system origin to camera origin, but doesn't rotate everything nicely:
R = camera.transform
chunk.transform.translation = Metashape.Vector([0,0,0])
chunk.transform.matrix = chunk.transform.matrix * R.inv()
#below (instead of 3 lines above) rotates coordinate system to camera pose, but doesn't translate properly
T = chunk.transform.matrix
origin = (-1) * camera.center
R = Metashape.Matrix().Rotation(camera.transform.rotation()*Metashape.Matrix().Diag([1,-1,1]))
origin = R.inv().mulp(origin)
chunk.transform.matrix = T.scale() * Metashape.Matrix().Translation(origin) * R.inv()
« Last Edit: August 09, 2019, 10:38:43 PM by andyroo »

andyroo

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: Exporting object with camera as origin of the coordinate system
« Reply #8 on: August 16, 2019, 04:40:53 AM »
OK figured it out. If I get rid of  the T.scale() factor that I didn't understand, I love everything. final code below:

Code: [Select]
doc = Metashape.app.document
chunk = doc.chunk
camera = chunk.cameras[2]
#below rotates and translates everything to camera frame of reference
T = chunk.transform.matrix
origin = (-1) * camera.center
R = Metashape.Matrix().Rotation(camera.transform.rotation()*Metashape.Matrix().Diag([1,-1,1]))
origin = R.inv().mulp(origin)
chunk.transform.matrix = Metashape.Matrix().Translation(origin) * R.inv()

Andy
« Last Edit: August 16, 2019, 04:48:05 AM by andyroo »