def run(img_path, cfg): '''Wrapper over OpenCV SURF. Parameters ---------- img_path (str): Path to images. cfg: (Namespace): Configuration. ''' # Init opencv feature extractor if cfg.method_dict['config_common']['keypoint'].lower() == 'surf-def': feature = cv2.xfeatures2d.SURF_create() elif cfg.method_dict['config_common']['keypoint'].lower() == 'surf-lowth': feature = cv2.xfeatures2d.SURF_create(hessianThreshold=0) else: raise RuntimeError('Unknown local feature type') # Load Image img, _ = load_image(img_path, use_color_image=False, crop_center=False) # Compute features kp, desc = feature.detectAndCompute(img, None) # Convert opencv keypoints into our benchmark format kp, desc = convert_opencv_kp_desc( kp, desc, cfg.method_dict['config_common']['num_keypoints']) result = {} result['kp'] = [p[0:2] for p in kp] result['scale'] = [p[2] for p in kp] result['angle'] = [p[3] for p in kp] result['score'] = [p[4] for p in kp] result['descs'] = desc return result
def run(img_path, cfg): '''Wrapper over OpenCV ORB. Parameters ---------- img_path (str): Path to images. cfg: (Namespace): Configuration. ''' # Init opencv feature extractor feature = cv2.ORB_create( nfeatures=cfg.method_dict['config_common']['num_keypoints']) # Load Image img, _ = load_image(img_path, use_color_image=False, crop_center=False) # Compute features kp, desc = feature.detectAndCompute(img, None) # Convert opencv keypoints into our benchmark format kp, desc = convert_opencv_kp_desc( kp, desc, cfg.method_dict['config_common']['num_keypoints']) result = {} result['kp'] = [p[0:2] for p in kp] result['descs'] = desc return result
def run(img_path, cfg): '''Wrapper over OpenCV SIFT. Parameters ---------- img_path (str): Path to images. cfg: (Namespace): Configuration. Valid keypoint methods: "sift-def" (standard detection threshold) and "sift-lowth" (lowered detection threshold to extract 8000 features). Optional suffixes: "-clahe" (applies CLAHE over the image). Valid descriptors methods: "sift" and "rootsift". Optional suffixes: "-clahe" (applies CLAHE over the image), "upright" (sets keypoint orientations to 0, removing duplicates). ''' # Parse options kp_name = cfg.method_dict['config_common']['keypoint'].lower() desc_name = cfg.method_dict['config_common']['descriptor'].lower() num_kp = cfg.method_dict['config_common']['num_keypoints'] # Do a strict name check to prevent mistakes (e.g. due to flag order) if kp_name == 'sift-def': use_lower_det_th = False use_clahe_det = False elif kp_name == 'sift-lowth': use_lower_det_th = True use_clahe_det = False elif kp_name == 'sift-def-clahe': use_lower_det_th = False use_clahe_det = True elif kp_name == 'sift-lowth-clahe': use_lower_det_th = True use_clahe_det = True else: raise ValueError('Unknown detector') if desc_name == 'sift': use_rootsift = False use_clahe_desc = False use_upright = False elif desc_name == 'rootsift': use_rootsift = True use_clahe_desc = False use_upright = False elif desc_name == 'sift-clahe': use_rootsift = False use_clahe_desc = True use_upright = False elif desc_name == 'rootsift-clahe': use_rootsift = True use_clahe_desc = True use_upright = False elif desc_name == 'sift-upright': use_rootsift = False use_clahe_desc = False use_upright = True elif desc_name == 'rootsift-upright': use_rootsift = True use_clahe_desc = False use_upright = True elif desc_name == 'sift-clahe-upright': use_rootsift = False use_clahe_desc = True use_upright = True elif desc_name == 'rootsift-clahe-upright': use_rootsift = True use_clahe_desc = True use_upright = True else: raise ValueError('Unknown descriptor') # print('Extracting SIFT features with' # ' use_lower_det_th={},'.format(use_lower_det_th), # ' use_clahe_det={},'.format(use_clahe_det), # ' use_rootsift={},'.format(use_rootsift), # ' use_clahe_desc={},'.format(use_clahe_desc), # ' use_upright={}'.format(use_upright)) # Initialize feature extractor if use_lower_det_th: feature = cv2.xfeatures2d.SIFT_create(contrastThreshold=-10000, edgeThreshold=-10000) else: feature = cv2.xfeatures2d.SIFT_create() # Load image, for detection if use_clahe_det: img_det, _ = load_image(img_path, use_color_image=True, crop_center=False) img_det = l_clahe(img_det) else: img_det, _ = load_image(img_path, use_color_image=False, crop_center=False) # Load image, for descriptor extraction if use_clahe_desc: img_desc, _ = load_image(img_path, use_color_image=True, crop_center=False) img_desc = l_clahe(img_desc) else: img_desc, _ = load_image(img_path, use_color_image=False, crop_center=False) # Get keypoints kp = feature.detect(img_det, None) # Compute descriptors if use_upright: unique_kp = [] for i, x in enumerate(kp): if i > 0: if x.response == kp[i - 1].response: continue x.angle = 0 unique_kp.append(x) unique_kp, unique_desc = feature.compute(img_desc, unique_kp, None) top_resps = np.array([x.response for x in unique_kp]) idxs = np.argsort(top_resps)[::-1] kp = np.array(unique_kp)[idxs[:min(len(unique_kp), num_kp)]] desc = unique_desc[idxs[:min(len(unique_kp), num_kp)]] else: kp, desc = feature.compute(img_desc, kp, None) # Use root-SIFT if use_rootsift: desc /= desc.sum(axis=1, keepdims=True) + 1e-8 desc = np.sqrt(desc) # Convert opencv keypoints into our format kp, desc = convert_opencv_kp_desc(kp, desc, num_kp) result = {} result['kp'] = [p[0:2] for p in kp] result['scale'] = [p[2] for p in kp] result['angle'] = [p[3] for p in kp] result['score'] = [p[4] for p in kp] result['descs'] = desc return result
def main(cfg): '''Visualization of colmap points. Parameters ---------- cfg: Namespace Configurations for running this part of the code. ''' bag_size_json = load_json( getattr(cfg, 'splits_{}_{}'.format(cfg.dataset, cfg.subset))) bag_size_list = [b['bag_size'] for b in bag_size_json] bag_size_num = [b['num_in_bag'] for b in bag_size_json] # # Do not re-run if files already exist -- off for now # skip = True # for _bag_size in bag_size_list: # cfg_bag = deepcopy(cfg) # cfg_bag.bag_size = _bag_size # viz_folder_hq, viz_folder_lq = get_colmap_viz_folder(cfg_bag) # for _bag_id in range( # getattr(cfg_bag, # 'num_viz_colmap_subsets_bagsize{}'.format(_bag_size))): # if any([ # not os.path.exists( # os.path.join( # viz_folder_lq, # 'colmap-bagsize{:d}-bag{:02d}-image{:02d}.jpg'. # format(_bag_size, _bag_id, i))) # for i in range(_bag_size) # ]): # skip = False # break # if not os.path.exists( # os.path.join( # viz_folder_lq, # 'colmap-bagsize{:d}-bag{:02d}.pcd'.format( # _bag_size, _bag_id))): # skip = False # break # if skip: # print(' -- already exists, skipping colmap visualization') # return print(' -- Visualizations, multiview: "{}/{}"'.format( cfg.dataset, cfg.scene)) t_start = time() # Create results folder if it does not exist for _bag_size in bag_size_list: cfg_bag = deepcopy(cfg) cfg_bag.bag_size = _bag_size viz_folder_hq, viz_folder_lq = get_colmap_viz_folder(cfg_bag) if not os.path.exists(viz_folder_hq): os.makedirs(viz_folder_hq) if not os.path.exists(viz_folder_lq): os.makedirs(viz_folder_lq) # Load keypoints keypoints_dict = load_h5(get_kp_file(cfg)) # Loop over bag sizes for _bag_size in bag_size_list: cfg_bag = deepcopy(cfg) cfg_bag.bag_size = _bag_size num_bags = getattr( cfg_bag, 'num_viz_colmap_subsets_bagsize{}'.format(_bag_size)) for _bag_id in range(num_bags): print( ' -- Visualizations, multiview: "{}/{}", bag_size={}, bag {}/{}' .format(cfg.dataset, cfg.scene, _bag_size, _bag_id + 1, num_bags)) # Retrieve list of images cfg_bag.bag_id = _bag_id images_in_bag = get_colmap_image_path_list(cfg_bag) # Retrieve reconstruction colmap_output_path = get_colmap_output_path(cfg_bag) # is_colmap_valid = os.path.exists( # os.path.join(colmap_output_path, '0')) best_index = get_best_colmap_index(cfg_bag) if best_index != -1: colmap_images = read_images_binary( os.path.join(colmap_output_path, str(best_index), 'images.bin')) for i, image_path in enumerate(images_in_bag): # Limit to 10 or so, even for bag size 25 if i >= cfg.max_num_images_viz_multiview: break # Load image and keypoints im, _ = load_image(image_path, use_color_image=True, crop_center=False, force_rgb=True) used = None key = os.path.splitext(os.path.basename(image_path))[0] if best_index != -1: for j in colmap_images: if key in colmap_images[j].name: # plot all keypoints used = colmap_images[j].point3D_ids != -1 break if used is None: used = [False] * keypoints_dict[key].shape[0] used = np.array(used) fig = plt.figure(figsize=(20, 20)) plt.imshow(im) plt.plot(keypoints_dict[key][~used, 0], keypoints_dict[key][~used, 1], 'r.', markersize=12) plt.plot(keypoints_dict[key][used, 0], keypoints_dict[key][used, 1], 'b.', markersize=12) plt.tight_layout() plt.axis('off') # TODO Ideally we would save to pdf # but it does not work on 16.04, so we do png instead # https://bugs.launchpad.net/ubuntu/+source/imagemagick/+bug/1796563 viz_folder_hq, viz_folder_lq = get_colmap_viz_folder(cfg_bag) viz_file_hq = os.path.join( viz_folder_hq, 'bagsize{:d}-bag{:02d}-image{:02d}.png'.format( _bag_size, _bag_id, i)) viz_file_lq = os.path.join( viz_folder_lq, 'bagsize{:d}-bag{:02d}-image{:02d}.jpg'.format( _bag_size, _bag_id, i)) plt.savefig(viz_file_hq, bbox_inches='tight') # Convert with imagemagick os.system('convert -quality 75 -resize \"400>\" {} {}'.format( viz_file_hq, viz_file_lq)) plt.close() if best_index != -1: colmap_points = read_points3d_binary( os.path.join(colmap_output_path, str(best_index), 'points3D.bin')) points3d = [] for k in colmap_points: points3d.append([ colmap_points[k].xyz[0], colmap_points[k].xyz[1], colmap_points[k].xyz[2] ]) points3d = np.array(points3d) points3d -= np.median(points3d, axis=0)[None, ...] points3d /= np.abs(points3d).max() + 1e-6 pcd = os.path.join( get_colmap_viz_folder(cfg_bag)[0], 'colmap-bagsize{:d}-bag{:02d}.pcd'.format( _bag_size, _bag_id)) with open(pcd, 'w') as f: f.write('# .PCD v.7 - Point Cloud Data file format\n') f.write('VERSION .7\n') f.write('FIELDS x y z\n') f.write('SIZE 4 4 4\n') f.write('TYPE F F F\n') f.write('COUNT 1 1 1\n') f.write('WIDTH {}\n'.format(len(colmap_points))) f.write('HEIGHT 1\n') f.write('VIEWPOINT 0 0 0 1 0 0 0\n') f.write('POINTS {}\n'.format(len(colmap_points))) f.write('DATA ascii\n') for p in points3d: f.write('{:.05f} {:.05f} {:.05f}\n'.format( p[0], p[1], p[2])) copyfile( os.path.join( get_colmap_viz_folder(cfg_bag)[0], 'colmap-bagsize{:d}-bag{:02d}.pcd'.format( _bag_size, _bag_id)), os.path.join( get_colmap_viz_folder(cfg_bag)[1], 'colmap-bagsize{:d}-bag{:02d}.pcd'.format( _bag_size, _bag_id))) print('done [{:.02f} s.]'.format(time() - t_start))