Thanks that works great.
I have modified the code to write tie points to a csv file, including camera label and date/time:
import Metashape
from PyQt5.QtWidgets import QFileDialog
import os
def get_tie_points(camera1, camera2, chunk):
if not camera1.transform:
Metashape.app.messageBox("Not aligned camera selected.")
return 0
if not camera2.transform:
Metashape.app.messageBox("Not aligned camera selected.")
return 0
projections = chunk.point_cloud.projections
points = chunk.point_cloud.points
tracks = chunk.point_cloud.tracks
npoints = len(points)
point_ids = [-1] * len(chunk.point_cloud.tracks)
for point_id in range(0, npoints):
point_ids[points[point_id].track_id] = point_id
camera_matches_valid = dict()
tie_points = dict()
tie_points[camera1] = dict()
tie_points[camera2] = dict()
for camera in [camera1, camera2]:
T = camera.transform.inv()
calib = camera.sensor.calibration
valid_matches = set()
for proj in projections[camera]:
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
valid_matches.add(point_id)
tie_points[camera][point_id] = proj.coord
camera_matches_valid[camera] = valid_matches
valid = camera_matches_valid[camera1].intersection(camera_matches_valid[camera2])
tie_point_output = list()
for point_id in valid:
tie_point_output.append((tie_points[camera1][point_id], tie_points[camera2][point_id]))
if not len(tie_point_output):
return None
return tie_point_output
chunk = Metashape.app.document.chunk
project_path = Metashape.app.document.path
common_tiepoints = get_tie_points(chunk.cameras[0], chunk.cameras[1], chunk)
def save_tiepoints_to_csv(tiepoints):
camera1 = chunk.cameras[0]
camera2 = chunk.cameras[1]
filename = f"{camera1.label}_{camera2.label}.csv"
parent_dir = os.path.dirname(project_path)
filepath = os.path.join(parent_dir, filename)
if not filepath:
return
with open(filepath, 'w') as f:
# write the tiepoints to the CSV file
f.write('Camera1, DateTime1, x1, y1, Camera2, DateTime2, x2, y2\n')
for tiepoint in tiepoints:
x1, y1 = tiepoint[0]
x2, y2 = tiepoint[1]
camera1_datetime = chunk.cameras[0].photo.meta['Exif/DateTime']
camera2_datetime = chunk.cameras[1].photo.meta['Exif/DateTime']
f.write(f'{chunk.cameras[0].label},{camera1_datetime},{x1},{y1},{chunk.cameras[1].label},{camera2_datetime},{x2},{y2}\n')
chunk = Metashape.app.document.chunk
common_tiepoints = get_tie_points(chunk.cameras[0], chunk.cameras[1], chunk)
if common_tiepoints:
save_tiepoints_to_csv(common_tiepoints)
else:
print("No common tiepoints found.")
I would also like to include the point ids and raw digital number/color for the grayscale band. Is that possible?