def bootstrap_reconstruction(data, graph, im1, im2): '''Starts a reconstruction using two shots. ''' print 'Initial reconstruction with', im1, 'and', im2 d1 = data.load_exif(im1) d2 = data.load_exif(im2) cameras = data.load_camera_models() tracks, p1, p2 = dataset.common_tracks(graph, im1, im2) print 'Number of common tracks', len(tracks) f1 = d1['focal_prior'] f2 = d2['focal_prior'] threshold = data.config.get('five_point_algo_threshold', 0.006) ret = csfm.two_view_reconstruction(p1, p2, f1, f2, threshold) if ret is not None: R, t, cov, inliers = ret else: return None if len(inliers): print 'Number of inliers', len(inliers) reconstruction = { "cameras": cameras, "shots" : { im1: { "camera": str(d1['camera']), "rotation": [0.0, 0.0, 0.0], "translation": [0.0, 0.0, 0.0], }, im2: { "camera": str(d2['camera']), "rotation": list(R), "translation": list(t), }, }, "points" : { }, } add_gps_position(data, reconstruction['shots'][im1], im1) add_gps_position(data, reconstruction['shots'][im2], im2) triangulate_shot_features( graph, reconstruction, im1, data.config.get('triangulation_threshold', 0.004), data.config.get('triangulation_min_ray_angle', 2.0)) print 'Number of reconstructed 3D points :{}'.format(len(reconstruction['points'])) if len(reconstruction['points']) > data.config.get('five_point_algo_min_inliers', 50): print 'Found initialize good pair', im1 , 'and', im2 return reconstruction print 'Pair', im1, ':', im2, 'fails' return None
def compute_image_pairs(graph, image_graph, config): '''All matched image pairs sorted by reconstructability. ''' pairs = [] score = [] for im1, im2, d in image_graph.edges(data=True): tracks, p1, p2 = dataset.common_tracks(graph, im1, im2) if len(tracks) >= 50: H, inliers = cv2.findHomography(p1, p2, cv2.RANSAC, config.get('homography_threshold', 0.004)) r = pairwise_reconstructability(len(tracks), inliers.sum()) if r > 0: pairs.append((im1,im2)) score.append(r) order = np.argsort(-np.array(score)) return [pairs[o] for o in order]
def retriangulate(graph, reconstruction, image_graph, config): '''Re-triangulate 3D points ''' P_by_id = {} KR1_by_id = {} Kinv_by_id = {} shots = reconstruction['shots'] points = reconstruction['points'] points_added = 0 tracks_added = [] points_before = len(points) for im1, im2, d in image_graph.edges(data=True): if (im1 in shots) and (im2 in shots): tracks, p1, p2 = dataset.common_tracks(graph, im1, im2) # find already reconstructed tracks diff = np.setdiff1d(tracks, points.keys()) reconstruct_ratio = 1 - len(diff) / float(len(tracks)) if reconstruct_ratio < 0.3: for track in diff: if track not in tracks_added: triangulate_track(track, graph, reconstruction, P_by_id, KR1_by_id, Kinv_by_id, reproj_threshold=0.006) points_added += 1 tracks_added.append(track) # bundle adjustment bundle(graph, reconstruction, config) # filter points with large reprojection errors track_to_delete = [] for track in tracks_added: error = reprojection_error_track(track, graph, reconstruction) if error > config.get('triangulation_threshold', 0.004): track_to_delete.append(track) print 'Add {0} points after retriangulation.'.format( len(reconstruction['points']) - points_before) for t in track_to_delete: if t in reconstruction['points']: del reconstruction['points'][t] # bundle adjustment bundle(graph, reconstruction, config)
def bootstrap_reconstruction(data, graph, im1, im2): """Starts a reconstruction using two shots. """ print "Initial reconstruction with", im1, "and", im2 d1 = data.load_exif(im1) d2 = data.load_exif(im2) cameras = data.load_camera_models() camera1 = cameras[d1["camera"]] camera2 = cameras[d2["camera"]] tracks, p1, p2 = dataset.common_tracks(graph, im1, im2) print "Number of common tracks", len(tracks) threshold = data.config.get("five_point_algo_threshold", 0.006) R, t, inliers = two_view_reconstruction(p1, p2, camera1, camera2, threshold) if len(inliers) > 5: print "Number of inliers", len(inliers) reconstruction = { "cameras": cameras, "shots": { im1: {"camera": str(d1["camera"]), "rotation": [0.0, 0.0, 0.0], "translation": [0.0, 0.0, 0.0]}, im2: {"camera": str(d2["camera"]), "rotation": list(R), "translation": list(t)}, }, "points": {}, } add_gps_position(data, reconstruction["shots"][im1], im1) add_gps_position(data, reconstruction["shots"][im2], im2) triangulate_shot_features( graph, reconstruction, im1, data.config.get("triangulation_threshold", 0.004), data.config.get("triangulation_min_ray_angle", 2.0), ) print "Number of reconstructed 3D points :{}".format(len(reconstruction["points"])) if len(reconstruction["points"]) > data.config.get("five_point_algo_min_inliers", 50): print "Found initialize good pair", im1, "and", im2 bundle_single_view(graph, reconstruction, im2, data.config) retriangulate(graph, reconstruction, data.config) bundle_single_view(graph, reconstruction, im2, data.config) return reconstruction print "Pair", im1, ":", im2, "fails" return None
def retriangulate(graph, reconstruction, image_graph, config): '''Re-triangulate 3D points ''' P_by_id = {} KR1_by_id = {} Kinv_by_id = {} shots = reconstruction['shots'] points = reconstruction['points'] points_added = 0 tracks_added = [] points_before = len(points) for im1, im2, d in image_graph.edges(data=True): if (im1 in shots) and (im2 in shots): tracks, p1, p2 = dataset.common_tracks(graph, im1, im2) # find already reconstructed tracks diff = np.setdiff1d(tracks, points.keys()) reconstruct_ratio = 1 - len(diff)/float(len(tracks)) if reconstruct_ratio < 0.3: for track in diff: if track not in tracks_added: triangulate_track(track, graph, reconstruction, P_by_id, KR1_by_id, Kinv_by_id, reproj_threshold=0.006) points_added += 1 tracks_added.append(track) # bundle adjustment bundle(graph, reconstruction, config) # filter points with large reprojection errors track_to_delete = [] for track in tracks_added: error = reprojection_error_track(track, graph, reconstruction) if error > config.get('triangulation_threshold', 0.004): track_to_delete.append(track) print 'Add {0} points after retriangulation.'.format(len(reconstruction['points']) - points_before) for t in track_to_delete: if t in reconstruction['points']: del reconstruction['points'][t] # bundle adjustment bundle(graph, reconstruction, config)