def main(): parser = argparse.ArgumentParser(description="Calibrate using keypoint matches"); parser.add_argument('pattern_key_fname', type=str, help='reference pattern keypoint file') parser.add_argument('num_frames', type=int, help='Number of scene frames') parser.add_argument('scene_key_fmt', type=str, help='Printf-formatted string representing keypoint files from N scene frames') parser.add_argument('match_fmt', type=str, help='Printf-formatted string representing keypoint match files') parser.add_argument('example_image', type=str, help='Example image to get dimensions from') parser.add_argument('out_fname', type=str, help='filename for intrinsic calibrated camera') parser.add_argument('--min_matches', default=20, type=str, help='omit frames with fewer than N matches') args = parser.parse_args() pattern_keys = feat.read_features(args.pattern_key_fname)[0]; fnames = [(args.scene_key_fmt % x, args.match_fmt % x) for x in range(1,args.num_frames+1)] fnames = [x for x in fnames if os.path.isfile(x[0])] if len(fnames) == 0: print "No matching keypoint files" exit(1) missing = next((x[1] for x in fnames if not os.path.isfile(x[1])), None) if missing is not None: print "File not found: %s" % missing exit(1) [frame_fnames, match_fnames] = zip(*fnames) print "reading keypoint from %d frames" % len(frame_fnames) frames_keys = [feat.read_features(x)[0] for x in frame_fnames] print "reading matches from %d frames" % len(match_fnames) frames_matches = [feat.read_matches(x) for x in match_fnames] img = cv2.imread(args.example_image) img_size = (img.shape[1], img.shape[0]); [obj_pts, image_pts] = to_calibration_data(frames_matches, pattern_keys, frames_keys, args.min_matches) cam = calibrate_intrinsic(obj_pts, image_pts, img_size) calib.write_intrinsic_camera(args.out_fname, cam);
def main(): parser = argparse.ArgumentParser(description="Match keypoints and calibrate camera"); parser.add_argument('pattern_key_fname', type=str, help='reference pattern keypoint file') parser.add_argument('num_frames', type=int, help='Number of scene frames') parser.add_argument('scene_key_fmt', type=str, help='Printf-formatted string representing keypoint files from N scene frames') parser.add_argument('example_image', type=str, help='Example image (used to get dimensions)') parser.add_argument('out_matches_fmt', type=str, help='printf string for output matches filenames') parser.add_argument('out_camera_fname', type=str, help='output camera intrinsic calibration filename') parser.add_argument('--num_iterations', nargs='?', type=int, default=0.6, help='number of iterations of match & homography re-estimation (2-3 is usually good)') parser.add_argument('--lowe_threshold', nargs='?', type=float, default=0.6, help='Use David Lowe\'s ratio criterion for pruning bad matches') parser.add_argument('--homography_threshold', nargs='?', type=float, default=0, help='fit a homography to matches and prune by this reprojection error threshold (zero ignores)') parser.add_argument('--H_det_threshold', nargs='?', type=float, default=0, help='ignore frame if fitted homography has too small of a determinant.') parser.add_argument('--f_threshold', nargs='?', type=float, default=2, help='fit a fundamental matrix to matches and prune by this error threshold (zero ignores)') parser.add_argument('--min_matches', nargs='?', type=int, default=25, help='Minimum number of matches in a frame to be accepted into calibration set') args = parser.parse_args() [pattern_keys, pattern_descs] = feat.read_features(args.pattern_key_fname); if args.num_frames == 1: frame_fnames = [args.scene_key_fmt] out_match_fnames = [args.out_matches_fmt] else: I = range(1, args.num_frames+1) frame_fnames = [args.scene_key_fmt % x for x in I] out_match_fnames = [args.out_matches_fmt % x for x in I] tmp = [(a,b) for (a,b) in zip(frame_fnames, out_match_fnames) if os.path.isfile(a)] [frame_fnames, out_match_fnames] = zip(*tmp) if len(frame_fnames) == 0: print "No files found matching %s" % args.scene_key_fmt exit(1) print "reading keypoint from %d frames" % len(frame_fnames) frames_features = [feat.read_features(x) for x in frame_fnames] [frames_keys, frames_descs] = zip(*frames_features) img = cv2.imread(args.example_image) img_size = (img.shape[1], img.shape[0]); distortion = np.zeros((1,5)) pattern_kp_mat = np.array([x.pt for x in pattern_keys], np.float32) frame_kp_mats = [np.array([x.pt for x in keys], np.float32) for keys in frames_keys] fixed_kp_mats = [x.copy() for x in frame_kp_mats] frames_matches = [feat.match_features(pattern_descs, descs, args.lowe_threshold) for descs in frames_descs] for i in range(0, args.num_iterations): print "Iteration %d" % i homo_matches = [] homo_keys = [] for [kp_mat, fixed_kp_mat, matches] in zip(frame_kp_mats, fixed_kp_mats, frames_matches): if len(matches) < args.min_matches: homo_matches.append([]) homo_keys.append([]) continue filtered_matches = matches; if args.homography_threshold > 0: [filtered_matches, H] = feat.filter_matches_by_homography( pattern_kp_mat, fixed_kp_mat, filtered_matches, args.homography_threshold) det_H = np.linalg.det(H) if args.H_det_threshold > 0 and det_H < args.H_det_threshold: filtered_matches = [] print "%d matches after homography filter" % len(filtered_matches) if args.f_threshold > 0 and len(filtered_matches) > 4: filtered_matches = feat.filter_matches_by_fundamental_matrix( pattern_kp_mat, fixed_kp_mat, filtered_matches, args.f_threshold) print "%d matches after fundamental matrix filter" % len(filtered_matches) homo_matches.append(filtered_matches) homo_keys.append(kp_mat) if len(homo_matches) == 0: print "Error: No frames with sufficient matches found" exit(1) # gather calibration data tmp = [(x,y) for (x,y) in zip(homo_matches, homo_keys) if len(x) >= args.min_matches] print "using %d frames for calibration after pruning bad frames" % len(tmp) tmp = [calib.keypoint_matches_to_calibration_data(m, pattern_kp_mat, k) \ for (m,k) in tmp] [obj_pts, img_pts] = zip(*tmp) # perform calibration [error, K, distortion, rvecs, tvecs] = cv2.calibrateCamera(obj_pts, img_pts, img_size) if i < args.num_iterations-1: # undistort image points, which will improve # homography filtering next iteration fixed_kp_mats = [] for kp_mat in frame_kp_mats: tmp = np.reshape(kp_mat, (-1, 1, 2)) if kp_mat.shape[0] == 0: tmp = kp_mat else: tmp = cv2.undistortPoints(tmp, K, distortion, P=K) fixed_kp_mats.append(np.reshape(tmp, (-1, 2))) out_matchset = [x if len(x) >= args.min_matches else [] for x in homo_matches] assert(len(out_match_fnames) == len(out_matchset)) map(lambda (fname, m): feat.write_matches(fname, m), zip(out_match_fnames, out_matchset)) cam = calib.Intrinsic_camera() cam.K = K cam.distortion = distortion cam.image_size = img_size calib.write_intrinsic_camera(args.out_camera_fname, cam)
def main(): parser = argparse.ArgumentParser( description="Match keypoints and calibrate camera") parser.add_argument('pattern_key_fname', type=str, help='reference pattern keypoint file') parser.add_argument('num_frames', type=int, help='Number of scene frames') parser.add_argument( 'scene_key_fmt', type=str, help= 'Printf-formatted string representing keypoint files from N scene frames' ) parser.add_argument('example_image', type=str, help='Example image (used to get dimensions)') parser.add_argument('out_matches_fmt', type=str, help='printf string for output matches filenames') parser.add_argument('out_camera_fname', type=str, help='output camera intrinsic calibration filename') parser.add_argument( '--num_iterations', nargs='?', type=int, default=0.6, help= 'number of iterations of match & homography re-estimation (2-3 is usually good)' ) parser.add_argument( '--lowe_threshold', nargs='?', type=float, default=0.6, help='Use David Lowe\'s ratio criterion for pruning bad matches') parser.add_argument( '--homography_threshold', nargs='?', type=float, default=0, help= 'fit a homography to matches and prune by this reprojection error threshold (zero ignores)' ) parser.add_argument( '--H_det_threshold', nargs='?', type=float, default=0, help='ignore frame if fitted homography has too small of a determinant.' ) parser.add_argument( '--f_threshold', nargs='?', type=float, default=2, help= 'fit a fundamental matrix to matches and prune by this error threshold (zero ignores)' ) parser.add_argument( '--min_matches', nargs='?', type=int, default=25, help= 'Minimum number of matches in a frame to be accepted into calibration set' ) args = parser.parse_args() [pattern_keys, pattern_descs] = feat.read_features(args.pattern_key_fname) if args.num_frames == 1: frame_fnames = [args.scene_key_fmt] out_match_fnames = [args.out_matches_fmt] else: I = range(1, args.num_frames + 1) frame_fnames = [args.scene_key_fmt % x for x in I] out_match_fnames = [args.out_matches_fmt % x for x in I] tmp = [(a, b) for (a, b) in zip(frame_fnames, out_match_fnames) if os.path.isfile(a)] [frame_fnames, out_match_fnames] = zip(*tmp) if len(frame_fnames) == 0: print "No files found matching %s" % args.scene_key_fmt exit(1) print "reading keypoint from %d frames" % len(frame_fnames) frames_features = [feat.read_features(x) for x in frame_fnames] [frames_keys, frames_descs] = zip(*frames_features) img = cv2.imread(args.example_image) img_size = (img.shape[1], img.shape[0]) distortion = np.zeros((1, 5)) pattern_kp_mat = np.array([x.pt for x in pattern_keys], np.float32) frame_kp_mats = [ np.array([x.pt for x in keys], np.float32) for keys in frames_keys ] fixed_kp_mats = [x.copy() for x in frame_kp_mats] frames_matches = [ feat.match_features(pattern_descs, descs, args.lowe_threshold) for descs in frames_descs ] for i in range(0, args.num_iterations): print "Iteration %d" % i homo_matches = [] homo_keys = [] for [kp_mat, fixed_kp_mat, matches] in zip(frame_kp_mats, fixed_kp_mats, frames_matches): if len(matches) < args.min_matches: homo_matches.append([]) homo_keys.append([]) continue filtered_matches = matches if args.homography_threshold > 0: [filtered_matches, H] = feat.filter_matches_by_homography( pattern_kp_mat, fixed_kp_mat, filtered_matches, args.homography_threshold) det_H = np.linalg.det(H) if args.H_det_threshold > 0 and det_H < args.H_det_threshold: filtered_matches = [] print "%d matches after homography filter" % len( filtered_matches) if args.f_threshold > 0 and len(filtered_matches) > 4: filtered_matches = feat.filter_matches_by_fundamental_matrix( pattern_kp_mat, fixed_kp_mat, filtered_matches, args.f_threshold) print "%d matches after fundamental matrix filter" % len( filtered_matches) homo_matches.append(filtered_matches) homo_keys.append(kp_mat) if len(homo_matches) == 0: print "Error: No frames with sufficient matches found" exit(1) # gather calibration data tmp = [(x, y) for (x, y) in zip(homo_matches, homo_keys) if len(x) >= args.min_matches] print "using %d frames for calibration after pruning bad frames" % len( tmp) tmp = [calib.keypoint_matches_to_calibration_data(m, pattern_kp_mat, k) \ for (m,k) in tmp] [obj_pts, img_pts] = zip(*tmp) # perform calibration [error, K, distortion, rvecs, tvecs] = cv2.calibrateCamera(obj_pts, img_pts, img_size) if i < args.num_iterations - 1: # undistort image points, which will improve # homography filtering next iteration fixed_kp_mats = [] for kp_mat in frame_kp_mats: tmp = np.reshape(kp_mat, (-1, 1, 2)) if kp_mat.shape[0] == 0: tmp = kp_mat else: tmp = cv2.undistortPoints(tmp, K, distortion, P=K) fixed_kp_mats.append(np.reshape(tmp, (-1, 2))) out_matchset = [ x if len(x) >= args.min_matches else [] for x in homo_matches ] assert (len(out_match_fnames) == len(out_matchset)) map(lambda (fname, m): feat.write_matches(fname, m), zip(out_match_fnames, out_matchset)) cam = calib.Intrinsic_camera() cam.K = K cam.distortion = distortion cam.image_size = img_size calib.write_intrinsic_camera(args.out_camera_fname, cam)
def main(): parser = argparse.ArgumentParser( description="Calibrate using keypoint matches") parser.add_argument('pattern_key_fname', type=str, help='reference pattern keypoint file') parser.add_argument('num_frames', type=int, help='Number of scene frames') parser.add_argument( 'scene_key_fmt', type=str, help= 'Printf-formatted string representing keypoint files from N scene frames' ) parser.add_argument( 'match_fmt', type=str, help='Printf-formatted string representing keypoint match files') parser.add_argument('example_image', type=str, help='Example image to get dimensions from') parser.add_argument('out_fname', type=str, help='filename for intrinsic calibrated camera') parser.add_argument('--min_matches', default=20, type=str, help='omit frames with fewer than N matches') args = parser.parse_args() pattern_keys = feat.read_features(args.pattern_key_fname)[0] fnames = [(args.scene_key_fmt % x, args.match_fmt % x) for x in range(1, args.num_frames + 1)] fnames = [x for x in fnames if os.path.isfile(x[0])] if len(fnames) == 0: print "No matching keypoint files" exit(1) missing = next((x[1] for x in fnames if not os.path.isfile(x[1])), None) if missing is not None: print "File not found: %s" % missing exit(1) [frame_fnames, match_fnames] = zip(*fnames) print "reading keypoint from %d frames" % len(frame_fnames) frames_keys = [feat.read_features(x)[0] for x in frame_fnames] print "reading matches from %d frames" % len(match_fnames) frames_matches = [feat.read_matches(x) for x in match_fnames] img = cv2.imread(args.example_image) img_size = (img.shape[1], img.shape[0]) [obj_pts, image_pts] = to_calibration_data(frames_matches, pattern_keys, frames_keys, args.min_matches) cam = calibrate_intrinsic(obj_pts, image_pts, img_size) calib.write_intrinsic_camera(args.out_fname, cam)