def subpixel_register(self, clean_keys=[], threshold=0.8, template_size=19, search_size=53, max_x_shift=1.0, max_y_shift=1.0, tiled=False, **kwargs): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search max_x_shift : float The maximum (positive) value that a pixel can shift in the x direction without being considered an outlier max_y_shift : float The maximum (positive) value that a pixel can shift in the y direction without being considered an outlier """ matches = self.matches for column, default in {'x_offset': 0, 'y_offset': 0, 'correlation': 0, 'reference': -1}.items(): if column not in self.matches.columns: self.matches[column] = default # Build up a composite mask from all of the user specified masks matches, mask = self._clean(clean_keys) # Grab the full images, or handles if tiled is True: s_img = self.source.geodata d_img = self.destination.geodata else: s_img = self.source.geodata.read_array() d_img = self.destination.geodata.read_array() source_image = (matches.iloc[0]['source_image']) # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_keypoint = self.source.get_keypoint_coordinates(s_idx) d_keypoint = self.destination.get_keypoint_coordinates(d_idx) # Get the template and search window s_template = sp.clip_roi(s_img, s_keypoint, template_size) d_search = sp.clip_roi(d_img, d_keypoint, search_size) try: x_offset, y_offset, strength = sp.subpixel_offset(s_template, d_search, **kwargs) self.matches.loc[idx, ('x_offset', 'y_offset', 'correlation', 'reference')] = [x_offset, y_offset, strength, source_image] except: warnings.warn('Template-Search size mismatch, failing for this correspondence point.') continue # Compute the mask for correlations less than the threshold threshold_mask = self.matches['correlation'] >= threshold # Compute the mask for the point shifts that are too large query_string = 'x_offset <= -{0} or x_offset >= {0} or y_offset <= -{1} or y_offset >= {1}'.format(max_x_shift, max_y_shift) sp_shift_outliers = self.matches.query(query_string) shift_mask = pd.Series(True, index=self.matches.index) shift_mask.loc[sp_shift_outliers.index] = False # Generate the composite mask and write the masks to the mask data structure mask = threshold_mask & shift_mask self.masks = ('shift', shift_mask) self.masks = ('threshold', threshold_mask) self.masks = ('subpixel', mask)
def subpixel_register(self, clean_keys=[], threshold=0.8, upsampling=16, template_size=19, search_size=53, max_x_shift=1.0, max_y_shift=1.0, tiled=False): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search max_x_shift : float The maximum (positive) value that a pixel can shift in the x direction without being considered an outlier max_y_shift : float The maximum (positive) value that a pixel can shift in the y direction without being considered an outlier """ matches = self.matches self.subpixel_offsets = pd.DataFrame(0, index=matches.index, columns=['x_offset', 'y_offset', 'correlation', 's_idx', 'd_idx']) # Build up a composite mask from all of the user specified masks if clean_keys: matches, mask = self._clean(clean_keys) if tiled is True: s_img = self.source.handle d_img = self.destination.handle else: s_img = self.source.handle.read_array() d_img = self.destination.handle.read_array() # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_keypoint = self.source.keypoints.iloc[s_idx][['x', 'y']].values d_keypoint = self.destination.keypoints.iloc[d_idx][['x', 'y']].values # Get the template and search window s_template = sp.clip_roi(s_img, s_keypoint, template_size) d_search = sp.clip_roi(d_img, d_keypoint, search_size) try: x_off, y_off, strength = sp.subpixel_offset(s_template, d_search, upsampling=upsampling) self.subpixel_offsets.loc[idx] = [x_off, y_off, strength,s_idx, d_idx] except: warnings.warn('Template-Search size mismatch, failing for this correspondence point.') continue self.subpixel_offsets.to_sparse(fill_value=0.0) # Compute the mask for correlations less than the threshold threshold_mask = self.subpixel_offsets['correlation'] >= threshold # Compute the mask for the point shifts that are too large subp= self.subpixel_offsets query_string = 'x_offset <= -{0} or x_offset >= {0} or y_offset <= -{1} or y_offset >= {1}'.format(max_x_shift, max_y_shift) sp_shift_outliers = subp.query(query_string) shift_mask = pd.Series(True, index=self.subpixel_offsets.index) shift_mask[sp_shift_outliers.index] = False # Generate the composite mask and write the masks to the mask data structure mask = threshold_mask & shift_mask self.masks = ('shift', shift_mask) self.masks = ('threshold', threshold_mask) self.masks = ('subpixel', mask)
def compute_subpixel_offset(self, clean_keys=[], threshold=0.8, upsampling=16, template_size=19, search_size=53): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search """ matches = self.matches full_offsets = np.zeros((len(matches), 3)) # Build up a composite mask from all of the user specified masks if clean_keys: mask = np.prod([self._mask_arrays[i] for i in clean_keys], axis=0, dtype=np.bool) matches = matches[mask] full_mask = np.where(mask == True) # Preallocate the numpy array to avoid appending and type conversion edge_offsets = np.empty((len(matches), 3)) # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_keypoint = self.source.keypoints.iloc[s_idx][['x', 'y']].values d_keypoint = self.destination.keypoints.iloc[d_idx][['x', 'y']].values # Get the template and search windows s_template = sp.clip_roi(self.source.handle, s_keypoint, template_size) d_search = sp.clip_roi(self.destination.handle, d_keypoint, search_size) try: edge_offsets[i] = sp.subpixel_offset(s_template, d_search, upsampling=upsampling) except: warnings.warn( 'Template-Search size mismatch, failing for this correspondence point.' ) continue # Compute the mask for correlations less than the threshold threshold_mask = edge_offsets[edge_offsets[:, -1] >= threshold] # Convert the truncated mask back into a full length mask if clean_keys: mask[full_mask] = threshold_mask full_offsets[full_mask] = edge_offsets else: mask = threshold_mask self.subpixel_offsets = pd.DataFrame( full_offsets, columns=['x_offset', 'y_offset', 'correlation']) self.masks = ('subpixel', mask)
def subpixel_register(self, clean_keys=[], threshold=0.8, template_size=19, search_size=53, max_x_shift=1.0, max_y_shift=1.0, tiled=False, **kwargs): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search max_x_shift : float The maximum (positive) value that a pixel can shift in the x direction without being considered an outlier max_y_shift : float The maximum (positive) value that a pixel can shift in the y direction without being considered an outlier """ matches = self.matches for column, default in { 'x_offset': 0, 'y_offset': 0, 'correlation': 0, 'reference': -1 }.items(): if column not in self.matches.columns: self.matches[column] = default # Build up a composite mask from all of the user specified masks matches, mask = self._clean(clean_keys) # Grab the full images, or handles if tiled is True: s_img = self.source.geodata d_img = self.destination.geodata else: s_img = self.source.geodata.read_array() d_img = self.destination.geodata.read_array() source_image = (matches.iloc[0]['source_image']) # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_keypoint = self.source.get_keypoint_coordinates(s_idx) d_keypoint = self.destination.get_keypoint_coordinates(d_idx) # Get the template and search window s_template = sp.clip_roi(s_img, s_keypoint, template_size) d_search = sp.clip_roi(d_img, d_keypoint, search_size) try: x_offset, y_offset, strength = sp.subpixel_offset( s_template, d_search, **kwargs) self.matches.loc[idx, ('x_offset', 'y_offset', 'correlation', 'reference')] = [ x_offset, y_offset, strength, source_image ] except: warnings.warn( 'Template-Search size mismatch, failing for this correspondence point.' ) continue # Compute the mask for correlations less than the threshold threshold_mask = self.matches['correlation'] >= threshold # Compute the mask for the point shifts that are too large query_string = 'x_offset <= -{0} or x_offset >= {0} or y_offset <= -{1} or y_offset >= {1}'.format( max_x_shift, max_y_shift) sp_shift_outliers = self.matches.query(query_string) shift_mask = pd.Series(True, index=self.matches.index) shift_mask.loc[sp_shift_outliers.index] = False # Generate the composite mask and write the masks to the mask data structure mask = threshold_mask & shift_mask self.masks = ('shift', shift_mask) self.masks = ('threshold', threshold_mask) self.masks = ('subpixel', mask)
def compute_subpixel_offsets(self, clean_keys=[], threshold=0.8, upsampling=10, template_size=9, search_size=27): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search """ for source, destination, attributes in self.edges_iter(data=True): matches = attributes['matches'] full_offsets = np.zeros((len(matches), 3)) # Build up a composite mask from all of the user specified masks if clean_keys: mask = np.prod([attributes[i] for i in clean_keys], axis=0, dtype=np.bool) matches = matches[mask] full_mask = np.where(mask == True) src_image = self.node[source]['image'] dest_image = self.node[destination]['image'] # Preallocate the numpy array to avoid appending and type conversion edge_offsets = np.empty((len(matches),3)) # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_node = self.node[source] d_node = self.node[destination] s_keypoint = s_node['keypoints'][s_idx].pt d_keypoint = d_node['keypoints'][d_idx].pt # Get the template and search windows s_template = sp.clip_roi(src_image, s_keypoint, template_size) d_search = sp.clip_roi(dest_image, d_keypoint, search_size) edge_offsets[i] = sp.subpixel_offset(s_template, d_search, upsampling=upsampling) # Compute the mask for correlations less than the threshold threshold_mask = edge_offsets[edge_offsets[:,-1] >= threshold] # Convert the truncated mask back into a full length mask if clean_keys: mask[full_mask] = threshold_mask full_offsets[full_mask] = edge_offsets else: mask = threshold_mask attributes['subpixel_offsets'] = pd.DataFrame(full_offsets, columns=['x_offset', 'y_offset', 'correlation']) attributes['subpixel'] = mask
def compute_subpixel_offset(self, clean_keys=[], threshold=0.8, upsampling=16, template_size=19, search_size=53): """ For the entire graph, compute the subpixel offsets using pattern-matching and add the result as an attribute to each edge of the graph. Parameters ---------- clean_keys : list of string keys to masking arrays (created by calling outlier detection) threshold : float On the range [-1, 1]. Values less than or equal to this threshold are masked and can be considered outliers upsampling : int The multiplier to the template and search shapes to upsample for subpixel accuracy template_size : int The size of the template in pixels, must be odd search_size : int The size of the search """ matches = self.matches full_offsets = np.zeros((len(matches), 3)) # Build up a composite mask from all of the user specified masks if clean_keys: mask = np.prod([self._mask_arrays[i] for i in clean_keys], axis=0, dtype=np.bool) matches = matches[mask] full_mask = np.where(mask == True) # Preallocate the numpy array to avoid appending and type conversion edge_offsets = np.empty((len(matches),3)) # for each edge, calculate this for each keypoint pair for i, (idx, row) in enumerate(matches.iterrows()): s_idx = int(row['source_idx']) d_idx = int(row['destination_idx']) s_keypoint = self.source.keypoints.iloc[s_idx][['x', 'y']].values d_keypoint = self.destination.keypoints.iloc[d_idx][['x', 'y']].values # Get the template and search windows s_template = sp.clip_roi(self.source.handle, s_keypoint, template_size) d_search = sp.clip_roi(self.destination.handle, d_keypoint, search_size) try: edge_offsets[i] = sp.subpixel_offset(s_template, d_search, upsampling=upsampling) except: warnings.warn('Template-Search size mismatch, failing for this correspondence point.') continue # Compute the mask for correlations less than the threshold threshold_mask = edge_offsets[edge_offsets[:, -1] >= threshold] # Convert the truncated mask back into a full length mask if clean_keys: mask[full_mask] = threshold_mask full_offsets[full_mask] = edge_offsets else: mask = threshold_mask self.subpixel_offsets = pd.DataFrame(full_offsets, columns=['x_offset', 'y_offset', 'correlation']) self.masks = ('subpixel', mask)