Agisoft Metashape
Agisoft Metashape => Python and Java API => Topic started by: b3059651 on April 30, 2015, 10:20:33 PM
-
Hi all,
It is great the support we get from this forum to solve issues. It seems that Agisoft provides fantastic results. :)
I would like to export the reprojection error of a sparse point cloud in order to perform accuracy assessment of my results.
This follows the same question from here: http://www.agisoft.com/forum/index.php?topic=3534.msg19362#msg19362
Please any feedback would be great!!!
Regards,
Maria
-
Hello Maria,
Sorry for the late reply.
Please try the following script:
# Compatibility - Agisoft PhotoScan Professional 1.1.6
# saves reprojection error for the tie points in the cloud
# export format:
# point_index X-coord Y-coord Z-coord reproj_error
import PhotoScan
import math, time
doc = PhotoScan.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 = PhotoScan.app.getSaveFileName("Specify export path and filename:")
file = open(path, "wt")
print("Script started")
t0 = time.time()
points_coords = {}
points_errors = {}
for photo in chunk.cameras:
if not photo.transform:
continue
T = photo.transform.inv()
calib = photo.sensor.calibration
point_index = 0
for proj in projections[photo]:
track_id = proj.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 not points[point_index].valid:
continue
dist = calib.error(T.mulp(points[point_index].coord), proj.coord).norm() ** 2
v = M.mulp(points[point_index].coord)
if point_index in points_errors.keys():
point_index = int(point_index)
points_errors[point_index].x += dist
points_errors[point_index].y += 1
else:
points_errors[point_index] = PhotoScan.Vector([dist, 1])
for point_index in range(npoints):
if not points[point_index].valid:
continue
if chunk.crs:
X, Y, Z = chunk.crs.project(M.mulp(points[point_index].coord))
else:
X, Y, Z = M.mulp(points[point_index].coord)
error = math.sqrt(points_errors[point_index].x / points_errors[point_index].y)
file.write("{}\t{:.6f}\t{:.6f}\t{:.6f}\t{:.6f}\n".format(point_index, X, Y, Z, error))
t1 = time.time()
file.flush()
file.close()
print("Script finished in " + str(int(t1-t0)) + " seconds.")
-
Hello
Maria, thanks for the request
Alexey, many thanks for your effort, I have been looking forward to this
I was wondering if this is what Gradual Selection->Reprojection Error is based on
If this is the case, there's a slight discrepancy, due to rounding errors perhaps?
...not a big deal , but it might affect people with OCD; I suppose I am one of them ???
for example
I used the GUI to delete points with Gradual Selection->Reprojection Error > 1px
and the script to export them:
Most of the times there was one single point with error slightly larger than 1px left behind i.e. 1.004907 or 1.031976
any ideas?
regards
-
updated for v1.2.4
http://www.agisoft.com/forum/index.php?topic=5267.msg26171#msg26171