def detect(self, frame, mask=None): if self.row_divs == 1 and self.col_divs == 1: return self.detector.detect(frame, mask) else: if kVerbose: print('BlockAdaptor ', self.row_divs, 'x', self.col_divs) block_generator = img_mask_blocks(frame, mask, self.row_divs, self.col_divs) kps_all = [] # list are thread-safe def detect_block(b_m_i_j): b, m, i, j = b_m_i_j if kVerbose and False: print('BlockAdaptor in block (', i, ',', j, ')') kps = self.detector.detect(b, mask=m) #print('adaptor: detected #features: ', len(kps), ' in block (',i,',',j,')') for kp in kps: #print('kp.pt before: ', kp.pt) kp.pt = (kp.pt[0] + j, kp.pt[1] + i) #print('kp.pt after: ', kp.pt) kps_all.extend(kps) if not self.do_parallel: # process the blocks sequentially for b, m, i, j in block_generator: detect_block((b, m, i, j)) else: with ThreadPoolExecutor(max_workers=4) as executor: executor.map( detect_block, block_generator ) # automatic join() at the end of the `width` block return np.array(kps_all)
def detectAndCompute(self, frame, mask=None): if self.row_divs == 1 and self.col_divs == 1: return self.detector.detectAndCompute(frame, mask) else: if kVerbose: print('BlockAdaptor ', self.row_divs, 'x', self.col_divs) block_generator = img_mask_blocks(frame, mask, self.row_divs, self.col_divs) kps_all = [] des_all = [] kps_des_map = {} # (i,j) -> (kps,des) def detect_and_compute_block(b_m_i_j): b, m, i, j = b_m_i_j if kVerbose and False: print('BlockAdaptor in block (', i, ',', j, ')') if self.is_detector_equal_to_descriptor: kps, des = self.detector.detectAndCompute(b, mask=m) else: kps = self.detector.detect(b, mask=m) kps, des = self.descriptor.compute(b, kps) #print('adaptor: detected #features: ', len(kps), ' in block (',i,',',j,')') # transform the points for kp in kps: #print('kp.pt before: ', kp.pt) kp.pt = (kp.pt[0] + j, kp.pt[1] + i) #print('kp.pt after: ', kp.pt) kps_des_map[(i, j)] = (kps, des) if not self.do_parallel: # process the blocks sequentially for b, m, i, j in block_generator: detect_and_compute_block((b, m, i, j)) else: with ThreadPoolExecutor( max_workers=kBlockAdaptorMaxNumWorkers) as executor: executor.map( detect_and_compute_block, block_generator ) # automatic join() at the end of the `width` block # now merge the computed results for ij, (kps, des) in kps_des_map.items(): kps_all.extend(kps) if des is not None and len(des) > 0: if len(des_all) > 0: des_all = np.vstack([des_all, des]) else: des_all = des return np.array(kps_all), np.array(des_all)