Agisoft Metashape
Agisoft Metashape => Python and Java API => Topic started by: ivan.mdn on October 22, 2014, 12:21:35 AM
-
I am creating a marker using a python script and setting its projection on one of the photos using the following:
chunk.markers[j].projections[chunk.cameras[i]] = (x,y)
I would like to see the marker on the 3d model (already generated) but i dont have the coordinates of the marker on the others photos. Is there a way to generate them automatically through the python api?
I am asking this because when I add the marker through the gui (right click on the photo -> create marker) it automatically projects the marker on the others photos.
-
Hello ivan,mdn,
Marker creation from GUI with automatic projections placement on all the photos actually works only if the surface model has been generated. Based on this information and single projection defined by user PhotoScan intersects the ray coming from camera center through point on 2D image with the polygonal model and then projects the point of intersection back to all other photos.
In principle such operation can be implemented in Python script, but it will take longer time that GUI analogue.
-
Could you give some specifics about how i could do this through the api, given that the model has already been generated? I am just starting in 3d modeling and by looking through the api documentation I wasn't able to come up with a way to do that.
About taking longer than through the GUI, its not really an issue for me. I am more interested in automating the process than on its speed.
-
Hello ivan.mdn,
I can suggest something like the following for given camera and projection coordinates on the corresponding photo (you'll find it in the script body):
#compatibility PhotoScan Pro 1.1.0
import PhotoScan
def cross(a, b):
result = PhotoScan.Vector([a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y *b.x])
return result
print("Script started")
doc = PhotoScan.app.document
chunk = doc.chunk
model = chunk.model
vertices = chunk.model.vertices
if chunk.transform.matrix:
T0 = chunk.transform.matrix
else:
T0 = PhotoScan.Matrix().diag([1, 1, 1, 1])
camera = chunk.cameras[120] #camera index
marker_2D = (500, 400) #projections of marker on the given photo
chunk.addMarker()
marker = chunk.markers[-1] #the last marker in set
marker.projections[camera] = marker_2D
point_2D = marker.projections[camera].coord
vect = camera.sensor.calibration.unproject(point_2D)
vect = camera.transform.mulv(vect)
center = camera.center
#estimating ray and surface intersection
for face in model.faces:
v = face.vertices
E1 = PhotoScan.Vector(vertices[v[1]].coord - vertices[v[0]].coord)
E2 = PhotoScan.Vector(vertices[v[2]].coord - vertices[v[0]].coord)
D = PhotoScan.Vector(vect)
T = PhotoScan.Vector(center - vertices[v[0]].coord)
P = cross(D, E2)
Q = cross(T, E1)
result = PhotoScan.Vector([Q * E2, P * T, Q * D]) / (P * E1)
if (0 < result[1]) and (0 < result[2]) and (result[1] + result[2] <= 1):
t = (1 - result[1] - result[2]) * vertices[v[0]].coord
u = result[1] * vertices[v[1]].coord
v_ = result[2] * vertices[v[2]].coord
point_3D = T0.mulp(u + v_ + t)
point_3D = chunk.crs.project(point_3D)
break
point = chunk.crs.unproject(point_3D)
point = T0.inv().mulp(point)
for cur_camera in chunk.cameras:
if (cur_camera == camera) or not cur_camera.transform:
continue
cur_proj = cur_camera.project(point)
if (0 <= cur_proj[0] < camera.sensor.width) and (0 <= cur_proj[1] < camera.sensor.height):
marker.projections[cur_camera] = cur_proj
print("Script finished")
But please note that this script is already for PhotoScan Pro 1.1.0.
-
Thank you for your support Alexey, the code worked perfectly for what I needed.
-
Hi Alexey, I can't get this to work with 1.2.2. it does not like
chunk.crs.project(point_3D)
Did something change about the crs in the chunk in the new version or does it need to be initialized somehow?
Thank you!
-
Hello mauchi,
In case the chunk is not referenced the chunk.crs will be None, so you can include additional condition, like:
if chunk.crs:
point_3D = chunk.crs.project(point_3D)
If you have any other problems, please provide the Console pane output related to the error.