def test_01_03_diagonal_lines(self): img = np.ones((20, 30)) * .5 i, j = np.mgrid[0:20, 0:30] img[(i == j - 3) & (i <= 15)] = 1 img[(i == j + 3)] = 0 expected = np.zeros((20, 30), bool) expected[(i >= j - 3) & (i <= j + 3)] = True result = F.line_integration(img, -45, 1, 0) self.assertTrue(np.mean(result[expected]) > .5) self.assertTrue(np.mean(result[~expected]) < .25)
def test_01_02_two_lines(self): img = np.ones((20, 30)) * .5 img[8, 10:20] = 1 img[12, 10:20] = 0 result = F.line_integration(img, 0, 1, 0) expected = np.zeros((20, 30)) expected[9:12, 10:20] = 1 expected[8, 10:20] = .5 expected[12, 10:20] = .5 np.testing.assert_almost_equal(result, expected)
def test_01_05_smooth(self): img = np.ones((30, 20)) * .5 img[10, 10] = 1 img[20, 10] = 0 result = F.line_integration(img, 0, 1, .5) part = result[15, :] part = (part - np.min(part)) / (np.max(part) - np.min(part)) expected = np.exp(-(np.arange(20) - 10)**2 * 2) expected = (expected - np.min(expected)) / (np.max(expected) - np.min(expected)) np.testing.assert_almost_equal(part, expected)
def test_01_04_decay(self): img = np.ones((25, 23)) * .5 img[10, 10] = 1 img[20, 10] = 0 result = F.line_integration(img, 0, .9, 0) decay_part = result[11:20, 10] expected = .9**np.arange(1, 10) + .9**np.arange(9, 0, -1) expected = ((expected - np.min(expected)) / (np.max(expected) - np.min(expected))) decay_part = ((decay_part - np.min(decay_part)) / (np.max(decay_part) - np.min(decay_part))) np.testing.assert_almost_equal(decay_part, expected)
def test_01_01_nothing(self): img = np.zeros((23, 17)) result = F.line_integration(img, 0, .95, 2.0) np.testing.assert_almost_equal(result, 0)
def run(self, workspace): image = workspace.image_set.get_image(self.image_name.value, must_be_grayscale = True) # # Match against Matlab's strel('disk') operation. # radius = (float(self.object_size.value)-1.0) / 2.0 mask = image.mask if image.has_mask else None pixel_data = image.pixel_data if self.method == ENHANCE: if self.enhance_method == E_SPECKLES: if self.speckle_accuracy == S_SLOW: result = white_tophat(pixel_data, radius, mask) else: # # white_tophat = img - opening # = img - dilate(erode) # = img - median_filter(median_filter(0%) 100%) result = pixel_data - median_filter( median_filter(pixel_data, mask, radius, percent = 0), mask, radius, percent = 100) if mask is not None: result[~mask] = pixel_data[~mask] elif self.enhance_method == E_NEURITES: if self.neurite_choice == N_GRADIENT: # # white_tophat = img - opening # black_tophat = closing - img # desired effect = img + white_tophat - black_tophat # = img + img - opening - closing + img # = 3*img - opening - closing result = (3 * pixel_data - opening(pixel_data, radius, mask) - closing(pixel_data, radius, mask)) result[result > 1] = 1 result[result < 0] = 0 else: sigma = self.smoothing.value smoothed = gaussian_filter(pixel_data, sigma) L = hessian(smoothed, return_hessian = False, return_eigenvectors = False) # # The positive values are darker pixels with lighter # neighbors. The original ImageJ code scales the result # by sigma squared - I have a feeling this might be # a first-order correction for e**(-2*sigma), possibly # because the hessian is taken from one pixel away # and the gradient is less as sigma gets larger. # result = -L[:, :, 0] * (L[:, :, 0] < 0) * sigma * sigma if image.has_mask: result[~mask] = pixel_data[~mask] elif self.enhance_method == E_DARK_HOLES: min_radius = max(1,int(self.hole_size.min / 2)) max_radius = int((self.hole_size.max+1)/2) result = enhance_dark_holes(pixel_data, min_radius, max_radius, mask) elif self.enhance_method == E_CIRCLES: result = circular_hough(pixel_data, radius + .5, mask=mask) elif self.enhance_method == E_TEXTURE: result = variance_transform(pixel_data, self.smoothing.value, mask = mask) elif self.enhance_method == E_DIC: result = line_integration(pixel_data, self.angle.value, self.decay.value, self.smoothing.value) else: raise NotImplementedError("Unimplemented enhance method: %s"% self.enhance_method.value) elif self.method == SUPPRESS: if image.has_mask: result = opening(image.pixel_data, radius, image.mask) else: result = opening(image.pixel_data, radius) else: raise ValueError("Unknown filtering method: %s"%self.method) result_image = cpi.Image(result, parent_image=image) workspace.image_set.add(self.filtered_image_name.value, result_image) if self.show_window: workspace.display_data.image = image.pixel_data workspace.display_data.result = result
def run(self, workspace): image = workspace.image_set.get_image(self.image_name.value, must_be_grayscale=True) # # Match against Matlab's strel('disk') operation. # radius = (float(self.object_size.value) - 1.0) / 2.0 mask = image.mask if image.has_mask else None pixel_data = image.pixel_data if self.method == ENHANCE: if self.enhance_method == E_SPECKLES: if self.speckle_accuracy == S_SLOW: result = white_tophat(pixel_data, radius, mask) else: # # white_tophat = img - opening # = img - dilate(erode) # = img - median_filter(median_filter(0%) 100%) result = pixel_data - median_filter(median_filter( pixel_data, mask, radius, percent=0), mask, radius, percent=100) if mask is not None: result[~mask] = pixel_data[~mask] elif self.enhance_method == E_NEURITES: if self.neurite_choice == N_GRADIENT: # # white_tophat = img - opening # black_tophat = closing - img # desired effect = img + white_tophat - black_tophat # = img + img - opening - closing + img # = 3*img - opening - closing result = (3 * pixel_data - opening(pixel_data, radius, mask) - closing(pixel_data, radius, mask)) result[result > 1] = 1 result[result < 0] = 0 else: sigma = self.smoothing.value smoothed = gaussian_filter(pixel_data, sigma) L = hessian(smoothed, return_hessian=False, return_eigenvectors=False) # # The positive values are darker pixels with lighter # neighbors. The original ImageJ code scales the result # by sigma squared - I have a feeling this might be # a first-order correction for e**(-2*sigma), possibly # because the hessian is taken from one pixel away # and the gradient is less as sigma gets larger. # result = -L[:, :, 0] * (L[:, :, 0] < 0) * sigma * sigma if image.has_mask: result[~mask] = pixel_data[~mask] elif self.enhance_method == E_DARK_HOLES: min_radius = max(1, int(self.hole_size.min / 2)) max_radius = int((self.hole_size.max + 1) / 2) result = enhance_dark_holes(pixel_data, min_radius, max_radius, mask) elif self.enhance_method == E_CIRCLES: result = circular_hough(pixel_data, radius + .5, mask=mask) elif self.enhance_method == E_TEXTURE: result = variance_transform(pixel_data, self.smoothing.value, mask=mask) elif self.enhance_method == E_DIC: result = line_integration(pixel_data, self.angle.value, self.decay.value, self.smoothing.value) else: raise NotImplementedError("Unimplemented enhance method: %s" % self.enhance_method.value) elif self.method == SUPPRESS: if image.has_mask: result = opening(image.pixel_data, radius, image.mask) else: result = opening(image.pixel_data, radius) else: raise ValueError("Unknown filtering method: %s" % self.method) result_image = cpi.Image(result, parent_image=image) workspace.image_set.add(self.filtered_image_name.value, result_image) if self.show_window: workspace.display_data.image = image.pixel_data workspace.display_data.result = result