def test_tensor_analysis(self): tensor = np.array([[1, 0], [0, 1]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor) self.assertArrayAlmostEqual(np.array([0]), tot_coher) self.assertArrayAlmostEqual(np.array([0]), tot_angle) self.assertArrayAlmostEqual(np.array([2]), tot_energy) tensor = np.array([[1, 0], [0, -1]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor) self.assertArrayAlmostEqual(np.array([0]), tot_coher) self.assertArrayAlmostEqual(np.array([90]), tot_angle) self.assertArrayAlmostEqual(np.array([2]), tot_energy) tensor = np.array([[1, 0], [0, 0]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor) self.assertArrayAlmostEqual(np.array([1]), tot_coher) self.assertArrayAlmostEqual(np.array([90]), tot_angle) self.assertArrayAlmostEqual(np.array([1]), tot_energy) tensor = np.array([[0, 0], [0, 1]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor) self.assertArrayAlmostEqual(np.array([1]), tot_coher) self.assertArrayAlmostEqual(np.array([0]), tot_angle) self.assertArrayAlmostEqual(np.array([1]), tot_energy) tensor = np.array([[0, 1], [1, 0]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor) self.assertArrayAlmostEqual(np.array([0]), tot_coher) self.assertArrayAlmostEqual(np.array([45]), tot_angle) self.assertArrayAlmostEqual(np.array([0]), tot_energy)
def create_angle_reference(size, min_n=50, max_n=120): # Make circular test image size = np.max(np.asarray([min_n, size], dtype=int)) size = np.min(np.asarray([size, max_n], dtype=int)) if np.mod(size, 2) != 0: size += 1 image_grid = np.mgrid[:size, :size] for i in range(2): image_grid[i] -= size * np.array(2 * image_grid[i] / size, dtype=int) image_grid[i] = np.fft.fftshift(image_grid[i]) image_radius = np.sqrt(np.sum(image_grid**2, axis=0)) image_sine = np.sin(4 * np.pi * image_radius / size) image_cos = np.cos(4 * np.pi * image_radius / size) image_rings = image_sine * image_cos j_tensor = form_structure_tensor(image_rings, sigma=1.0) pix_j_coher, pix_j_angle, pix_j_energy = tensor_analysis(j_tensor) pix_j_angle = rotate(pix_j_angle, 90)[:size // 2] pix_j_coher = pix_j_coher[:size // 2] pix_j_energy = np.where(image_radius < (size / 2), pix_j_energy, 0)[:size // 2] return pix_j_angle, pix_j_coher, pix_j_energy
def create_tensor_image(image, min_N=50): # Form structure tensors for each pixel j_tensor = form_structure_tensor(image, sigma=1.0) # Perform coherence and angle analysis on each pixel pix_j_coher, pix_j_angle, pix_j_energy = tensor_analysis(j_tensor) hue = (pix_j_angle + 90) / 180 saturation = pix_j_coher / pix_j_coher.max() brightness = image / image.max() size = 0.2 * np.sqrt(image.size) if size >= min_N: ref_angle, ref_coher, ref_energy = create_angle_reference(size) size = ref_angle.shape[1] start = -size // 2 end = image.shape[0] hue[start:end, :size] = (ref_angle + 90) / 180 saturation[start:end, :size] = ref_coher / ref_coher.max() brightness[start:end, :size] = ref_energy / ref_energy.max() # Form structure tensor image rgb_image = create_hsb_image(image, hue, saturation, brightness) return rgb_image
def test_1d_tensor(self): tensor_1d = np.array([[[0, 1], [1, 0]], [[0, 0], [0, 1]]]) tot_coher, tot_angle, tot_energy = tensor_analysis(tensor_1d) self.assertArrayAlmostEqual(np.array([0, 1]), tot_coher) self.assertArrayAlmostEqual(np.array([45, 0]), tot_angle) self.assertArrayAlmostEqual(np.array([0, 1]), tot_energy)
def structure_tensor_metrics(structure_tensor, tag=''): """Nematic tensor analysis for a scikit-image region""" database = pd.Series(dtype=object) (segment_coher_map, segment_angle_map, segment_angle_map) = tensor_analysis(structure_tensor) # Calculate mean structure tensor elements axis = tuple(range(structure_tensor.ndim - 2)) mean_tensor = np.mean(structure_tensor, axis=axis) segment_coher, _, _ = tensor_analysis(mean_tensor) database[f"{tag} Angle SDI"], _ = angle_analysis(segment_angle_map, segment_coher_map) database[f"{tag} Coherence"] = segment_coher[0] database[f"{tag} Local Coherence"] = np.mean(segment_coher_map) return database