Forum

Author Topic: Select cameras inside a shape polygon and move them to another chunk  (Read 4023 times)

jugii

  • Newbie
  • *
  • Posts: 4
    • View Profile
Hello

Is there a way to select cameras inside a shape polygon and move them to another chunk? Or to delete photos outside a shape polygon?

thanks
Jukka

Bastiaan Veenstra

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Select cameras inside a shape polygon and move them to another chunk
« Reply #1 on: November 23, 2020, 10:02:15 AM »
Same question here! Would love to be able to select points within a shape without aligning all my photos first.

Polygon selection tool would be great too  :P

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14813
    • View Profile
Re: Select cameras inside a shape polygon and move them to another chunk
« Reply #2 on: November 24, 2020, 12:56:10 PM »
Hello,

The example of the camera selection based on the selected polygonal shapes is below, for aligned cameras the estimated locations are used and for not aligned - the source reference coordinates, if present:

Code: [Select]
import Metashape

def point_inside(point, poly):

x, y = point.x, point.y
inside = False

p1x, p1y = poly[0]
for i in range(len(poly) + 1):
p2x, p2y = poly[i % len(poly)]
if y >= min(p1y, p2y):
if y <= max(p1y, p2y):
if x <= max(p1x, p2x):
if p1y != p2y:
xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
if p1x == p2x or x <= xinters:
inside = not inside
p1x, p1y = p2x, p2y
return inside

doc = Metashape.app.document
chunk = doc.chunk
shapes = chunk.shapes
crs = shapes.crs
T = chunk.transform.matrix
polygons = dict()

for shape in shapes:
if not shape.selected: #skipping not selected shapes
continue
if shape.type == Metashape.Shape.Polygon:
polygons[shape] = [[v.x, v.y] for v in shape.vertices]

for camera in chunk.cameras:
camera.selected = False
if not camera.transform:
if camera.reference.location:
camera_coord = crs.project(chunk.crs.unproject(camera.reference.location))
else:
continue
else:
camera_coord = crs.project(T.mulp(camera.center))
for shape in polygons.keys():
if point_inside(Metashape.Vector([camera_coord.x, camera_coord.y]), polygons[shape]):
camera.selected = True

print("Script finished")

As for the copying cameras to the new chunk, currently there's no such built-in feature in API, so I can only suggest to form a list of file paths related to the cameras that should be copied (camera.photo.path), then create a new chunk (doc.addChunk) and use addPhotos to load the cameras based on the custom list of paths. Note that the coordinate information should be re-loaded to the newly created chunk, as no information from the source chunk will be used in such approach.
Best regards,
Alexey Pasumansky,
Agisoft LLC

mrv2020

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Re: Select cameras inside a shape polygon and move them to another chunk
« Reply #3 on: December 13, 2023, 04:54:09 PM »
To cameras not align I`m trying this, but not working, any help?

Code: [Select]
import Metashape

def point_inside(point, poly):
    x, y = point.x, point.y
    inside = False

    p1x, p1y = poly[0]
    for i in range(len(poly) + 1):
        p2x, p2y = poly[i % len(poly)]
        if y >= min(p1y, p2y):
            if y <= max(p1y, p2y):
                if x <= max(p1x, p2x):
                    if p1y != p2y:
                        xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                    if p1x == p2x or x <= xinters:
                        inside = not inside
        p1x, p1y = p2x, p2y
    return inside

doc = Metashape.app.document
chunk = doc.chunk
shapes = chunk.shapes
crs = shapes.crs
T = chunk.transform.matrix
polygons = dict()

for shape in shapes:
    if not shape.selected:
        continue
    if shape.type == Metashape.Shape.Polygon:
        polygons[shape] = [[v.x, v.y] for v in shape.vertices]

for camera in chunk.cameras:
    camera.selected = False
    if not camera.transform:
        if camera.reference.location:
            # For non-aligned images, use the camera's reference location directly
            camera_coord = crs.project(chunk.crs.unproject(camera.reference.location))
        else:
            continue
    else:
        # For aligned images, use the estimated location
        camera_coord = crs.project(T.mulp(camera.center))
    for shape in polygons.keys():
        if point_inside(Metashape.Vector([camera_coord.x, camera_coord.y]), polygons[shape]):
            camera.selected = True