Loading autocnet/matcher/naive_template.py +37 −15 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from math import floor import cv2 import numpy as np from scipy.ndimage.interpolation import zoom from skimage.transform import rescale from scipy.ndimage.measurements import center_of_mass Loading Loading @@ -80,7 +81,7 @@ def pattern_match_autoreg(template, image, subpixel_size=3, metric=cv2.TM_CCOEFF return x, y, max_corr, result def pattern_match(template, image, upsampling=16, metric=cv2.TM_CCOEFF_NORMED, error_check=False): def pattern_match(template, image, upsampling=8, metric=cv2.TM_CCOEFF_NORMED, error_check=False): """ Call an arbitrary pattern matcher using a subpixel approach where the template and image are upsampled using a third order polynomial. Loading Loading @@ -117,37 +118,58 @@ def pattern_match(template, image, upsampling=16, metric=cv2.TM_CCOEFF_NORMED, e if upsampling < 1: raise ValueError print(template) print(image) # Fit a 3rd order polynomial to upsample the images if upsampling != 1: u_template = zoom(template, upsampling, order=3) u_image = zoom(image, upsampling, order=3) u_template = rescale(template, upsampling, order=1, mode='edge', preserve_range=True) u_image = rescale(image, upsampling, order=1, mode='edge', preserve_range=True) else: u_template = template u_image = image h, w = u_template.shape[:2] print(u_image) print(u_template) result = cv2.matchTemplate(u_image, u_template, method=metric) _, max_corr, min_loc, max_loc = cv2.minMaxLoc(result) print(result) print("min/max loc: ", min_loc, max_loc) _, max_corr, min_loc, max_loc = cv2.minMaxLoc(result) if metric == cv2.TM_SQDIFF or metric == cv2.TM_SQDIFF_NORMED: x, y = (min_loc[0], min_loc[1]) x = (min_loc[0] + w//2) / upsampling y = (min_loc[1] + h//2) / upsampling else: x, y = (max_loc[0], max_loc[1]) x = ((max_loc[0] + w//2)) / upsampling y = ((max_loc[1] + h//2)) / upsampling print('things', x, y, max_loc, h, w) return x, y, max_corr, result # -1 because the returned results array is W-w+1 and H-h+1 in shape, # where W, H are the width and height of the image and w,h are the # width and height of the template print(u_template.shape, u_image.shape, result.shape, x,y) print(u_image.shape, u_template.shape, max_loc) # the max_loc array is of shape W-w+1, H-h+1, where W, H are the width # and height of the image and w,h are the width and height of the template print(x / upsampling - 1, y / upsampling - 1) # Compute the idealized shift (image center) ideal_y = u_image.shape[0] / 2. ideal_x = u_image.shape[1] / 2. ideal_y = (u_image.shape[0] + 1) / 2. - 0.5 ideal_x = (u_image.shape[1] + 1) / 2. - 0.5 # Compute the shift from template upper left to template center y += (u_template.shape[0] / 2.) x += (u_template.shape[1] / 2.) print("x,ideal x, ", x, ideal_x, (x - ideal_x) / upsampling) print("y,ideal y, ", y, ideal_y, (y - ideal_y) / upsampling) # x = (x - ideal_x) / upsampling y = (y - ideal_y) / upsampling y = ((y - ideal_y) / upsampling) + 1 print(x, y) return x, y, max_corr, result autocnet/matcher/subpixel.py +28 −16 Original line number Diff line number Diff line Loading @@ -208,12 +208,15 @@ def subpixel_phase(reference_roi, moving_roi, affine=tf.AffineTransform(), **kwa walking_template, **kwargs) # get shifts in input pixel space shift_x, shift_y = affine.inverse([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_x, -shift_y)) shift_x, shift_y = affine([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_y, -shift_x)) return new_affine, error, diffphase def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mode='reflect', def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mode='reflect', func=pattern_match, **kwargs): """ Loading Loading @@ -260,7 +263,7 @@ def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mo ref_clip = reference_roi.clip() moving_clip = moving_roi.clip(affine) print(affine) if moving_clip.var() == 0: warnings.warn('Input ROI has no variance.') return [None] * 3 Loading @@ -270,7 +273,7 @@ def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mo shift_x, shift_y, metrics, corrmap = func(moving_clip, ref_clip, **kwargs) if shift_x is None: return None, None, None print(shift_x, shift_y) # get shifts in input pixel space shift_x, shift_y = affine.inverse([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_x, -shift_y)) Loading Loading @@ -1715,8 +1718,8 @@ def subpixel_register_point_smart(pointid, destination_node.geodata, source.apriorisample, source.aprioriline, 60, 60) 30, 30) except Exception as e: print(e) m = {'id': measure.id, Loading @@ -1737,8 +1740,16 @@ def subpixel_register_point_smart(pointid, if match_kwarg['template_size'][1] < size_y: size_y = match_kwarg['template_size'][1] reference_roi = roi.Roi(source_node.geodata, source.apriorisample, source.aprioriline, size_x=size_x, size_y=size_y) moving_roi = roi.Roi(destination_node.geodata, measure.apriorisample, measure.aprioriline, size_x=size_x, size_y=size_y) reference_roi = roi.Roi(source_node.geodata, source.apriorisample, source.aprioriline, size_x=size_x, size_y=size_y) moving_roi = roi.Roi(destination_node.geodata, measure.apriorisample, measure.aprioriline, size_x=size_x, size_y=size_y) _, baseline_corr, _ = subpixel_template(reference_roi, moving_roi, Loading Loading @@ -1766,6 +1777,7 @@ def subpixel_register_point_smart(pointid, baseline_mi = mutual_information(base_roi, dst_roi)""" baseline_mi = 0 print(f'Baseline MI: {baseline_mi} | Baseline Corr: {baseline_corr}') print(affine) for parameter in parameters: match_kwargs = parameter['match_kwargs'] Loading @@ -1782,6 +1794,7 @@ def subpixel_register_point_smart(pointid, updated_affine, maxcorr, temp_corrmap = subpixel_template(reference_roi, moving_roi, affine=affine) print(updated_affine) """ if x is None or y is None: print('Unable to match with this parameter set.') Loading @@ -1803,10 +1816,9 @@ def subpixel_register_point_smart(pointid, else: metric = maxcorr new_x, new_y = updated_affine([measure.sample, measure.line])[0] dist = np.linalg.norm([measure.sample-new_x, measure.line-new_y]) dist = np.linalg.norm([measure.line-new_x, measure.sample-new_y]) cost = cost_func(dist, metric) print(new_x, new_y, dist) m = {'id': measure.id, 'sample':new_x, Loading autocnet/transformation/roi.py +1 −3 Original line number Diff line number Diff line Loading @@ -130,14 +130,12 @@ class Roi(): if left_x < 0 or top_y < 0 or right_x > raster_size[0] or bottom_y > raster_size[1]: raise IndexError(f"Input window size {(self.size_x, self.size_y)}) at center {(self.x, self.y)} is out of the image bounds") print("extents:", list(map(int, [left_x, right_x, top_y, bottom_y]))) print("center:", self.x, self.y, self.size_x, self.size_y) return list(map(int, [left_x, right_x, top_y, bottom_y])) @property def center(self): ie = self.image_extent return (ie[1] - ie[0])/2.+0.5, (ie[3]-ie[2])/2.+0.5 return (ie[1] - ie[0])/2., (ie[3]-ie[2])/2. @property def is_valid(self): Loading tests/test_subpixel_match.py +6 −6 Original line number Diff line number Diff line Loading @@ -36,12 +36,12 @@ def test_full_subpixel_registration(ncg, images, point): 'chooser':'smart_subpixel_registration'} parameters = [ {'match_kwargs': {'image_size':(121,121), 'template_size':(61,61)}}, {'match_kwargs': {'image_size':(151,151), 'template_size':(67,67)}}, {'match_kwargs': {'image_size':(181,181), 'template_size':(73,73)}}, {'match_kwargs': {'image_size':(221,221), 'template_size':(81,81)}}, {'match_kwargs': {'image_size':(251,251), 'template_size':(89,89)}}, {'match_kwargs': {'image_size':(281,281), 'template_size':(98,98)}} {'match_kwargs': {'image_size':(61,61), 'template_size':(31,31)}}, {'match_kwargs': {'image_size':(75,75), 'template_size':(33,33)}}, {'match_kwargs': {'image_size':(91,91), 'template_size':(37,37)}}, {'match_kwargs': {'image_size':(111,111), 'template_size':(41,41)}}, {'match_kwargs': {'image_size':(125,125), 'template_size':(45,45)}}, {'match_kwargs': {'image_size':(141,141), 'template_size':(49,49)}} ] measures_to_update, measures_to_set_false = smart_register_point(1, Loading Loading
autocnet/matcher/naive_template.py +37 −15 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from math import floor import cv2 import numpy as np from scipy.ndimage.interpolation import zoom from skimage.transform import rescale from scipy.ndimage.measurements import center_of_mass Loading Loading @@ -80,7 +81,7 @@ def pattern_match_autoreg(template, image, subpixel_size=3, metric=cv2.TM_CCOEFF return x, y, max_corr, result def pattern_match(template, image, upsampling=16, metric=cv2.TM_CCOEFF_NORMED, error_check=False): def pattern_match(template, image, upsampling=8, metric=cv2.TM_CCOEFF_NORMED, error_check=False): """ Call an arbitrary pattern matcher using a subpixel approach where the template and image are upsampled using a third order polynomial. Loading Loading @@ -117,37 +118,58 @@ def pattern_match(template, image, upsampling=16, metric=cv2.TM_CCOEFF_NORMED, e if upsampling < 1: raise ValueError print(template) print(image) # Fit a 3rd order polynomial to upsample the images if upsampling != 1: u_template = zoom(template, upsampling, order=3) u_image = zoom(image, upsampling, order=3) u_template = rescale(template, upsampling, order=1, mode='edge', preserve_range=True) u_image = rescale(image, upsampling, order=1, mode='edge', preserve_range=True) else: u_template = template u_image = image h, w = u_template.shape[:2] print(u_image) print(u_template) result = cv2.matchTemplate(u_image, u_template, method=metric) _, max_corr, min_loc, max_loc = cv2.minMaxLoc(result) print(result) print("min/max loc: ", min_loc, max_loc) _, max_corr, min_loc, max_loc = cv2.minMaxLoc(result) if metric == cv2.TM_SQDIFF or metric == cv2.TM_SQDIFF_NORMED: x, y = (min_loc[0], min_loc[1]) x = (min_loc[0] + w//2) / upsampling y = (min_loc[1] + h//2) / upsampling else: x, y = (max_loc[0], max_loc[1]) x = ((max_loc[0] + w//2)) / upsampling y = ((max_loc[1] + h//2)) / upsampling print('things', x, y, max_loc, h, w) return x, y, max_corr, result # -1 because the returned results array is W-w+1 and H-h+1 in shape, # where W, H are the width and height of the image and w,h are the # width and height of the template print(u_template.shape, u_image.shape, result.shape, x,y) print(u_image.shape, u_template.shape, max_loc) # the max_loc array is of shape W-w+1, H-h+1, where W, H are the width # and height of the image and w,h are the width and height of the template print(x / upsampling - 1, y / upsampling - 1) # Compute the idealized shift (image center) ideal_y = u_image.shape[0] / 2. ideal_x = u_image.shape[1] / 2. ideal_y = (u_image.shape[0] + 1) / 2. - 0.5 ideal_x = (u_image.shape[1] + 1) / 2. - 0.5 # Compute the shift from template upper left to template center y += (u_template.shape[0] / 2.) x += (u_template.shape[1] / 2.) print("x,ideal x, ", x, ideal_x, (x - ideal_x) / upsampling) print("y,ideal y, ", y, ideal_y, (y - ideal_y) / upsampling) # x = (x - ideal_x) / upsampling y = (y - ideal_y) / upsampling y = ((y - ideal_y) / upsampling) + 1 print(x, y) return x, y, max_corr, result
autocnet/matcher/subpixel.py +28 −16 Original line number Diff line number Diff line Loading @@ -208,12 +208,15 @@ def subpixel_phase(reference_roi, moving_roi, affine=tf.AffineTransform(), **kwa walking_template, **kwargs) # get shifts in input pixel space shift_x, shift_y = affine.inverse([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_x, -shift_y)) shift_x, shift_y = affine([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_y, -shift_x)) return new_affine, error, diffphase def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mode='reflect', def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mode='reflect', func=pattern_match, **kwargs): """ Loading Loading @@ -260,7 +263,7 @@ def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mo ref_clip = reference_roi.clip() moving_clip = moving_roi.clip(affine) print(affine) if moving_clip.var() == 0: warnings.warn('Input ROI has no variance.') return [None] * 3 Loading @@ -270,7 +273,7 @@ def subpixel_template(reference_roi, moving_roi, affine=tf.AffineTransform(), mo shift_x, shift_y, metrics, corrmap = func(moving_clip, ref_clip, **kwargs) if shift_x is None: return None, None, None print(shift_x, shift_y) # get shifts in input pixel space shift_x, shift_y = affine.inverse([shift_x, shift_y])[0] new_affine = tf.AffineTransform(translation=(-shift_x, -shift_y)) Loading Loading @@ -1715,8 +1718,8 @@ def subpixel_register_point_smart(pointid, destination_node.geodata, source.apriorisample, source.aprioriline, 60, 60) 30, 30) except Exception as e: print(e) m = {'id': measure.id, Loading @@ -1737,8 +1740,16 @@ def subpixel_register_point_smart(pointid, if match_kwarg['template_size'][1] < size_y: size_y = match_kwarg['template_size'][1] reference_roi = roi.Roi(source_node.geodata, source.apriorisample, source.aprioriline, size_x=size_x, size_y=size_y) moving_roi = roi.Roi(destination_node.geodata, measure.apriorisample, measure.aprioriline, size_x=size_x, size_y=size_y) reference_roi = roi.Roi(source_node.geodata, source.apriorisample, source.aprioriline, size_x=size_x, size_y=size_y) moving_roi = roi.Roi(destination_node.geodata, measure.apriorisample, measure.aprioriline, size_x=size_x, size_y=size_y) _, baseline_corr, _ = subpixel_template(reference_roi, moving_roi, Loading Loading @@ -1766,6 +1777,7 @@ def subpixel_register_point_smart(pointid, baseline_mi = mutual_information(base_roi, dst_roi)""" baseline_mi = 0 print(f'Baseline MI: {baseline_mi} | Baseline Corr: {baseline_corr}') print(affine) for parameter in parameters: match_kwargs = parameter['match_kwargs'] Loading @@ -1782,6 +1794,7 @@ def subpixel_register_point_smart(pointid, updated_affine, maxcorr, temp_corrmap = subpixel_template(reference_roi, moving_roi, affine=affine) print(updated_affine) """ if x is None or y is None: print('Unable to match with this parameter set.') Loading @@ -1803,10 +1816,9 @@ def subpixel_register_point_smart(pointid, else: metric = maxcorr new_x, new_y = updated_affine([measure.sample, measure.line])[0] dist = np.linalg.norm([measure.sample-new_x, measure.line-new_y]) dist = np.linalg.norm([measure.line-new_x, measure.sample-new_y]) cost = cost_func(dist, metric) print(new_x, new_y, dist) m = {'id': measure.id, 'sample':new_x, Loading
autocnet/transformation/roi.py +1 −3 Original line number Diff line number Diff line Loading @@ -130,14 +130,12 @@ class Roi(): if left_x < 0 or top_y < 0 or right_x > raster_size[0] or bottom_y > raster_size[1]: raise IndexError(f"Input window size {(self.size_x, self.size_y)}) at center {(self.x, self.y)} is out of the image bounds") print("extents:", list(map(int, [left_x, right_x, top_y, bottom_y]))) print("center:", self.x, self.y, self.size_x, self.size_y) return list(map(int, [left_x, right_x, top_y, bottom_y])) @property def center(self): ie = self.image_extent return (ie[1] - ie[0])/2.+0.5, (ie[3]-ie[2])/2.+0.5 return (ie[1] - ie[0])/2., (ie[3]-ie[2])/2. @property def is_valid(self): Loading
tests/test_subpixel_match.py +6 −6 Original line number Diff line number Diff line Loading @@ -36,12 +36,12 @@ def test_full_subpixel_registration(ncg, images, point): 'chooser':'smart_subpixel_registration'} parameters = [ {'match_kwargs': {'image_size':(121,121), 'template_size':(61,61)}}, {'match_kwargs': {'image_size':(151,151), 'template_size':(67,67)}}, {'match_kwargs': {'image_size':(181,181), 'template_size':(73,73)}}, {'match_kwargs': {'image_size':(221,221), 'template_size':(81,81)}}, {'match_kwargs': {'image_size':(251,251), 'template_size':(89,89)}}, {'match_kwargs': {'image_size':(281,281), 'template_size':(98,98)}} {'match_kwargs': {'image_size':(61,61), 'template_size':(31,31)}}, {'match_kwargs': {'image_size':(75,75), 'template_size':(33,33)}}, {'match_kwargs': {'image_size':(91,91), 'template_size':(37,37)}}, {'match_kwargs': {'image_size':(111,111), 'template_size':(41,41)}}, {'match_kwargs': {'image_size':(125,125), 'template_size':(45,45)}}, {'match_kwargs': {'image_size':(141,141), 'template_size':(49,49)}} ] measures_to_update, measures_to_set_false = smart_register_point(1, Loading