Forum

Author Topic: Possible to get number of projections per camera? As shown in 'Reference' pane  (Read 4211 times)

joacampb

  • Newbie
  • *
  • Posts: 12
    • View Profile
Hello,

I've been digging through the forum and documentation for a day or so, and I am wondering if its possible to get the count of projections per camera? Which would be the value reported in the Reference pane under 'Projections'.

My goal, is to disable any camera with a projection count less than 200.

So something like:
Code: [Select]
for camera in chunk.cameras:
    if (point_cloud.projections[camera]) < 200:
        camera.enabled = False


I am pulling from this post as inspiration: https://www.agisoft.com/forum/index.php?topic=10564.msg47949#msg47949

Code: [Select]
for camera_id, camera in enumerate(Metashape.app.document.chunks[1].cameras):
    projections = Metashape.app.document.chunks[1].point_cloud.projections[camera]
    print(camera, len(projections))

Output:
Quote
2020-11-15 13:00:58 <Camera '_SPK4758'> 1272
2020-11-15 13:00:58 <Camera '_SPK4759'> 972
2020-11-15 13:00:58 <Camera '_SPK4760'> 716
2020-11-15 13:00:58 <Camera '_SPK4761'> 937


I've tried different variations, such as looping through the projections per camera but its the same result as above using the len() function. the value at the end of each loop never matches the Reference Pane

the attached image shows the reference pane next to the console output for the above code. The reference pane says 810 projections for camera _SPK4758, whereas the code says 1272 projections.


So it seems obvious I don't fully understand the point_cloud.projections class and data

Any guidance would be appreciated.



Paulo

  • Hero Member
  • *****
  • Posts: 1320
    • View Profile
Hi joacampb,

the projections[camera] contain all camera projections valid and invalid. So to get only valid projections per camera as printed  in reference pane you can use following:

Code: [Select]
chunk = Metashape.app.document.chunk

point_cloud = chunk.point_cloud
projections = point_cloud.projections
points = point_cloud.points
npoints = len(points)
tracks = point_cloud.tracks
point_ids = [-1] * len(point_cloud.tracks)

for point_id in range(0, npoints):
point_ids[points[point_id].track_id] = point_id


for camera in chunk.cameras:
nprojections = 0

if camera.type == Metashape.Camera.Type.Keyframe:

continue # skipping Keyframes

if not camera.transform:
continue

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:
continue

nprojections += 1

print(camera, nprojections, len(projections[camera]))

and result would  be something like:

Code: [Select]
2020-11-15 13:52:08 <Camera 'IX-11-23119_0096_0230.JPG'> 3565 7377
2020-11-15 13:52:08 <Camera 'IX-11-23119_0096_0231.JPG'> 5409 10381
2020-11-15 13:52:08 <Camera 'IX-11-23119_0096_0232.JPG'> 4487 9117
2020-11-15 13:52:08 <Camera 'IX-11-23119_0096_0233.JPG'> 4354 9017
...

where 1st number after Camera is number of valid projections...

Hope this can help,
Best Regards,
Paul Pelletier,
Surveyor

joacampb

  • Newbie
  • *
  • Posts: 12
    • View Profile
Thank you Paulo!

This was very helpful and makes complete sense to the difference I was seeing. I appreciate the code as it helped spell out some of the logic I was missing as well.

My only question about all of this, is how to conceptualize the 'track_id' and what exactly are camera tracks? I thought they were a path the camera travels around an object or through a space. but I dont understand the relation to the point_cloud under the hood in Metashape and the need to access a projection track_id for this scenario.

If you have time, could you elaborate on the need for the track_id?

Specifically, I am not 100% sure why we would need the track_id here:

Code: [Select]
for point_id in range(0, npoints):
    point_ids[points[point_id].track_id] = point_id


and here:

Code: [Select]
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:
continue


thank you again for your time.



Paulo

  • Hero Member
  • *****
  • Posts: 1320
    • View Profile
In fact the tracks represent the original number of tie points after matching operation. After adjustment some tracks are rejected based on some criteria (precision, gradual selection, etc..) and thus final tie points are less than original tracks.

As you can see in screen capture, the alignement resulted in 59,917 tie points out of 125,424 original tracks....

point_ids populates a list with -1 in case where original tracks were rejected because of above mentioned criteria and values from 0 to number tie points in case where tracks where accepted as tie points...

Hope this makes sense,
« Last Edit: November 16, 2020, 05:40:04 AM by Paulo »
Best Regards,
Paul Pelletier,
Surveyor