Forum

Author Topic: Build cylindrical Orthomosaic via batch/python  (Read 3972 times)

geri

  • Newbie
  • *
  • Posts: 11
    • View Profile
Build cylindrical Orthomosaic via batch/python
« on: November 20, 2018, 11:42:17 AM »
Hi there,

I'm currently using the cylindrical option of the orthomosaic generation to create an "unwrap" (flat pattern) of a tunnel. It works perfectly fine using fictional markers to define the cylinder and the projection center. Good job there!

What I'm missing is, how to adress the cylindrical orthomosaic via python, since I have to create lots orthomosaics with different cylinders along a curved line. Is it already implemented in the python API and I missed it? Any chance to add it any time soon?

Thanks for any help.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14817
    • View Profile
Re: Build cylindrical Orthomosaic via batch/python
« Reply #1 on: November 22, 2018, 08:00:05 PM »
Hello geri,

Here's the script that uses first two markers (m2 -> m1) for the axis definition and the third (m3) for the origin definition.

Code: [Select]
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.normalized()
chunk = PhotoScan.app.document.chunk
crs = chunk.world_crs
T = chunk.transform.matrix

m1 = chunk.markers[0] #defines the top of the cylinder axis
m2 = chunk.markers[1] #defines the bottom of the cylinder axis
m3 = chunk.markers[2] #defines the origin

p1 = T.mulp(m1.position)
p2 = T.mulp(m2.position)
p3 = T.mulp(m3.position)
axis_z = (p1 - p2).normalized()
origin = p2 + ((p3 - p2) * axis_z) * axis_z
radius = (p3 - origin).norm()
axis_x = (p3 - origin).normalized()
axis_y = cross(axis_z, axis_x)
R = PhotoScan.Matrix ([axis_x, axis_y, axis_z]).t()
T = PhotoScan.Matrix.Translation(origin) * PhotoScan.Matrix.Rotation(R)
proj = PhotoScan.OrthoProjection()
proj.type = PhotoScan.OrthoProjection.Type.Cylindrical
proj.radius = radius
proj.matrix = T.inv()
proj.crs = crs
chunk.buildOrthomosaic(surface = PhotoScan.ModelData, projection = proj)

Let me know if it works for you or if there are any problems.
Best regards,
Alexey Pasumansky,
Agisoft LLC

geri

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Build cylindrical Orthomosaic via batch/python
« Reply #2 on: November 27, 2018, 06:20:05 PM »
Thanks Alexey,

it works perfectly.
On the other hand I'm still missing some other details.

1. How can I define the "interior projection" for the cylindrical projection in python?

2. I used your script, and it uses the first three markers as reference. Is it somehow possible to search the existing markers via arguments? For example my list of markers contains markers named "10130ZA" "10130ZE" and "10130P" for Beginning, End and Projection Center of the first cylinder. The next cylinder would be defined by "10190_ZA" "10190_ZE" and "10190_ZP" and so on. Therefore I would like to somehow define that the software should use the 3 markers with the numbers "10130" in them. Is that possible?

3. Also I would like to store those orthomosaics in the chunk, but everytime I create a new one, the existing one is overwritten. Is there another way?

4. I already created a script for the export of the orthomosaic, but I also want to add the name of the marker into the file name. How do I do that?


Thanks in advance.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14817
    • View Profile
Re: Build cylindrical Orthomosaic via batch/python
« Reply #3 on: November 27, 2018, 06:53:47 PM »
Hello geri,

To get the interior projection please try to use flip_x=True and flip_z=True parameters in the .buildOrthomosaic() function.

To look for the certain markers I can suggest to write some custom function, for example:
Code: [Select]
def find_markers(label, chunk):
     output_list = list()   
     for marker in chunk.markers:
          if marker.label.startswith(label):
                output_list.append(marker)
     if len(output_list) == 3:     
          return output_list
     else:
          print("Can't find 3 markers")
          return False

chunk = PhotoScan.app.document.chunk
markers = find_markers("100130", chunk)

I think, you can build and export orthomosaic in the loop, for example:

Code: [Select]
for m_label in ["10130", "10190"]:
    if chunk.orthomosaic:
         chunk.orthomosaic = None #make orthomosaic not active
    #find markers
    #perform required operations
    chunk.buildOrthomosaic(...)
    chunk.orthomosaic.label = m_label
    chunk.exportOrthomosaic(path = export_folder + "/" + m_label + "_ortho.tif", ...)
    chunk.orthomosaic = None

So it loops through the list of labels that define the groups of markers and for each such group generated the orthomosaic, labels it correspondingly in the Workspace pane and exports under this name.
Best regards,
Alexey Pasumansky,
Agisoft LLC

geri

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Build cylindrical Orthomosaic via batch/python
« Reply #4 on: November 28, 2018, 02:21:05 PM »
Thanks, I combined everything and after some tweaking and trying around I got the perfect result. It saves a LOT of time! :)

antonispagonakis

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Build cylindrical Orthomosaic via batch/python
« Reply #5 on: September 27, 2022, 05:36:24 PM »
Hello everyone,
I know the software itself has already a script to produce an orthomosaic (.jpeg) via cylindrical orthomosaic tool which unwraps a tunnel and it asks for 3 markers but for the whole tunnel (2 for the axis in xy dimensions and 1 for the z dimension). However a tunnel never goes straight so is there any way Photoscan’s script to be modified in order to ask these 3 markers every 10 meters in order to produce only 1 .jpeg instead of doing sepereate orthomosaics of the tunnel’s unwrap.

Thanks in advance