Forum

Author Topic: number valid/total matches between pairs of images  (Read 922 times)

Paoline

  • Newbie
  • *
  • Posts: 3
    • View Profile
number valid/total matches between pairs of images
« on: November 28, 2022, 02:35:42 PM »
Hi,

I'm trying to acces the number of total and valid matches between pairs of images with the python API.
After looking through the forum I tried two solutions but neither worked :

> My first code returns the same number for total and valid matches (the total number of matches is the same as in the GUI with --> View Matches)
Code: [Select]
import Metashape
import numpy as np
doc = Metashape.app.document
chunk=doc.chunk

point_cloud = chunk.point_cloud
point_proj = point_cloud.projections
points = point_cloud.points

projection_matches = list()

for camera in chunk.cameras:
photo_proj = point_proj[camera] #get individual projection
total_projections = set()
for proj in photo_proj:
total_projections.add(proj.track_id)
projection_matches.append(total_projections)

i=0
camera=chunk.cameras[i]
list_cameras = [ chunk.cameras.index(photo) for photo in chunk.cameras if photo != camera ]
for j in list_cameras:
  projection_match = projection_matches[i] & projection_matches[j] # Get projections intersections for cameras i and j
 
  total = len(projection_match)
  valid=0
  for p_index in projection_match:
    if points[p_index].valid : valid += 1
   
  if total >0 :  print(camera.label, chunk.cameras[j].label, total, valid)
 


> The second version (is way slower and) returns the right number of total matches but not the same number of valid matches as in the GUI
Code: [Select]
import Metashape
import numpy as np
doc = Metashape.app.document
chunk=doc.chunk

point_cloud = chunk.point_cloud
point_proj = point_cloud.projections
points = point_cloud.points
npoints = len(points)

projection_matches = list() #here projections for total matches will be stored
photo_matches = dict() #here points for valid matches will be stored

for camera in chunk.cameras:
photo_proj = point_proj[camera]
total_projections = set()
for proj in photo_proj:
total_projections.add(proj.track_id)
projection_matches.append(total_projections)

for camera in chunk.cameras:
  i=0
  total_points = set()
  point_index = 0
  proj = point_proj[camera]
  for cur_point in proj:
    track_id = cur_point.track_id
    i+=1
    while point_index < npoints and points[point_index].track_id < track_id:
      point_index += 1
      if point_index < npoints and points[point_index].track_id == track_id:
        if point_cloud.points[point_index].valid:
          total_points.add(point_index)
        photo_matches[camera] = total_points

MatchesKeys = []
for keys in photo_matches.keys():
  MatchesKeys.append(keys)

i=0
camera=chunk.cameras[i]
list_cameras = [ chunk.cameras.index(photo) for photo in chunk.cameras if photo != camera ]
for j in list_cameras:
  projection_match = projection_matches[i] & projection_matches[j] # Get projections intersections for cameras i and j
  point_match = photo_matches[MatchesKeys[i]] & photo_matches[MatchesKeys[j]] # Get points intersections for cameras
 
  total = len(projection_match)
  valid = len(point_match)
  if total >0 :  print(camera.label, chunk.cameras[j].label, total, valid)

Does anyone knows a way to obtain the wanted results?

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 14816
    • View Profile
Re: number valid/total matches between pairs of images
« Reply #1 on: November 28, 2022, 04:29:48 PM »
Hello Paoline,

Please check, if the following function gives you the desired output:

Code: [Select]
import Metashape

def get_tie_point_number(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

#point_cloud = chunk.tie_points #for version 2.0
point_cloud = chunk.point_cloud #for version 1.8
projections = point_cloud.projections
points = point_cloud.points
tracks = point_cloud.tracks
npoints = len(points)
point_ids = [-1] * len(point_cloud.tracks)
for point_id in range(0, npoints):
point_ids[points[point_id].track_id] = point_id
camera_matches_valid = dict()

for camera in [camera1, camera2]:
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)
camera_matches_valid[camera] = valid_matches
valid = camera_matches_valid[camera1].intersection(camera_matches_valid[camera2])

total = set([p.track_id for p in projections[camera1]]).intersection(set([p.track_id for p in projections[camera2]]))

return (len(valid), len(total))

chunk = Metashape.app.document.chunk
Valid, Total = get_tie_point_number(chunk.cameras[0], chunk.cameras[1], chunk)
print(chunk.cameras[0].label, chunk.cameras[1].label, Total, Valid, Total-Valid)

I think that calculation of total common tie points can be optimized and integrated to the main loop, but in this script it is calculated as a separate step.
Best regards,
Alexey Pasumansky,
Agisoft LLC

Paoline

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: number valid/total matches between pairs of images
« Reply #2 on: November 28, 2022, 05:00:28 PM »
Thanks Alexey, that works perfectly !