Hello Brit,
Script samples for the version 1.0.4 and 1.1.0 are published in the following thread:
http://www.agisoft.com/forum/index.php?topic=2734
I've been using a modified version of this script and it's working great. But the process has taken over a week to run so far. I made some minor modifications to export the dense cloud of each tile and to save the tile to a new document which can help in saving your progress in case a crash occurs. You can merge the tile documents into a single document using the merge_tiles function listed near the top. Here is the script that works with version 1.1.0 build 1985:
## Splits active chunk into user defined grid of sub-chunks (images are kept but bounding box is split)
## after chunk being split, for every smaller chunk mesh is generated based on the dense cloud, then dense cloud is removed from smaller chunks
##additional stripes will be generated and exported
#arguments - X and Y grid sizes
#compatibility PhotoScan Professional 1.1.0
#script v5.3
# Obtained from Alexey at Agisoft on 11/17/14
# Modified by Steven F
# Build dense cloud in main chunk but perform save as after every tile
import PhotoScan
import sys
doc = PhotoScan.app.document
orig_path = doc.path
chunk = doc.chunk
def dist(v0, v1):
"""
Calculate distance between two points defined as vectors
"""
distance = (v1 - v0)
return distance.norm() #**2
# take a folder of photoscan documents and merge them into one document then save
def merge_tiles(doc_tile_folder, merged_file):
import glob
tile_docs = glob.glob(doc_tile_folder + "*.psz")
merged_doc = PhotoScan.Document()
for doc in tile_docs:
tile = PhotoScan.Document()
tile.open(doc)
merged_doc.append(tile)
merged_doc.save(merged_file)
#parts of the model, 3 by default
partsX = 20
partsY = 20
if len(sys.argv) == 2:
parts = int(sys.argv[1])
partsX = partsY = parts
elif len(sys.argv) == 3:
partsX = int(sys.argv[1])
partsY = int(sys.argv[2])
print("Script started...")
# dense cloud settings
quality = PhotoScan.UltraQuality
filter = PhotoScan.MildFiltering
reuse_depth = False
# tile doc save and dense cloud export paths
tile_basename = "tileUltra"
las_tile_folder = "/project/ultra_las/"
doc_tile_folder = "/project/ultra_docs/"
las_basepath = las_tile_folder + tile_basename
doc_basepath = doc_tile_folder + tile_basename
# get existing chunk region
region = chunk.region
r_center = region.center
r_rotate = region.rot
r_size = region.size
# part size based on existing chunk region and number of parts
x_scale = r_size.x / partsX
y_scale = r_size.y / partsY
z_scale = r_size.z
# Offset between parts. I don't understand why it wouldn't just be the size,
# but they use center and rotate as well.
offset = r_center - r_rotate * r_size /2.
# Create a dense cloud for each part in a seperate chunk
for j in range(1, partsY + 1):
for i in range(1, partsX + 1):
print("Starting tile x", i, "y", j)
chunk.label = "Chunk "+ str(i)+ "\\" + str(j)
# set the region for the part
new_region = PhotoScan.Region()
new_rot = r_rotate
new_center = PhotoScan.Vector([(i - 0.5) * x_scale, (j - 0.5) * y_scale, 0.5 * z_scale])
new_center = offset + new_rot * new_center
new_size = PhotoScan.Vector([x_scale, y_scale, z_scale])
new_region.size = new_size
new_region.center = new_center
new_region.rot = new_rot
chunk.region = new_region
# print region center
print("Region center = ", chunk.region.center)
# create a dense cloud for the part
PhotoScan.app.update()
denseStatus = chunk.buildDenseCloud(quality = quality,
filter = filter,
reuse_depth = reuse_depth)
# # export dense points to LAS
if denseStatus == True:
print ("Dense cloud generation successful. Exporting LAS tile")
las_file = las_basepath + "_x" + str(i) + "y" + str(j) + ".las"
exportPoints = chunk.exportPoints(las_file,
source = PhotoScan.PointsSource.DensePoints,
format = "las",
projection = chunk.crs)
print("Point export successful?", str(exportPoints))
else:
print("Dense cloud generation failed. Nothing to export.")
# # save as a new document
new_doc = doc_basepath + "_x" + str(i) + "y" + str(j) + ".psz"
doc.save(new_doc)
# remove depth map, dense cloud, and model to save memory
chunk.depth_maps = None
chunk.dense_cloud = None
chunk.model = None
print("Finished with tile x", i, "y", j)
print("Script finished...")
PhotoScan.app.update()
You'll want to change a number of these settings of course: partsX, partsY, quality, filter, reuse_depth, tile_basename, las_tile_folder, doc_tile_folder
Lately I've been thinking that it would be nice if this process could be sped up by only calculating a depth map once for each image using every image it overlaps. This would probably require a significant change in the way PhotoScan is programmed, but it would remove the need to recalculate depth for an image that overlaps multiple tiles.