Agisoft Metashape > Python and Java API

Python script to loop and process 800 projects one after another

(1/2) > >>

Ant:
Hi there,

I'm a newbie in Python!

I need to write a script that I can use in PhotoScan 1.4.2 to process 800 projects from 800 folders (named from 0001 to 0800) that contains different sets of pictures.

The idea is simply to load the pictures from the first folder, align them, build dense point cloud, build mesh, save the .psx file with the name 0001.psx, export the mesh with the name 0001.ply.

And then automatically loop to go to the next folder to process the exact same steps... and this until folder 0800.

Can anyone help me with this?

Regards,
Ant

Alexey Pasumansky:
Hello Ant,

Please check the following script. It requires to specify the path to the "master folder" via script arguments:


--- Code: ---## Autoprocessing script for multiple sub-folders in some master folder

#compatibility Agisoft PhotoScan Professional 1.4.2
#use argument to specify the path to the "master folder"

import PhotoScan, os, sys, time

def process(path):

PhotoScan.app.gpu_mask = 2 ** len(PhotoScan.app.enumGPUDevices()) - 1 #setting GPU mask
if PhotoScan.app.gpu_mask:
PhotoScan.app.cpu_enable = False 
else:
PhotoScan.app.cpu_enable = True


### processing parameters
accuracy = PhotoScan.Accuracy.HighAccuracy  #align photos accuracy
reference_preselection = False
generic_preselection = True
keypoints = 40000 #align photos key point limit
tiepoints = 4000 #align photos tie point limit
source = PhotoScan.DataSource.DenseCloudData #build mesh/DEM source
surface = PhotoScan.SurfaceType.Arbitrary #build mesh surface type
quality = PhotoScan.Quality.MediumQuality #build dense cloud quality
filtering = PhotoScan.FilterMode.AggressiveFiltering #depth filtering
interpolation = PhotoScan.Interpolation.EnabledInterpolation #build mesh interpolation
blending = PhotoScan.BlendingMode.MosaicBlending #blending mode
face_num = PhotoScan.FaceCount.HighFaceCount #build mesh polygon count
mapping = PhotoScan.MappingMode.GenericMapping #build texture mapping
atlas_size = 4096
TYPES = ["jpg", "jpeg", "tif", "tiff"]
###end of processing parameters definition

print("Processing " + path)
list_files = os.listdir(path)
list_photos = list()
for entry in list_files: #finding image files
file = path + "/" + entry
if os.path.isfile(file):
if file[-3:].lower() in TYPES:
list_photos.append(file)
if not(len(list_photos)):
print("No images in " + path)
return False

doc = PhotoScan.Document()
doc.save(path + "/" + path.rsplit("/", 1)[1] + ".psx")
chunk = doc.addChunk()
chunk.label = path.rsplit("/", 1)[1]

###align photos
chunk.addPhotos(list_photos)
chunk.matchPhotos(accuracy = accuracy, generic_preselection = generic_preselection, reference_preselection = reference_preselection, filter_mask = False, keypoint_limit = keypoints, tiepoint_limit = tiepoints)
chunk.alignCameras()
chunk.optimizeCameras()
chunk.resetRegion()
doc.save()

###building dense cloud
chunk.buildDepthMaps(quality = quality, filter = filtering)
chunk.buildDenseCloud(point_colors = True, keep_depth = False)
doc.save()

###building mesh
chunk.buildModel(surface = surface, source = source, interpolation = interpolation, face_count = face_num)
doc.save()

###build texture
chunk.buildUV(mapping = mapping, count = 1)
chunk.buildTexture(blending = blending, size = atlas_size)
doc.save()

###export model
chunk. exportModel(path = path + "/" + chunk.label + ".obj", binary=False, texture_format=ImageFormatJPEG, texture=True, normals=False, colors=False, cameras=False, format = PhotoScan.ModelFormatOBJ)

print("Processed " + chunk.label)
return True

def main()

t0 = time.time()
print("Script started...")

if len(sys.argv) < 2:
print("No valid path input. Script aborted.")
return False
if os.path.isdir(sys.argv[1]):
path = sys.argv[1]
else:
print("No valid path input. Script aborted.")
return False

folders = ["/".join([path,entry]) for entry in os.listdir(path) if os.path.isdir(os.path.join(path,entry))]

for folder in folders:
process(folder)

t1 = time.time()
t1 -= t0
t1 = float(t1)

print("Script finished in " + "{:.2f}".format(t1) + " seconds.\n")
return

main()

--- End code ---

You can check it on a few subfolders and let me know, if everything works as expected or if there are any issues. In case of any problems, please provide the Console pane output with the related error information.

Ant:
Thanks Alexey!

I've actually managed to make it work with the script below (in case it can help out someone else).

***

import os, PhotoScan

dir_projects = 'E:/...//' #Directory folders with pictures
dir_PS_outputs = 'E:/...//' #Directory saved PS outputs


foldernames = os.listdir(dir_projects)
len(foldernames)

for i in range (0,len(foldernames)):
   
   doc=PhotoScan.app.document
   
   chunk = doc.addChunk()

   path_photos=dir_projects+foldernames

   image_list=os.listdir(path_photos)

   photo_list = list()

   for photo in image_list:
      if photo.rsplit(".",1)[1].lower() in  ["jpg", "jpeg", "tif", "tiff"]:
         photo_list.append("/".join([path_photos, photo]))

   chunk.addPhotos(photo_list)

   chunk.matchPhotos(accuracy=PhotoScan.HighestAccuracy,
                  generic_preselection=False,
                  reference_preselection=False,
                  filter_mask=False,
                  mask_tiepoints=False,
                  keypoint_limit=40000,
                  tiepoint_limit=4000)

   #accuracy=HighestAccuracy, HighAccuracy, MediumAccuracy, LowAccuracy, LowestAccuracy               
                  
   chunk.alignCameras(adaptive_fitting=True)

   chunk.buildDepthMaps(quality=PhotoScan.UltraQuality,
                  filter=PhotoScan.ModerateFiltering)
                  
   #quality=UltraQuality, HighQuality, MediumQuality, LowQuality, LowestQuality               

   chunk.buildDenseCloud(point_colors=True)

   chunk.buildModel(surface=PhotoScan.Arbitrary,
                  interpolation=PhotoScan.EnabledInterpolation,
                  face_count=PhotoScan.HighFaceCount,
                  vertex_colors=True)
                  
   #face_count=LowFaceCount, MediumFaceCount, HighFaceCount               

   chunk.buildUV(mapping=PhotoScan.GenericMapping,
                  count=1,
                  adaptive_resolution=False)
   
   chunk.buildTexture(blending=PhotoScan.MosaicBlending,
                  size=4096,
                  fill_holes=True,
                  ghosting_filter=True)   

   chunk.exportModel(path=dir_PS_outputs+foldernames+"_PS.ply",
                  binary=False,
                  precision=6,
                  texture_format=PhotoScan.ImageFormatNone,
                  texture=False,
                  normals=True,
                  colors=True,
                  cameras=False,
                  markers=False,
                  udim=False,
                  alpha=False,
                  strip_extensions=False,
                  raster_transform=PhotoScan.RasterTransformNone,
                  format=PhotoScan.ModelFormatPLY)

   chunk.exportModel(path=dir_PS_outputs+foldernames+"_PS.obj",
                  binary=False,
                  precision=6,
                  texture_format=PhotoScan.ImageFormatNone,
                  texture=False,
                  normals=True,
                  colors=True,
                  cameras=False,
                  markers=False,
                  udim=False,
                  alpha=False,
                  strip_extensions=False,
                  raster_transform=PhotoScan.RasterTransformNone,
                  format=PhotoScan.ModelFormatOBJ)

   doc.save(path=dir_PS_outputs+foldernames+"_PS.psx")
   
   doc.clear()

Ant:
Another question about Python in PhotoScan Pro 1.2.3:

What command line should I use to re-locate the pictures of a project that has already been created (with aligning, scaling and optimising steps done).

Regards,
Ant

Alexey Pasumansky:
Hello Ant,

Do you mean to modify the paths to the images, similar to Change Paths operation from GUI?

Navigation

[0] Message Index

[#] Next page

Go to full version