Forum

Author Topic: visualize success of matching process  (Read 6758 times)

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
visualize success of matching process
« on: May 03, 2017, 03:21:28 PM »
I often end up with subsets of my chunk that appear as if they are matched, but if you look closely they are just well positioned by ground control and not actually linked to each other. So I am looking for a way to visualize matches.

My goal: Save to file the labels and XYZ coordinates for every two cameras that have at least three valid matches.
Code: [Select]
CAM1.jpg, X_coord, Y_coord, Z_coord, CAM2.jpg, X_coord, Y_coord, Z_coord
...

I intend to plot lines in between each of those two coordinates either in 2D or 3D.

I have found a snippet of code in a previous post but never got it to work. It always returns the total number of matches, not the valid ones, and it has other issues too.

Hello James,

Currently these numbers are not accessible through Python, but if you wish I can post a sample script to do the calculations (unfortunately, for large datasets it's quite slow).

Could someone please have a look at this?
It is really important and I have not solved this after several attempts...
Here is my attempt at getting the script to run:

Code: [Select]
import PhotoScan

doc = PhotoScan.app.document
chunk = doc.chunk

point_cloud = chunk.point_cloud
point_proj = point_cloud.projections

photo_matches = list()
total_matches = list() #here the result will be stored

for photo in chunk.cameras:
try:
photo_proj = point_proj[photo]
total = set()
for proj in photo_proj:
total.add(proj.index)
except:
total = set()
photo_matches.append(total)

for i in range(0, len(chunk.cameras) - 1):
for j in range(i + 1, len(chunk.cameras)):
match = photo_matches[i] & photo_matches[j]

total = 0
valid = 0
invalid = 0

for p_index in match:
if point_cloud.points[p_index].valid:
valid += 1
total = len(match)
invalid = total - valid

pos_i = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[i].center))
pos_j = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[j].center))

if valid > 3:
total_matches.append((chunk.cameras[i].label, pos_i , chunk.cameras[j].label, pos_j, total, valid, invalid)) #the result - photo1, photo2, total, valid, invalid
else:
continue

print(total_matches)

Thanks so much!
Tom

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: visualize success of matching process
« Reply #1 on: May 22, 2017, 06:51:02 PM »
Allow me to renew my request for assistance...

Alexey Pasumansky

  • Agisoft Technical Support
  • Hero Member
  • *****
  • Posts: 15083
    • View Profile
Re: visualize success of matching process
« Reply #2 on: May 24, 2017, 10:54:08 PM »
Hello Tom,

Sorry for the late reply.

Can you please try the following script. It prints the requested information to the console, but you can redirect and modify the output if necessary:

Code: [Select]
import PhotoScan

doc = PhotoScan.app.document
chunk = doc.chunk
point_cloud = chunk.point_cloud
points = point_cloud.points
point_proj = point_cloud.projections
npoints = len(points)

photo_matches = dict()

for photo in chunk.cameras:

total = set() #only valid
point_index = 0
proj = point_proj[photo]

for cur_point in proj:

track_id = cur_point.track_id
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.add(point_index)

photo_matches[photo] = total

for i in range(0, len(chunk.cameras) - 1):
if chunk.cameras[i] not in photo_matches.keys():
continue

for j in range(i + 1, len(chunk.cameras)):

if chunk.cameras[j] not in photo_matches.keys():
continue

matches = photo_matches[chunk.cameras[i]] & photo_matches[chunk.cameras[j]]
if len(matches) > 3:
pos_i = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[i].center))
pos_j = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[j].center))
print(chunk.cameras[i].label, pos_i, chunk.cameras[j].label, pos_j)
else:
continue
Best regards,
Alexey Pasumansky,
Agisoft LLC

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: visualize success of matching process
« Reply #3 on: May 30, 2017, 11:02:09 AM »
Dear Alexey,
thank you so much, this is an incredible help!

And the results are quite shocking! The script takes a while to run as you said earlier. How can I update the GUI while photoscan runs? I added some print commands in between the loops but they all just show up at the end.

May I suggest that within the Photoscan GUI, you enable the user to select all the cameras in the "view matches" window or introduce a "select all" button? this would allow the user to check for the same thing locally, since all the images surrounding a photo should light up.

Best greetings
Tom

tkwasnitschka

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: visualize success of matching process
« Reply #4 on: May 30, 2017, 11:45:21 AM »
The above script does not handle non-aligned images in a chunk. Not a big problem, though.

I modified it to work only on a selection of images which is also handy to simplify the graph and cut down on the substantial time it takes to run, e.g. one should now select every second image before running it.

You can now also specify the destination folder and the minimum number of valid tie points from the gui.

Code: [Select]
import PhotoScan

doc = PhotoScan.app.document
chunk = doc.chunk
point_cloud = chunk.point_cloud
points = point_cloud.points
point_proj = point_cloud.projections
npoints = len(points)

photo_matches = dict()


path = PhotoScan.app.getSaveFileName("Specify export path and filename:")
print("exporting to", path)
file = open(path, "wt")
# file.write("Image_A Coords_A Image_B Coords_B\n")

step = PhotoScan.app.getInt("Minimum number of valid tie points:" ,3)

# Select photos in the gui on which to run the export

selected_photos = list()
for photo in chunk.cameras:
if photo.selected:
selected_photos.append(photo)

# Find matching image pairs:

for photo in selected_photos:

total = set() #only valid
point_index = 0
proj = point_proj[photo]

for cur_point in proj:

track_id = cur_point.track_id
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.add(point_index)
# print("listing photo:", photo.label)
photo_matches[photo] = total

for i in range(0, len(chunk.cameras) - 1):
if chunk.cameras[i] not in photo_matches.keys():
continue

for j in range(i + 1, len(chunk.cameras)):

if chunk.cameras[j] not in photo_matches.keys():
continue

matches = photo_matches[chunk.cameras[i]] & photo_matches[chunk.cameras[j]]
if len(matches) > step:
pos_i = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[i].center))
pos_j = chunk.crs.project(chunk.transform.matrix.mulp(chunk.cameras[j].center))
file.write("%s %s %s %s\n" %(chunk.cameras[i].label, pos_i, chunk.cameras[j].label, pos_j))
# print("matching:",chunk.cameras[i].label," & ", chunk.cameras[j].label)
else:
continue
print("export of valid matches completed!")
file.close()

bwbj

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: visualize success of matching process
« Reply #5 on: August 13, 2018, 03:29:42 PM »
Hi, tkwasnitschka and Alexey Pasumansky:
    I import the script and the solution seems perfect. However, for my project, the number of invalid points(as the 'view matches' table shown when you right click the photo) is also quite important.
    I have tried several ways but fail to acquire this value. Any suggestion? Thanks in advance.