Forum

Author Topic: Marker projections  (Read 7410 times)

ivan.mdn

  • Newbie
  • *
  • Posts: 9
    • View Profile
Marker projections
« 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:
Code: [Select]
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.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14847
    • View Profile
Re: Marker projections
« Reply #1 on: October 22, 2014, 03:20:28 PM »
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.
Best regards,
Alexey Pasumansky,
Agisoft LLC

ivan.mdn

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Marker projections
« Reply #2 on: October 22, 2014, 03:53:37 PM »
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.
« Last Edit: October 22, 2014, 03:57:57 PM by ivan.mdn »

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14847
    • View Profile
Re: Marker projections
« Reply #3 on: October 22, 2014, 04:36:30 PM »
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):

Code: [Select]
#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.
Best regards,
Alexey Pasumansky,
Agisoft LLC

ivan.mdn

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Marker projections
« Reply #4 on: October 22, 2014, 10:35:26 PM »
Thank you for your support Alexey, the code worked perfectly for what I needed.

mauchi

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Marker projections
« Reply #5 on: December 31, 2015, 09:56:21 AM »
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!

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14847
    • View Profile
Re: Marker projections
« Reply #6 on: December 31, 2015, 11:32:18 AM »
Hello mauchi,

In case the chunk is not referenced the chunk.crs will be None, so you can include additional condition, like:
Code: [Select]
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.
Best regards,
Alexey Pasumansky,
Agisoft LLC