Armadillo,
thanks for the input... I looked at your script and modified it to take into account that some shapes may have some markers and thus vertices are extracted differently:
import Metashape
import json
output_file = 'C:/Users/paul.pelletier/Desktop/polygons.json'
def shape2image(shape, camera, chunk):
"""
Converts model coordinates of passed shape to image coordinates of passed camera and chunk.
If the shape does not lie completely in the camera image, returns None.
"""
image_coords = list()
T = chunk.transform.matrix #4x4 transformation matrix
if shape.vertex_ids:
vertices = [(i.position) for i in chunk.markers if i.key in shape.vertex_ids]
else:
vertices = [(T.inv().mulp(chunk.shapes.crs.unproject(vertex))) for vertex in shape.vertices]
for vertex in vertices:
if not camera.project(vertex):
return None
pixel_coords = camera.project(vertex)
pixel_coords[0] = round(pixel_coords[0],3)
pixel_coords[1] = round(pixel_coords[1],3)
if pixel_coords[0] > camera.sensor.width or pixel_coords[0] < 0 or pixel_coords[1] > camera.sensor.height or pixel_coords[1] < 0: # check coords lie inside image
return None
image_coords.append(pixel_coords)
return image_coords
def get_all_shapes_in_camera(camera, chunk):
""" Returns a list of lists.
Each list contains coordinates in image (pixel) coordinates of a shape.
Every shape in the chunk that is completely inside the camera's image is in the list.
"""
pixel_shapes = list() # list to hold the shapes in pixel coords
for shape in chunk.shapes:
ps = shape2image(shape, camera, chunk)
if ps is not None:
pixel_shapes.append({"label": shape.label, "type": shape.type, "vertices": ps})
return pixel_shapes
chunk = Metashape.app.document.chunk
image_data = list()
cameras = [camera for camera in chunk.cameras if camera.type == Metashape.Camera.Type.Regular]
for i in range(len(cameras)):
if not cameras[i].enabled:
continue
image_data.append({"image": cameras[i].label, "shapes": get_all_shapes_in_camera(cameras[i], chunk)})
with open(output_file, 'w') as f:
json.dump(image_data, f, indent=4, ensure_ascii=True, skipkeys=True)
print("Polygons saved in file: " + output_file)
Now I run it and get error in json.dump line as see in following:
2020-04-26 21:58:35 Traceback (most recent call last):
2020-04-26 21:58:35 File "C:/Users/paul.pelletier/Documents/Photoscan/Scripts/Export_Shape_imagecoords.py", line 55, in <module>
2020-04-26 21:58:35 json.dump(image_data, f, indent=4, sort_keys=True)
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\__init__.py", line 178, in dump
2020-04-26 21:58:35 for chunk in iterable:
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 427, in _iterencode
2020-04-26 21:58:35 yield from _iterencode_list(o, _current_indent_level)
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 324, in _iterencode_list
2020-04-26 21:58:35 yield from chunks
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 403, in _iterencode_dict
2020-04-26 21:58:35 yield from chunks
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 324, in _iterencode_list
2020-04-26 21:58:35 yield from chunks
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 403, in _iterencode_dict
2020-04-26 21:58:35 yield from chunks
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 324, in _iterencode_list
2020-04-26 21:58:35 yield from chunks
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 436, in _iterencode
2020-04-26 21:58:35 o = _default(o)
2020-04-26 21:58:35 File "C:\Program Files\Agisoft\Metashape Pro\python\lib\json\encoder.py", line 179, in default
2020-04-26 21:58:35 raise TypeError(repr(o) + " is not JSON serializable")
2020-04-26 21:58:35 TypeError: Vector([2400.865, 985.495]) is not JSON serializable
2020-04-26 21:58:35 Error: Vector([2400.865, 985.495]) is not JSON serializable
Note that image_data dict is correctly built as seen in:
image_data
Out[1]: 2020-04-26 21:59:16
2020-04-26 21:59:16 [{'image': '000001.png',
2020-04-26 21:59:16 'shapes': [{'label': '1',
2020-04-26 21:59:16 'vertices': [Vector([2400.865, 985.495]), Vector([2489.325, 1522.156])]},
2020-04-26 21:59:16 {'label': '2',
2020-04-26 21:59:16 'vertices': [Vector([2254.728, 1070.235]),
2020-04-26 21:59:16 Vector([2089.051, 960.86]),
2020-04-26 21:59:16 Vector([2057.241, 1165.198]),
2020-04-26 21:59:16 Vector([2261.582, 1216.922])]}]},
2020-04-26 21:59:16 {'image': '000002.png',
2020-04-26 21:59:16 'shapes': [{'label': '1',
2020-04-26 21:59:16 'vertices': [Vector([2396.742, 1024.154]), Vector([2456.715, 1559.424])]},
2020-04-26 21:59:16 {'label': '2',
2020-04-26 21:59:16 'vertices': [Vector([2243.45, 1106.666]),
2020-04-26 21:59:16 Vector([2081.281, 990.555]),
2020-04-26 21:59:16 Vector([2041.085, 1196.629]),
2020-04-26 21:59:16 Vector([2243.052, 1253.72])]}]},
As I am not very knowledgeable in python, what would be the problem.....
Attached is the json file generated....