Forum

Poll

Running the workflow completely automatized

Yes
12 (54.5%)
No
10 (45.5%)

Total Members Voted: 22

Author Topic: Python Scripting  (Read 21552 times)

chillema

  • Newbie
  • *
  • Posts: 5
    • View Profile
Python Scripting
« on: April 16, 2014, 05:46:54 PM »
Hi folks!  :)

I am a complete newbie in terms of Batch Processing and Scripting, especially with Python. But since I somehow have to find a way in automizing the workflow I really appreciate any help you can provide me.

To make the story short:

The latest version of PhotoScan is running on my Mac and I would like the script to run the following for me:

1. Add Photos to the workspace (they all come from a single folder)
2. Aligning the Photos with HIGH Accuracy, GENERIC Pair Preselection & a point limit of 50k.
3. Building a Dense Cloud with HIGH quality and AGGRESSIVE Depth filtering
4. Building a Mesh with ARBITRARY Surface Type, DENSE CLOUD as Source Data as well as a HIGH Polygon Count
5. Build Texture with ADAPTIVE ORTHOPHOTO Mapping Mode, MOSAIC Blending Mode and a Texture Size of 4096 x 1
6. Save the whole project

I know that mwillis already asked a quite similar question (http://www.agisoft.ru/forum/index.php?topic=1967.msg10483#msg10483) but unfortunately it didn't work out when I used to modify it for my purpose...

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #1 on: April 16, 2014, 06:15:06 PM »
Hello chillema,

Few questions: do you want to specify the paths to input images and output project file manually (using common OS dialogs)? And is there any OpenCL device to be activated during depth maps estimation step?
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #2 on: April 16, 2014, 06:29:55 PM »
You can try this one meanwhile to check if it's working fine:

Code: [Select]
import os
import PhotoScan

def main():

print("Script started")

doc = PhotoScan.app.document
chunk = PhotoScan.Chunk()
chunk.label = "New Chunk"
doc.chunks.add(chunk)


path_photos = PhotoScan.app.getExistingDirectory("Specify folder with input photos:")
path_photos += "/"

#checking save filename
project_path = PhotoScan.app.getSaveFileName("Specify project filename for saving:")
if not project_path:
print("Script aborted")
return 0

if proejct_path[-4:].lower() != ".psz":
project_path += ".psz"

#adding photos
image_list = os.listdir(path_photos)
for photo in image_list:
if ("jpg" or "jpeg" or "tif" or "png") in photo.lower():
chunk.photos.add(path_photos + photo)
PhotoScan.app.update()

#align photos
chunk.matchPhotos(accuracy = "high", preselection = "generic", filter_mask = False, point_limit = 50000)
chunk.alignPhotos()

#build dense cloud
chunk.buildDenseCloud(quality = "high", filter = "aggressive")

#build mesh
chunk.buildModel(surface = "arbitrary", source = "dense", interpolation = "enabled", faces = "high")

#build texture
chunk.buildTexture(mapping = "adaptive", blending = "mosaic", color_correction = False, size = 4096, count = 1

#save
doc.save(project_path)

PhotoScan.app.update()
print("Script finished")
return 1


PhotoScan.app.addMenuItem("Custom menu/Process photos", main)
Best regards,
Alexey Pasumansky,
Agisoft LLC

chillema

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Python Scripting
« Reply #3 on: April 17, 2014, 12:53:34 AM »
Hi Alexey,

first of all thanks a lot for your quick help. Unfortunately I can't test the script before tomorrow morning when I am at my office...but in order to answer your questions:

yes, of course there is an OpenCL device (NVIDIA GeForce 9400M as well as a NVIDIA GeForce 9600GT) and well...I would like to set it up manually but I am not quite sure whether its working out or not...

So, thanks again...and maybe until tomorrow...

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #4 on: April 17, 2014, 11:21:18 AM »
Hello chillema,

Than you need to use the following (just small corrections in buildDenseCloud):

Code: [Select]
import os
import PhotoScan

def main():

print("Script started")

doc = PhotoScan.app.document
chunk = PhotoScan.Chunk()
chunk.label = "New Chunk"
doc.chunks.add(chunk)


path_photos = PhotoScan.app.getExistingDirectory("Specify folder with input photos:")
path_photos += "/"

#checking save filename
project_path = PhotoScan.app.getSaveFileName("Specify project filename for saving:")
if not project_path:
print("Script aborted")
return 0

if project_path[-4:].lower() != ".psz":
project_path += ".psz"

#adding photos
image_list = os.listdir(path_photos)
for photo in image_list:
if ("jpg" or "jpeg" or "tif" or "png") in photo.lower():
chunk.photos.add(path_photos + photo)

PhotoScan.app.update()

#align photos
chunk.matchPhotos(accuracy = "high", preselection = "generic", filter_mask = False, point_limit = 50000)
chunk.alignPhotos()

#build dense cloud
chunk.buildDenseCloud(quality = "high", filter = "aggressive", gpu_mask = 1, cpu_cores_inactive = 1)

#build mesh
chunk.buildModel(surface = "arbitrary", source = "dense", interpolation = "enabled", faces = "high")

#build texture
chunk.buildTexture(mapping = "adaptive", blending = "mosaic", color_correction = False, size = 4096, count = 1)

#save
doc.save(project_path)

PhotoScan.app.update()
print("Script finished")
return 1

PhotoScan.app.addMenuItem("Custom menu/Process photos", main)
Best regards,
Alexey Pasumansky,
Agisoft LLC

chillema

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Python Scripting
« Reply #5 on: April 17, 2014, 11:45:53 AM »
Hi Alexey,

it's still not working out properly....and/or I am too stupid!^^

When I am running the script in PhotoScan the following error shows up in the console:

OpenGL Vendor: NVIDIA Corporation
OpenGL Renderer: NVIDIA GeForce 9400M OpenGL Engine
OpenGL Version: 2.1 NVIDIA-8.24.11 310.90.9b01
Maximum Texture Size: 8192
Quad Buffered Stereo: not enabled
ARB_vertex_buffer_object: supported
ARB_texture_non_power_of_two: supported
  File "/Users/Hille/Desktop/Python_Script_V2.py", line 1
    {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190
                                                      ^
SyntaxError: unexpected character after line continuation character
>>>

See attached the textedit file...The pictures are in the folder PhotoScan on my Desktop and the application should save the project within a subfolder of this (Test) with the name Test.psz....

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #6 on: April 17, 2014, 11:54:59 AM »
Hello chillema,

This line path_photos = PhotoScan.app.getExistingDirectory("Specify folder with input photos:") means that PhotoScan will open Open Dir dialog box with the corresponding tip. So you do not need to change these tips for any paths, since PhotoScan will ask you to specify the directory with the images and project filename.

Please also check that .py file is save in UTF-8 without BOM encoding.
« Last Edit: April 17, 2014, 11:58:07 AM by Alexey Pasumansky »
Best regards,
Alexey Pasumansky,
Agisoft LLC

studentTUBAF

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Python Scripting
« Reply #7 on: May 05, 2014, 02:20:41 PM »
Dear Mr. Pasumansky and Chillema,

I'm a student at the university of Freiberg, Germany. My group and I work on a geomonitoring project. Now we try to automize the import, alignment and mesh-building. We did use the python script from above and the following error occured:

"
Traceback (most recent call last):
  File "D:/Geomonitoring/Gruppe 2_SS14/automatischer_Workflow.py", line 54, in <module>
    PhotoScan.app.addMenuItem("Custom menu/Process photos", main)
AttributeError: 'PhotoScan.Application' object has no attribute 'addMenuItem'
"

we just got this one error from the script. the other errors from Chilemma didn't occur.
Can u help us with the shown error.

Furthermore we used the 4D-Processing-Tool as we want to evaluate several measurement decades. If you have any informations on modifying the python script for that purpose we would be very grateful.

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #8 on: May 05, 2014, 02:26:36 PM »
Hello studentTUBAF,

Could you please specify the version of PhotoScan you are using? I recommend to update to the version 1.0.4 to avoid any other script compatibility issues.

Please provide some additional details regarding 4D processing: are the images taken from the same camera positions using identical camera parameters?
Best regards,
Alexey Pasumansky,
Agisoft LLC

studentTUBAF

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Python Scripting
« Reply #9 on: May 06, 2014, 12:26:14 PM »
Hello,

I updated the latest version of Agisoft PhotoScan (before we used a 0.9.-version) and now the script from above won't work in any way. It even does not appear any message within the console-window.
Regarding the 4D-Processing-Tool: we did use two similar highspeed-cameras (Basel ACE) and placed them like a triangle relative to the desired object. Regarding the calibration of the cameras we use the Agisoft onboard-calibration during the "Alignment" process

Thank you a lot in advance!

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #10 on: May 06, 2014, 12:29:22 PM »
Dear studentTUBAF,

The script adds new option in Custom Menu (in Main Menu), so to run the processing you need to choose this newly created option.

Maybe you can provide a sample dataset for 4D processing?
Best regards,
Alexey Pasumansky,
Agisoft LLC

studentTUBAF

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Python Scripting
« Reply #11 on: May 19, 2014, 01:45:31 PM »
Hello Alexey,

sorry that we didn't catch up with you that long. Your script did work now. But we still need to edit it. We want to add Folder automatically in the same way as we can do it manually. We do have the two similar camera's (Master, Slave) and like to add the folder's as multiframe for using them in 4D-processing. It would be great if you can provide us some informations. Furthermore I'd like to ask, if there need to be any changes in the following programming code regarding alignment, build dense pointcloud etc.
Regarding your last question I added a link!

https://www.dropbox.com/sh/qb56gi5a9o9ewfv/AAAEV8iUVtcOLCTOrxwCIoSta

Thank you again!




Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #12 on: June 23, 2014, 01:35:46 PM »
Hello,

Sorry for the late reply.

Here's the code for the task:

Code: [Select]
import os
import PhotoScan

doc = PhotoScan.app.document
print("Srcipt started")

chunk = PhotoScan.Chunk()
chunk.label = "Multiframe"
doc.chunks.add(chunk)

path = PhotoScan.app.getExistingDirectory("main folder:")
folders = os.listdir(path)

for folder in list(folders):
if not os.path.isdir(path + "\\" +folder):
folders.remove(folder)
folders.sort()

image_folders = list()
for frame in range(len(folders)):
images = os.listdir(path + "\\" + folders[frame])
for image in list(images):
if image.rsplit(".", 1)[1].upper() != "JPG":
images.remove(image)
images.sort()
image_folders.append(images.copy())

frames = len(image_folders[0])

#Loading images:
for frame in range(frames):

for folder in range(len(folders)):
if not frame:
chunk.photos.add(path + "\\" + folders[folder] + "\\" + image_folders[folder][frame])
else:
f = PhotoScan.Frame()
f.open(path + "\\" + folders[folder] + "\\" + image_folders[folder][frame], 0)
chunk.photos[folder].frames.append(f)
doc.activeChunk = chunk

#Processing:
chunk.matchPhotos(accuracy='high', preselection='disabled', filter_mask=False, point_limit=40000)
chunk.alignPhotos()

chunk.buildDenseCloud(quality = 'medium', filter = 'aggressive', gpu_mask = 1, cpu_cores_inactive = 1, frames = list(range(frames)))
chunk.buildModel(surface = 'arbitrary', source = 'dense', interpolation = 'enabled', faces = 200000, frames = list(range(frames)))

#chunk.buildTexture(mapping = 'generic', blending = 'mosaic', size = 2048, count=1, frames = list(range(frames)))

print("Script finished")

On script run you'll be asked of the main folder where only sub-folders corresponding to the cameras should be situated
From each folder scripts loads only JPG images sorted in alphabetic order, so the sequence should be the same in each sub-folder
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14846
    • View Profile
Re: Python Scripting
« Reply #13 on: June 23, 2014, 01:36:07 PM »
Please check if it works as expected.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Freiberg

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Python Scripting
« Reply #14 on: July 14, 2014, 11:11:09 AM »
Hi Alexey,
the code worked. So thank u very much.
Now we saw, that our export code is just for 1
photo. Could u give us the code for a multiframe export?
« Last Edit: July 14, 2014, 11:34:45 AM by Freiberg »