Hello kcm,
Please check for the following general approach for getting the projected point 3D coordinates from the 2D image coordinates and vice versa (assuming that the chunk is georeferenced):
import Metashape
doc = Metashape.app.document
chunk = doc.chunk
T = chunk.transform.matrix
crs = chunk.crs
#for projecting 3D point to the camera and obtaining 2D coordinates:
camera0 = chunk.cameras[0] #first camera
point = Metashape.Vector([x, y, z]) #point of interest in geographic coord
point_internal = T.inv().mulp(crs.unproject(point))
coords_2D = camera0.project(point_internal)
#for projecting 2D point in image coordinates to available 3D surface (mesh model in this case):
coords_2D = Metashape.Vector([X, Y])
point_internal = chunk.model.pickPoint(camera0.center, camera0.unproject(coords_2D))
point3D_world = chunk.crs.project(chunk.transform.matrix.mulp(point_internal))
In case your task is to get 3D coordinates of the tie points and their projections on the individual images, you can follow a different approach, as this information is already present in the project:
#export format:
#point_ID X Y Z
#[camera_label x_proj y_proj]
import Metashape, math
doc = Metashape.app.document
chunk = doc.chunk
M = chunk.transform.matrix
crs = chunk.crs
point_cloud = chunk.point_cloud
projections = point_cloud.projections
points = point_cloud.points
npoints = len(points)
tracks = point_cloud.tracks
path = Metashape.app.getSaveFileName("Specify export path and filename:", filter ="Text / CSV (*.txt *.csv);;All files (*.*)")
file = open(path, "wt")
print("Script started...")
point_ids = [-1] * len(point_cloud.tracks)
for point_id in range(0, npoints):
point_ids[points[point_id].track_id] = point_id
points_proj = {}
for photo in chunk.cameras:
if not photo.transform:
continue
T = photo.transform.inv()
calib = photo.sensor.calibration
for proj in projections[photo]:
track_id = proj.track_id
point_id = point_ids[track_id]
if point_id < 0:
continue
if not points[point_id].valid: #skipping invalid points
continue
point_index = point_id
if point_index in points_proj.keys():
x, y = proj.coord
points_proj[point_index] = (points_proj[point_index] + "\n" + photo.label + "\t{:.2f}\t{:.2f}".format(x, y))
else:
x, y = proj.coord
points_proj[point_index] = ("\n" + photo.label + "\t{:.2f}\t{:.2f}".format(x, y))
for point_index in range(npoints):
if not points[point_index].valid:
continue
coord = M * points[point_index].coord
coord.size = 3
if chunk.crs:
#coord
X, Y, Z = chunk.crs.project(coord)
else:
X, Y, Z = coord
line = points_proj[point_index]
file.write("{}\t{:.6f}\t{:.6f}\t{:.6f}\t{:s}\n".format(point_index, X, Y, Z, line))
file.close()
print("Finished")