Agisoft Metashape > Python and Java API
Python script to loop and process 800 projects one after another
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