def detect(image_path: str, config: Dict, detector: Any) -> Tuple[List, np.array, None]: """Detects keypoints for a given input image. Draws keypoints into the image. Returns keypoints, heatmap and image with keypoints. """ img = cv2.imread(image_path, 0) img = io_utils.smart_scale( img, config['max_size'], prevent_upscaling=config['prevent_upscaling'] ) if config['max_size'] is not None else img # Get keypoints kpts = detector.detect(img, None) # Sort by response, take best n <= max_num_keypoints kpts.sort(key=lambda x: x.response, reverse=True) img_kp = io_utils.draw_keypoints(img, kpts, config) return (kpts, img_kp, None)
def detect(image_path: str, config: Dict, model: SuperPointFrontend, size: int = None ) -> Tuple[List[cv2.KeyPoint], np.array, np.array, np.array]: """Computes the keypoints and descriptors for a given input image. Draws keypoints into the image. Returns keypoints, descriptors and image with keypoints. Arguments: image_path {np.array} -- Path to the image. model {superpoint_frontend.SuperPointFrontend} -- The SuperPoint keypoint detector and descriptor. config {Dict} -- Configuration object. See config_run_detector.py Returns: Tuple[List[cv2.KeyPoint], np.array, np.array, None] -- Returns tuple (keypoints, descriptors, image with keypoints, image of heatmap). """ img = cv2.imread(image_path, 0) img = io_utils.smart_scale( img, config['max_size'], prevent_upscaling=config['prevent_upscaling'] ) if config['max_size'] is not None else img _kp, desc, heatmap = detectAndCompute(img, config, model) # Sort by confidences, descending. _kp, desc = _sort_keypoints_and_descriptors_by_confidence(_kp, desc) # Take n-th best max_num_kp = config['max_num_keypoints'] if max_num_kp: _kp = _kp[:max_num_kp] desc = desc[:max_num_kp] # Convert to list of openCV's KeyPoint kp = kps2KeyPoints(_kp) img_kp = io_utils.draw_keypoints(img, kp, config) return (kp, desc, img_kp, heatmap)
def detect(image_path: str, config: Dict, model: CustomModelLift) -> None: """Detects keypoints for a given input image. Draws keypoints into the image. Returns keypoints, heatmap and image with keypoints. 1) Load and smart scale the image. 2) Save the resulting image in `tmp` folder. 3) Subprocess call to tf-lift for keypoints. Save output text file in `tmp`. 4) Load text file as as np.array with dimension [num_kp x 13] 5) Convert keypoints to list of cv2.Keypoint. 6) Draw list of cv2.KeyPoints into image. 7) Return KeyPoint list, descriptors and image with KeyPoints. """ lift_path = os.path.join(config['root_dir_lift'], 'tf-lift') # 1) img = cv2.imread(image_path, 0) img = io_utils.smart_scale( img, config['max_size'], prevent_upscaling=config['prevent_upscaling'] ) if config['max_size'] is not None else img kpts_numpy = chunkify_image(img, config, model) # Sort by response kpts_numpy = _sort_keypoints_by_response(kpts_numpy) # Take n-th best if config['max_num_keypoints']: kpts_numpy = kpts_numpy[:config['max_num_keypoints']] # 5) Convert to cv2.KeyPoint list kpts_cv2 = kp_list_2_opencv_kp_list(kpts_numpy) # 6) Draw keypoints in image img_kp = io_utils.draw_keypoints(img, kpts_cv2, config) return (kpts_cv2, img_kp, None)
def detect( image_path: str, config: dict) -> None: """Detects keypoints for a given input image. Draws keypoints into the image. Returns keypoints, heatmap and image with keypoints. Arguments: image_path {str} -- Path to the image. config {dict} -- General configuations. See config_run_detectors.py. Returns: Tuple[List[cv2.KeyPoint], np.array, (np.array | None) ] -- Returns list of cv2.KeyPoint, an image with the corresponding keypoints, and if available, an heatmap. 1) Create temporary folder `tmp` to save intermediate output. 2a) Load and smart scale the image 2b) Save the resulting image in `tmp`. 3a) Subprocess call to TILDE for keypoints. Save output in `tmp` 4a) Load keypoints from 'tmp' and convert keypoints to cv2.Keypoints. 4b) Draw list of cv2.KeyPoints into image. 5) Return KeyPoint list and image with keypoints. """ # 1) io_utils.create_dir(config['tmp_dir_tilde']) # 2) img = cv2.imread(image_path, 0) img = io_utils.smart_scale(img, config['max_size'], prevent_upscaling=config['prevent_upscaling']) if config['max_size'] is not None else img # 2b) tmp_filename = 'tmp_img.png' tmp_keypoints = 'keypoints.csv' tmp_heatmap = 'heatmap.csv' path_tmp_img = os.path.join(config['tmp_dir_tilde'], tmp_filename) path_tmp_kpts = os.path.join(config['tmp_dir_tilde'], tmp_keypoints) path_tmp_heatmap = os.path.join(config['tmp_dir_tilde'], tmp_heatmap) cv2.imwrite(path_tmp_img, img) # 3a) imageDir = config['tmp_dir_tilde'] outputDir = config['tmp_dir_tilde'] fileName = tmp_filename filterPath = '/home/tilde/TILDE/c++/Lib/filters' filterName = 'Mexico.txt' # Call use_tilde.cpp # The output will be saved into # - config['tmp_dir_tilde']/keypoints.csv and # - config['tmp_dir_tilde']/heatmap.csv subprocess.check_call([ './use_tilde', '--imageDir', imageDir, '--outputDir', outputDir, '--fileName', fileName, '--filterPath', filterPath, '--filterName', filterName]) # 4) kpts_file = np.loadtxt(path_tmp_kpts, dtype=int, comments='#', delimiter=', ') max_num_keypoints = config['max_num_keypoints'] if max_num_keypoints: kpts_file = kpts_file[:max_num_keypoints] kpts = [cv2.KeyPoint(x[0], x[1], _size=1) for x in kpts_file] heatmap = np.loadtxt(path_tmp_heatmap, dtype=float, comments='# ', delimiter=', ') img_kp = io_utils.draw_keypoints(img, kpts, config) return (kpts, img_kp, heatmap)
def detect_bulk(file_list: List[str], config: Dict) -> None: """Computes keypoints for all files in `file_list`. Additionally for each file, create an image with the corresponding keypoints drawn into it. All results will be saved within the `tmp` folder for this module. Arguments: file_list {List[str]} -- List of all images for which to compute keypoints. config {Dict} -- General configuration object. See config_run_detectors.py for more information. Returns: None -- All results here are saved within the `tmp` dir specified within the `config` object. """ try: # Create feature map for each image in 'covariant_points' folder subprocess.check_call([ 'python', 'patch_network_point_test.py', '--save_feature', 'covariant_points', '--output_dir', config['tmp_dir_tcovdet'], '--file_list', ' '.join(file_list), ]) except Exception as e: print('TCovDet: Covariant feature map creation failed.') print(e) raise e try: collection_names = [] set_names = [] image_names = [] for file_path in file_list: collection_name, set_name, file_base, extension = io_utils.get_path_components( file_path) collection_names.append(collection_name) set_names.append(set_name) image_names.append(file_base) # The path to this file matlab_config_path = os.path.join(config['tmp_dir_tcovdet'], 'filelist.mat') # Where to save the keypoints dir_output = os.path.join(config['tmp_dir_tcovdet'], 'feature_points') io_utils.create_dir(dir_output) # Create on the fly if not existent # Where the .mat files of the covariant step lie dir_data = os.path.join(config['tmp_dir_tcovdet'], 'covariant_points') # Set maxinal number of keypoints to find point_number = 1000 if config['max_num_keypoints'] is None else config[ 'max_num_keypoints'] savemat( matlab_config_path, { 'file_list': file_list, 'collection_names': collection_names, 'set_names': set_names, 'image_names': image_names, 'dir_output': dir_output, 'dir_data': dir_data, 'point_number': point_number }) subprocess.check_call([ 'matlab', '-nosplash', '-r', "point_extractor('vlfeat-0.9.21', '{}');quit".format( matlab_config_path) ]) except Exception as e: print('TCovDet: Keypoint feature map creation failed.') print(e) raise e # Load each created .mat file, extract the keypoints (Column 2 and 5), # create list of cv2.KeyPoint. # Then load the image, scale it, draw the keypoints in it and save everything for i in tqdm(range(len(file_list))): file = file_list[i] mat_path = os.path.join(config['tmp_dir_tcovdet'], 'feature_points', collection_names[i], set_names[i], image_names[i] + '.mat') kpts_numpy = loadmat(mat_path)['feature'][:, [2, 5]] # numpy array scores = loadmat(mat_path)['score'] if len(kpts_numpy): kpts_cv2 = [ cv2.KeyPoint(x[0], x[1], 1.0, _response=scores[idx]) for idx, x in enumerate(kpts_numpy) ] # list of cv2.KeyPoint img = cv2.imread(file, 0) if (img.shape[0] * img.shape[1]) > (1024 * 768): ratio = (1024 * 768 / float(img.shape[0] * img.shape[1]))**(0.5) img = cv2.resize( img, (int(img.shape[1] * ratio), int(img.shape[0] * ratio)), interpolation=cv2.INTER_CUBIC) img_kp = io_utils.draw_keypoints(img, kpts_cv2, config) # Save everything. io_utils.save_detector_output(file, config['detector_name'], config, kpts_cv2, img_kp, None) else: print('Warning: Did not find any keypoints!')