def load_data(self): """Returns the patch, given the keypoint structure LATER: Cleanup. We currently re-use the utils we had from data extraction. """ # Load image img = cv2.imread(self.config.test_img_file) # If color image, turn it to gray if len(img.shape) == 3: img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) in_dim = 1 # Load keypoints kp = np.asarray(loadKpListFromTxt(self.config.test_kp_file)) # Use load patches function # Assign dummy values to y, ID, angle y = np.zeros((len(kp), )) ID = np.zeros((len(kp), ), dtype='int64') # angle = np.zeros((len(kp),)) angle = np.pi / 180.0 * kp[:, IDX_ANGLE] # store angle in radians # load patches with id (drop out of boundary) bPerturb = False fPerturbInfo = np.zeros((3, )) dataset = load_patches(img, kp, y, ID, angle, get_ratio_scale(self.config), 1.0, int(get_patch_size(self.config)), int(self.config.desc_input_size), in_dim, bPerturb, fPerturbInfo, bReturnCoords=True, is_test=True) # Change old dataset return structure to necessary data x = dataset[0] # y = dataset[1] # ID = dataset[2] pos = dataset[3] angle = dataset[4] coords = dataset[5] # Return the dictionary structure cur_data = {} cur_data["patch"] = np.transpose(x, (0, 2, 3, 1)) # In NHWC cur_data["kps"] = coords cur_data["xyz"] = pos # Make sure that angle is a Nx1 vector cur_data["angle"] = np.reshape(angle, (-1, 1)) return cur_data
def config_to_param(config): """The function that takes care of the transfer to the new framework""" param = paramStruct() # Param Group "dataset" param.dataset.nTestPercent = int(20) param.dataset.dataType = "ECCV" param.dataset.nValidPercent = int(20) param.dataset.fMinKpSize = float(2.0) param.dataset.nPosPerImg = int(-1) # Note that we are passing a list. This module actually supports # concatenating datsets. param.dataset.trainSetList = ["ECCV/" + config.data_name] param.dataset.nNegPerImg = int(1000) param.dataset.nTrainPercent = int(60) # Param Group "patch" if config.old_data_compat: param.patch.nPatchSize = int(get_patch_size(config)) else: param.patch.nPatchSize = int(get_patch_size_no_aug(config)) param.patch.nPatchSizeAug = int(get_patch_size(config)) param.patch.noscale = False param.patch.fNegOverlapTh = float(0.1) param.patch.sNegMineMethod = "use_all_SIFT_points" param.patch.fRatioScale = float(get_ratio_scale(config)) param.patch.fPerturbInfo = np.array([0.2, 0.2, 0.0]).astype(float) if config.old_data_compat: param.patch.nMaxRandomNegMineIter = int(500) else: param.patch.nMaxRandomNegMineIter = int(100) param.patch.fMaxScale = 1.0 param.patch.bPerturb = 1.0 # Param Group "model" param.model.nDescInputSize = int(config.desc_input_size) # override folders from config setattr(param, "data_dir", config.data_dir) setattr(param, "temp_dir", config.temp_dir) setattr(param, "scratch_dir", config.scratch_dir) return param
def _compute_kp(self): """Compute Keypoints. LATER: Clean up code """ total_time = 0.0 # Read image image_color, image_gray, load_prep_time = self.dataset.load_image() # check size image_height = image_gray.shape[0] image_width = image_gray.shape[1] # Multiscale Testing scl_intv = self.config.test_scl_intv # min_scale_log2 = 1 # min scale = 2 # max_scale_log2 = 4 # max scale = 16 min_scale_log2 = self.config.test_min_scale_log2 max_scale_log2 = self.config.test_max_scale_log2 # Test starting with double scale if small image min_hw = np.min(image_gray.shape[:2]) # for the case of testing on same scale, do not double scale if min_hw <= 1600 and min_scale_log2 != max_scale_log2: print("INFO: Testing double scale") min_scale_log2 -= 1 # range of scales to check num_division = (max_scale_log2 - min_scale_log2) * (scl_intv + 1) + 1 scales_to_test = 2**np.linspace(min_scale_log2, max_scale_log2, num_division) # convert scale to image resizes resize_to_test = ((float(self.config.kp_input_size - 1) / 2.0) / (get_ratio_scale(self.config) * scales_to_test)) # check if resize is valid min_hw_after_resize = resize_to_test * np.min(image_gray.shape[:2]) is_resize_valid = min_hw_after_resize > self.config.kp_filter_size + 1 # if there are invalid scales and resizes if not np.prod(is_resize_valid): # find first invalid # first_invalid = np.where(True - is_resize_valid)[0][0] first_invalid = np.where(~is_resize_valid)[0][0] # remove scales from testing scales_to_test = scales_to_test[:first_invalid] resize_to_test = resize_to_test[:first_invalid] print('resize to test is {}'.format(resize_to_test)) print('scales to test is {}'.format(scales_to_test)) # Run for each scale test_res_list = [] for resize in resize_to_test: # resize according to how we extracted patches when training new_height = np.cast['int'](np.round(image_height * resize)) new_width = np.cast['int'](np.round(image_width * resize)) start_time = time.clock() image = cv2.resize(image_gray, (new_width, new_height)) end_time = time.clock() resize_time = (end_time - start_time) * 1000.0 print("Time taken to resize image is {}ms".format(resize_time)) total_time += resize_time # run test # LATER: Compatibility with the previous implementations start_time = time.clock() # Run the network to get the scoremap (the valid region only) scoremap = None if self.config.test_kp_use_tensorflow: scoremap = self.network.test( self.config.subtask, image.reshape(1, new_height, new_width, 1)).squeeze() else: # OpenCV Version raise NotImplementedError("TODO: Implement OpenCV Version") end_time = time.clock() compute_time = (end_time - start_time) * 1000.0 print("Time taken for image size {}" " is {} milliseconds".format(image.shape, compute_time)) total_time += compute_time # pad invalid regions and add to list start_time = time.clock() test_res_list.append( np.pad(scoremap, int((self.config.kp_filter_size - 1) / 2), mode='constant', constant_values=-np.inf)) end_time = time.clock() pad_time = (end_time - start_time) * 1000.0 print("Time taken for padding and stacking is {} ms".format( pad_time)) total_time += pad_time # ------------------------------------------------------------------------ # Non-max suppresion and draw. # The nonmax suppression implemented here is very very slow. Consider # this as just a proof of concept implementation as of now. # Standard nearby : nonmax will check approximately the same area as # descriptor support region. nearby = int( np.round((0.5 * (self.config.kp_input_size - 1.0) * float(self.config.desc_input_size) / float(get_patch_size(self.config))))) fNearbyRatio = self.config.test_nearby_ratio # Multiply by quarter to compensate fNearbyRatio *= 0.25 nearby = int(np.round(nearby * fNearbyRatio)) nearby = max(nearby, 1) nms_intv = self.config.test_nms_intv edge_th = self.config.test_edge_th print("Performing NMS") start_time = time.clock() res_list = test_res_list # check whether the return result for socre is right # print(res_list[0][400:500,300:400]) XYZS = get_XYZS_from_res_list( res_list, resize_to_test, scales_to_test, nearby, edge_th, scl_intv, nms_intv, do_interpolation=True, ) end_time = time.clock() XYZS = XYZS[:self.config.test_num_keypoint] # For debugging # TODO: Remove below draw_XYZS_to_img(XYZS, image_color, self.config.test_out_file + '.jpg') nms_time = (end_time - start_time) * 1000.0 print("NMS time is {} ms".format(nms_time)) total_time += nms_time print("Total time for detection is {} ms".format(total_time)) # if bPrintTime: # # Also print to a file by appending # with open("../timing-code/timing.txt", "a") as timing_file: # print("------ Keypoint Timing ------\n" # "NMS time is {} ms\n" # "Total time is {} ms\n".format( # nms_time, total_time # ), # file=timing_file) # # resize score to original image size # res_list = [cv2.resize(score, # (image_width, image_height), # interpolation=cv2.INTER_NEAREST) # for score in test_res_list] # # make as np array # res_scores = np.asarray(res_list) # with h5py.File('test/scores.h5', 'w') as score_file: # score_file['score'] = res_scores # ------------------------------------------------------------------------ # Save as keypoint file to be used by the oxford thing print("Turning into kp_list") kp_list = XYZS2kpList(XYZS) # note that this is already sorted # ------------------------------------------------------------------------ # LATER: take care of the orientations somehow... # # Also compute angles with the SIFT method, since the keypoint # # component alone has no orientations. # print("Recomputing Orientations") # new_kp_list, _ = recomputeOrientation(image_gray, kp_list, # bSingleOrientation=True) print("Saving to txt") saveKpListToTxt(kp_list, None, self.config.test_out_file)
def compute_kp(self, image_gray): """Compute Keypoints. LATER: Clean up code """ total_time = 0.0 # check size image_height = image_gray.shape[0] image_width = image_gray.shape[1] # Multiscale Testing scl_intv = self.config.test_scl_intv # min_scale_log2 = 1 # min scale = 2 # max_scale_log2 = 4 # max scale = 16 min_scale_log2 = self.config.test_min_scale_log2 max_scale_log2 = self.config.test_max_scale_log2 # Test starting with double scale if small image min_hw = np.min(image_gray.shape[:2]) # for the case of testing on same scale, do not double scale if min_hw <= 1600 and min_scale_log2!=max_scale_log2: print("INFO: Testing double scale") min_scale_log2 -= 1 # range of scales to check num_division = (max_scale_log2 - min_scale_log2) * (scl_intv + 1) + 1 scales_to_test = 2**np.linspace(min_scale_log2, max_scale_log2, num_division) # convert scale to image resizes resize_to_test = ((float(self.config.kp_input_size - 1) / 2.0) / (get_ratio_scale(self.config) * scales_to_test)) # check if resize is valid min_hw_after_resize = resize_to_test * np.min(image_gray.shape[:2]) is_resize_valid = min_hw_after_resize > self.config.kp_filter_size + 1 # if there are invalid scales and resizes if not np.prod(is_resize_valid): # find first invalid first_invalid = np.where(~is_resize_valid)[0][0] # remove scales from testing scales_to_test = scales_to_test[:first_invalid] resize_to_test = resize_to_test[:first_invalid] print('resize to test is {}'.format(resize_to_test)) print('scales to test is {}'.format(scales_to_test)) # Run for each scale test_res_list = [] for resize in resize_to_test: # resize according to how we extracted patches when training new_height = np.cast['int'](np.round(image_height * resize)) new_width = np.cast['int'](np.round(image_width * resize)) start_time = time.clock() image = cv2.resize(image_gray, (new_width, new_height)) end_time = time.clock() resize_time = (end_time - start_time) * 1000.0 print("Time taken to resize image is {}ms".format( resize_time )) total_time += resize_time # run test # LATER: Compatibility with the previous implementations start_time = time.clock() # Run the network to get the scoremap (the valid region only) scoremap = None if self.config.test_kp_use_tensorflow: scoremap = self.graph_kp.test_squeeze(image.reshape(1, new_height, new_width, 1)) else: # OpenCV Version raise NotImplementedError( "TODO: Implement OpenCV Version") end_time = time.clock() compute_time = (end_time - start_time) * 1000.0 print("Time taken for image size {}" " is {} milliseconds".format( image.shape, compute_time)) total_time += compute_time # pad invalid regions and add to list start_time = time.clock() test_res_list.append( np.pad(scoremap, int((self.config.kp_filter_size - 1) / 2), mode='constant', constant_values=-np.inf) ) end_time = time.clock() pad_time = (end_time - start_time) * 1000.0 print("Time taken for padding and stacking is {} ms".format( pad_time )) total_time += pad_time # ------------------------------------------------------------------------ # Non-max suppresion and draw. # The nonmax suppression implemented here is very very slow. Consider # this as just a proof of concept implementation as of now. # Standard nearby : nonmax will check approximately the same area as # descriptor support region. nearby = int(np.round( (0.5 * (self.config.kp_input_size - 1.0) * float(self.config.desc_input_size) / float(get_patch_size(self.config))) )) fNearbyRatio = self.config.test_nearby_ratio # Multiply by quarter to compensate fNearbyRatio *= 0.25 nearby = int(np.round(nearby * fNearbyRatio)) nearby = max(nearby, 1) nms_intv = self.config.test_nms_intv edge_th = self.config.test_edge_th print("Performing NMS") start_time = time.clock() res_list = test_res_list #print(res_list[0][400:500,300:400]) # check whether the return result for socre is right XYZS = get_XYZS_from_res_list( res_list, resize_to_test, scales_to_test, nearby, edge_th, scl_intv, nms_intv, do_interpolation=True, ) end_time = time.clock() XYZS = XYZS[:self.config.test_num_keypoint] nms_time = (end_time - start_time) * 1000.0 print("NMS time is {} ms".format(nms_time)) total_time += nms_time print("Total time for detection is {} ms".format(total_time)) # ------------------------------------------------------------------------ # Save as keypoint file to be used by the oxford thing print("Turning into kp_list") kp_list = XYZS2kpList(XYZS) # note that this is already sorted return kp_list