Forum

Author Topic: Orthomosaic image assignment memory  (Read 9808 times)

James

  • Hero Member
  • *****
  • Posts: 771
    • View Profile
Orthomosaic image assignment memory
« on: July 30, 2025, 01:58:13 PM »
This is something I mentioned before, but I buried it at the end of a request for something different:

...something that would also help me would be to preserve image assignments made to orthomosaic shapes when regenerating it following the colour correction calculation.

The only other reference to it I can find is this statement that image assignments are discarded after being applied, which I assume means they can not even be recovered using the python api.

Note that using Update Orthomosaic command discards any assigned images (as they are already applied).

What I would love is if shapes could remember which images were assigned to them, so if I generate a new orthomosaic I can reapply the same image assignments that I made on a previous one more quickly.

This would be useful when I have made changes to the underlying surface data, image colour corrections, general alignment tweaks, or just need to generate the orthomosaic again at a higher resolution (as i do today!).

I know I should have just done it at the highest resolution to start with, but I didn't, and now I have to redo my very carefully considered image assignments.

Maybe something as 'simple' as appending a note in the polygon description property?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15650
    • View Profile
Re: Orthomosaic image assignment memory
« Reply #1 on: August 01, 2025, 12:43:00 PM »
Hello James,

I think, it could be done via script - add shape attributes related to the assigned images before updating the orthomosaic and, as the second option, assign images to the shape based on the attributes.

I'll try to check, if we already have such script, as it seems that there was a similar request some time ago.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15650
    • View Profile
Re: Orthomosaic image assignment memory
« Reply #2 on: August 01, 2025, 04:48:24 PM »
Hello James,

I have found the script, that allows to save information about patches to shape attributes and read them:

Code: [Select]
import Metashape

def get_camera_by_key(key, chunk):
for camera in chunk.cameras:
if camera.key == key:
return camera
return None #camera not found

def patch_to_attr():
doc = Metashape.app.document
chunk = doc.chunk #active chunk
if not chunk:
print("Empty project, script aborted")
return 0
if not len([camera for camera in chunk.cameras if camera.type == Metashape.Camera.Type.Regular]):
print("No cameras, script aborted")
return 0
if not chunk.orthomosaic:
print("No orthomosaic for the active chunk, script aborted")
return 0
if not chunk.shapes:
print ("No shapes, script aborted")
return 0

ortho = chunk.orthomosaic
shapes = chunk.shapes

patches = ortho.patches.keys()
if not len(patches):
print ("No patches, script aborted")
return 0
count = 0
for patch in patches:
assigned_image = get_camera_by_key(ortho.patches[patch].image_keys[0], chunk)
if assigned_image == None:
print("Skipping patch", patch)
continue
patch.attributes["PATCH_CAMERA_LABEL"] = assigned_image.label
if assigned_image.photo.path:
patch.attributes["PATCH_CAMERA_PATH"] = assigned_image.photo.path
count += 1

print(str(count) + " patches saved to shape attributes. Script finished.")
return 1

def attr_to_patch():
doc = Metashape.app.document
chunk = doc.chunk #active chunk

if not chunk:
print("Empty project, script aborted")
return 0
if not len([camera for camera in chunk.cameras if camera.type == Metashape.Camera.Type.Regular]):
print("No cameras, script aborted")
return 0
if not chunk.orthomosaic:
print("No orthomosaic for the active chunk, script aborted")
return 0
if not chunk.shapes:
print ("No shapes, script aborted")
return 0

ortho = chunk.orthomosaic
patches = [shape for shape in chunk.shapes if (shape.geometry.type == Metashape.Geometry.Type.PolygonType) and ("PATCH_CAMERA_LABEL" in shape.attributes.keys())] #list of patches
ortho_patches = dict()
count = 0

for shape in patches:
found_cameras = []
for camera in chunk.cameras:
if camera.label.upper() == shape.attributes["PATCH_CAMERA_LABEL"].upper():
found_cameras.append(camera)
if not len(found_cameras):
print("Skipping " + str(shape) + " patch, no related cameras found")
continue
elif len(found_cameras) > 1:
if "PATCH_CAMERA_PATH" not in shape.attributes.keys():
print("Using first found camera with corresponding label for " + str(shape) + " patch")
camera = found_cameras[0]
else:
for camera in found_cameras:
if camera.photo.path.upper() == shape.attributes["PATCH_CAMERA_PATH"].upper():
break
print("Using first found camera with corresponding label for " + str(shape) + " patch")
camera = found_cameras[0]
else:
camera = found_cameras[0]
###camera - image to be assigned

patch = Metashape.Orthomosaic.Patch()
patch.image_keys = [camera.key]
ortho.patches[shape] = patch
count += 1
print("Assigned patch " + str(shape) + " for camera " + camera.label)

print(str(count) + " patches loaded from shape attributes.")
return 1

Metashape.app.addMenuItem("Scripts/Save existing patches to shape attributes", patch_to_attr)
Metashape.app.addMenuItem("Scripts/Load patches from shape attributes", attr_to_patch)
Best regards,
Alexey Pasumansky,
Agisoft LLC

James

  • Hero Member
  • *****
  • Posts: 771
    • View Profile
Re: Orthomosaic image assignment memory
« Reply #3 on: August 02, 2025, 08:15:06 PM »
That's great, thank you!