Loading autocnet/matcher/mutual_information.py +38 −31 Original line number Diff line number Diff line from math import floor from autocnet.transformation.roi import Roi import numpy as np from scipy.ndimage.measurements import center_of_mass Loading Loading @@ -33,20 +33,14 @@ def mutual_information(reference_roi, walking_roi, affine=AffineTransform(), **k numpy.histogram2d : for the kwargs that can be passed to the comparison """ reference_image = reference_roi.clip() walking_template = walking_roi.clip(affine) # walking_template = tf.warp(walking_template, affine, order=3) reference_image = reference_roi.array walking_template = walking_roi.array if reference_roi.ndv == None or walking_roi.ndv == None: print('Unable to process due to NaN values in the input data') return raise Exception('Unable to process due to NaN values in the input data') # print(reference_roi.size_y, walking_roi.size_y) if reference_roi.size_y != walking_roi.size_y and reference_roi.size_x != walking_roi.size_x: print('Unable compute MI. Image sizes are not identical.') return raise Exception('Unable compute MI. Image sizes are not identical.') hgram, x_edges, y_edges = np.histogram2d(reference_image.ravel(), walking_template.ravel(), **kwargs) Loading Loading @@ -101,6 +95,12 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, if func == None: func = mutual_information if isinstance(s_image, Roi): image_size = s_image.array.shape#(s_image.size_x, s_image.size_y) template_size = d_template.array.shape# (d_template.size_x, d_template.size_y) else: image_size = s_image.shape template_size = d_template.shape Loading @@ -108,25 +108,35 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, x_diff = image_size[1] - template_size[1] max_corr = -np.inf corr_map = np.zeros((y_diff+1, x_diff+1)) corr_map = np.zeros(template_size) max_i = -1 # y max_j = -1 # x for i in range(y_diff+1): for j in range(x_diff+1): sub_image = s_image[i:i+template_size[1], # y j:j+template_size[0]] # x corr = func(sub_image, d_template, **kwargs) s_image_extent = s_image.image_extent for i in range(s_image_extent[2],s_image_extent[3]): for j in range(s_image_extent[0],s_image_extent[1]): s_image.x = (j)#*(1+template_size[0]))/2 s_image.y = (i)#*(1+template_size[1]))/2 # sub_image = s_image[i:i+template_size[1], # y # j:j+template_size[0]] # x corr = func(s_image, d_template, **kwargs) if corr > max_corr: max_corr = corr max_i = i max_j = j corr_map[i, j] = corr max_i = i - s_image_extent[2] max_j = j - s_image_extent[0] corr_map[i- s_image_extent[2], j - s_image_extent[0]] = corr y, x = np.unravel_index(np.argmax(corr_map, axis=None), corr_map.shape) upper = int(2 + floor(subpixel_size / 2)) lower = upper - 1 # x, y are the location of the upper left hand corner of the template in the image area = corr_map[y-lower:y+upper, x-lower:x+upper] Loading @@ -134,17 +144,14 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, cmass = center_of_mass(area) if area.shape != (subpixel_size+2, subpixel_size+2): print("Max correlation is too close to the boundary.") return None, None, 0, None subpixel_y_shift = subpixel_size - 1 - cmass[0] subpixel_x_shift = subpixel_size - 1 - cmass[1] y = abs(y - (corr_map.shape[1])/2) x = abs(x - (corr_map.shape[0])/2) y += subpixel_y_shift x += subpixel_x_shift # Compute the idealized shift (image center) y -= (s_image.shape[0] / 2) - (d_template.shape[0] / 2) x -= (s_image.shape[1] / 2) - (d_template.shape[1] / 2) return float(x), float(y), float(max_corr), corr_map new_affine = AffineTransform(translation=(-x, -y)) return new_affine, float(max_corr), corr_map # return float(x), float(y), float(max_corr), corr_map No newline at end of file autocnet/matcher/tests/test_mutual_information.py +8 −6 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ def test_good_mi(): assert corrilation == pytest.approx(2.30258509299404) def test_bad_mi(): test_image1 = np.array([[i for i in range(50)] for j in range(50)]) test_image2 = np.ones((50, 50)) test_image1 = Roi(np.array([[i for i in range(50)] for j in range(50)]), 25, 25, 25, 25, ndv=22222222) test_image2 = Roi(np.ones((50, 50)),25, 25, 25, 25, ndv=22222222) corrilation = mutual_information.mutual_information(test_image1, test_image2) assert corrilation == pytest.approx(0) Loading @@ -26,9 +26,11 @@ def test_mutual_information(): s_image[25:75, 25:75] = d_template x_offset, y_offset, max_corr, corr_map = mutual_information.mutual_information_match(d_template, s_image, bins=20) assert x_offset == 0.01711861257171421 assert y_offset == 0.0 d_template = Roi(d_template, 25, 25, 25, 25, ndv=22222222) s_image = Roi(s_image, 50, 50, 25, 25, ndv=22222222) affine, max_corr, corr_map = mutual_information.mutual_information_match(d_template, s_image, bins=20) assert max_corr == 2.9755967600033015 assert corr_map.shape == (51, 51) assert corr_map.shape == (50, 50) assert np.min(corr_map) >= 0.0 #TODO add assert for affine autocnet/transformation/roi.py +1 −1 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ class Roi(): """ pixels = self.image_extent if isinstance(self.data, np.ndarray): data = self.data[pixels[2]:pixels[3]+1,pixels[0]:pixels[1]+1] data = self.data[pixels[2]:pixels[3],pixels[0]:pixels[1]] else: # Have to reformat to [xstart, ystart, xnumberpixels, ynumberpixels] # TODO: I think this will result in an incorrect obj.center when the passed data is a GeoDataset Loading Loading
autocnet/matcher/mutual_information.py +38 −31 Original line number Diff line number Diff line from math import floor from autocnet.transformation.roi import Roi import numpy as np from scipy.ndimage.measurements import center_of_mass Loading Loading @@ -33,20 +33,14 @@ def mutual_information(reference_roi, walking_roi, affine=AffineTransform(), **k numpy.histogram2d : for the kwargs that can be passed to the comparison """ reference_image = reference_roi.clip() walking_template = walking_roi.clip(affine) # walking_template = tf.warp(walking_template, affine, order=3) reference_image = reference_roi.array walking_template = walking_roi.array if reference_roi.ndv == None or walking_roi.ndv == None: print('Unable to process due to NaN values in the input data') return raise Exception('Unable to process due to NaN values in the input data') # print(reference_roi.size_y, walking_roi.size_y) if reference_roi.size_y != walking_roi.size_y and reference_roi.size_x != walking_roi.size_x: print('Unable compute MI. Image sizes are not identical.') return raise Exception('Unable compute MI. Image sizes are not identical.') hgram, x_edges, y_edges = np.histogram2d(reference_image.ravel(), walking_template.ravel(), **kwargs) Loading Loading @@ -101,6 +95,12 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, if func == None: func = mutual_information if isinstance(s_image, Roi): image_size = s_image.array.shape#(s_image.size_x, s_image.size_y) template_size = d_template.array.shape# (d_template.size_x, d_template.size_y) else: image_size = s_image.shape template_size = d_template.shape Loading @@ -108,25 +108,35 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, x_diff = image_size[1] - template_size[1] max_corr = -np.inf corr_map = np.zeros((y_diff+1, x_diff+1)) corr_map = np.zeros(template_size) max_i = -1 # y max_j = -1 # x for i in range(y_diff+1): for j in range(x_diff+1): sub_image = s_image[i:i+template_size[1], # y j:j+template_size[0]] # x corr = func(sub_image, d_template, **kwargs) s_image_extent = s_image.image_extent for i in range(s_image_extent[2],s_image_extent[3]): for j in range(s_image_extent[0],s_image_extent[1]): s_image.x = (j)#*(1+template_size[0]))/2 s_image.y = (i)#*(1+template_size[1]))/2 # sub_image = s_image[i:i+template_size[1], # y # j:j+template_size[0]] # x corr = func(s_image, d_template, **kwargs) if corr > max_corr: max_corr = corr max_i = i max_j = j corr_map[i, j] = corr max_i = i - s_image_extent[2] max_j = j - s_image_extent[0] corr_map[i- s_image_extent[2], j - s_image_extent[0]] = corr y, x = np.unravel_index(np.argmax(corr_map, axis=None), corr_map.shape) upper = int(2 + floor(subpixel_size / 2)) lower = upper - 1 # x, y are the location of the upper left hand corner of the template in the image area = corr_map[y-lower:y+upper, x-lower:x+upper] Loading @@ -134,17 +144,14 @@ def mutual_information_match(d_template, s_image, subpixel_size=3, cmass = center_of_mass(area) if area.shape != (subpixel_size+2, subpixel_size+2): print("Max correlation is too close to the boundary.") return None, None, 0, None subpixel_y_shift = subpixel_size - 1 - cmass[0] subpixel_x_shift = subpixel_size - 1 - cmass[1] y = abs(y - (corr_map.shape[1])/2) x = abs(x - (corr_map.shape[0])/2) y += subpixel_y_shift x += subpixel_x_shift # Compute the idealized shift (image center) y -= (s_image.shape[0] / 2) - (d_template.shape[0] / 2) x -= (s_image.shape[1] / 2) - (d_template.shape[1] / 2) return float(x), float(y), float(max_corr), corr_map new_affine = AffineTransform(translation=(-x, -y)) return new_affine, float(max_corr), corr_map # return float(x), float(y), float(max_corr), corr_map No newline at end of file
autocnet/matcher/tests/test_mutual_information.py +8 −6 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ def test_good_mi(): assert corrilation == pytest.approx(2.30258509299404) def test_bad_mi(): test_image1 = np.array([[i for i in range(50)] for j in range(50)]) test_image2 = np.ones((50, 50)) test_image1 = Roi(np.array([[i for i in range(50)] for j in range(50)]), 25, 25, 25, 25, ndv=22222222) test_image2 = Roi(np.ones((50, 50)),25, 25, 25, 25, ndv=22222222) corrilation = mutual_information.mutual_information(test_image1, test_image2) assert corrilation == pytest.approx(0) Loading @@ -26,9 +26,11 @@ def test_mutual_information(): s_image[25:75, 25:75] = d_template x_offset, y_offset, max_corr, corr_map = mutual_information.mutual_information_match(d_template, s_image, bins=20) assert x_offset == 0.01711861257171421 assert y_offset == 0.0 d_template = Roi(d_template, 25, 25, 25, 25, ndv=22222222) s_image = Roi(s_image, 50, 50, 25, 25, ndv=22222222) affine, max_corr, corr_map = mutual_information.mutual_information_match(d_template, s_image, bins=20) assert max_corr == 2.9755967600033015 assert corr_map.shape == (51, 51) assert corr_map.shape == (50, 50) assert np.min(corr_map) >= 0.0 #TODO add assert for affine
autocnet/transformation/roi.py +1 −1 Original line number Diff line number Diff line Loading @@ -162,7 +162,7 @@ class Roi(): """ pixels = self.image_extent if isinstance(self.data, np.ndarray): data = self.data[pixels[2]:pixels[3]+1,pixels[0]:pixels[1]+1] data = self.data[pixels[2]:pixels[3],pixels[0]:pixels[1]] else: # Have to reformat to [xstart, ystart, xnumberpixels, ynumberpixels] # TODO: I think this will result in an incorrect obj.center when the passed data is a GeoDataset Loading