def test_scale_space(): num_levels = 3 for test_class in [ScaleSpace, IsotropicScaleSpace]: for dim in [2, 3]: print(dim, test_class) if dim == 2: moving, static = get_synthetic_warped_circle(1) else: moving, static = get_synthetic_warped_circle(30) input_spacing = np.array([1.1, 1.2, 1.5])[:dim] grid2world = np.diag(tuple(input_spacing) + (1.0,)) original = moving if test_class is ScaleSpace: ss = test_class( original, num_levels, grid2world, input_spacing) elif test_class is IsotropicScaleSpace: factors = [4, 2, 1] sigmas = [3.0, 1.0, 0.0] ss = test_class( original, factors, sigmas, grid2world, input_spacing) for level in range(num_levels): # Verify sigmas and images are consistent sigmas = ss.get_sigmas(level) expected = sp.ndimage.filters.gaussian_filter(original, sigmas) expected = ((expected - expected.min()) / (expected.max() - expected.min())) actual = ss.get_image(level) assert_array_almost_equal(actual, expected) # Verify scalings and spacings are consistent spacings = ss.get_spacing(level) scalings = ss.get_scaling(level) expected = ss.get_spacing(0) * scalings actual = ss.get_spacing(level) assert_array_almost_equal(actual, expected) # Verify affine and affine_inv are consistent affine = ss.get_affine(level) affine_inv = ss.get_affine_inv(level) expected = np.eye(1 + dim) actual = affine.dot(affine_inv) assert_array_almost_equal(actual, expected) # Verify affine consistent with spacings exp_dir, expected_sp = get_direction_and_spacings(affine, dim) actual_sp = spacings assert_array_almost_equal(actual_sp, expected_sp)
def test_scale_space(): num_levels = 3 for test_class in [ScaleSpace, IsotropicScaleSpace]: for dim in [2, 3]: print(dim, test_class) if dim == 2: moving, static = get_synthetic_warped_circle(1) else: moving, static = get_synthetic_warped_circle(30) moving = cp.asarray(moving) static = cp.asarray(static) input_spacing = np.array([1.1, 1.2, 1.5])[:dim] grid2world = np.diag(tuple(input_spacing) + (1.0, )) original = moving if test_class is ScaleSpace: ss = test_class(original, num_levels, grid2world, input_spacing) elif test_class is IsotropicScaleSpace: factors = [4, 2, 1] sigmas = [3.0, 1.0, 0.0] ss = test_class(original, factors, sigmas, grid2world, input_spacing) for level in range(num_levels): # Verify sigmas and images are consistent sigmas = ss.get_sigmas(level) expected = ndi.gaussian_filter(original, sigmas) expected = (expected - expected.min()) / (expected.max() - expected.min()) actual = ss.get_image(level) cp.testing.assert_array_almost_equal(actual, expected) # Verify scalings and spacings are consistent spacings = ss.get_spacing(level) scalings = ss.get_scaling(level) expected = ss.get_spacing(0) * scalings actual = ss.get_spacing(level) cp.testing.assert_array_almost_equal(actual, expected) # Verify affine and affine_inv are consistent affine = ss.get_affine(level) affine_inv = ss.get_affine_inv(level) expected = np.eye(1 + dim) actual = affine.dot(affine_inv) cp.testing.assert_array_almost_equal(actual, expected) # Verify affine consistent with spacings exp_dir, expected_sp = get_direction_and_spacings(affine, dim) actual_sp = spacings cp.testing.assert_array_almost_equal(actual_sp, expected_sp)
def test_get_direction_and_spacings(): xrot = 0.5 yrot = 0.75 zrot = 1.0 direction_gt = eulerangles.euler2mat(zrot, yrot, xrot) spacings_gt = np.array([1.1, 1.2, 1.3]) scaling_gt = np.diag(spacings_gt) translation_gt = np.array([1,2,3]) affine = np.eye(4) affine[:3, :3] = direction_gt.dot(scaling_gt) affine[:3, 3] = translation_gt direction, spacings = imwarp.get_direction_and_spacings(affine, 3) assert_array_almost_equal(direction, direction_gt) assert_array_almost_equal(spacings, spacings_gt)
def changeFoV(image_nib, new_FOV, com=False): if isinstance(new_FOV, list): try: new_FOV = np.array(new_FOV) except: raise IOError("list of fields of view") image_shape = np.array(image_nib.shape) direction, spacing = get_direction_and_spacings(image_nib.affine, image_nib.ndim) old_fov = image_shape * spacing print("Input Image has:" "FOVs: {} " "Our New FOVs: {}".format(old_fov, new_FOV)) doit = False for f, fov in enumerate(old_fov): if (abs(fov - new_FOV[f]) >= 2 * spacing[f]): doit = True else: doit = False break if not doit: return image_nib.get_data(), image_nib.affine arr = image_nib.get_data() # Assume B_0 image is always the first vol if image_nib.ndim > 3: b0_image = arr[:, :, :, 0] else: b0_image = arr nVols = image_shape[-1] if com: new_image, new_affine = crop4D(image_nib, new_FOV, b0_image) else: new_image, new_affine = changeFOVimage(image_nib, new_FOV) return new_image, new_affine
static = ((static.astype(np.float64) - static.min()) / (static.max() - static.min())) moving = ((moving.astype(np.float64) - moving.min()) / (moving.max() - moving.min())) static = np.array(static).astype(np.float64) moving = np.array(moving).astype(np.float64) import numpy.linalg as npl moving_world2grid = npl.inv(moving_grid2world) from dipy.align.imwarp import get_direction_and_spacings dim = len(static.shape) moving_direction, moving_spacing = \ get_direction_and_spacings(moving_grid2world, dim) from dipy.align.vector_fields import _gradient_3d out_shape = static.shape ftype = moving.dtype.type out = np.empty(tuple(out_shape) + (dim, ), dtype=ftype) inside = np.empty(tuple(out_shape), dtype=np.int32) _gradient_3d(moving, moving_world2grid, moving_spacing, static_grid2world, out, inside) mgrad = np.asarray(out) from dipy.align.imaffine import AffineMap dim = len(static.shape) starting_affine = np.eye(dim + 1) affine_map = AffineMap(starting_affine, static.shape, static_grid2world,
def changeFOVimage(image, new_FOV): arr = image.get_data() affine = image.affine n = 3 if isinstance(new_FOV, list): try: new_FOV = np.array(new_FOV) except: raise IOError("list of fields of view") direction, spacing = get_direction_and_spacings(affine, arr.ndim) print(direction, spacing) arr_size = arr.size arr_shape = np.array(arr.shape) old_fov = np.abs(spacing.dot(direction) * arr_shape) origin = affine[:3, 3] print("Input Image has:" "FOVs: {} " "Our New FOVs: {}".format(old_fov, new_FOV)) doit = False for f, fov in enumerate(old_fov): if (abs(fov - new_FOV[f]) >= 2 * spacing[f]): doit = True else: doit = False break if not doit: print("Can't Change FOV - Return original image") return image, affine total_add_3D, total_remove_3D = np.zeros(n).astype(int), np.zeros( n).astype(int) new_origin_index = np.zeros(n).astype(int) new_size = np.zeros(n).astype(int) start_from = np.zeros(n).astype(int) start_from_new, from_old_size = np.zeros(n).astype(int), np.zeros( n).astype(int) for d, fov in enumerate(old_fov[:n]): print(d) if new_FOV[d] > fov: # print("Dimension {} process add".format(d)) total_add_3D[d] = (np.ceil((new_FOV[d] - fov) / spacing[d])) if ((total_add_3D[d] % 2) == 1): total_add_3D[d] += 1 new_origin_index[d] = -(total_add_3D[d] / 2) new_size[d] = (arr_shape[d] + total_add_3D[d]) start_from[d] = 0 start_from_new[d] = total_add_3D[d] / 2 from_old_size[d] = arr_shape[d] else: # print("Dimension {} process remove".format(d)) total_remove_3D[d] = (np.floor((fov - new_FOV[d]) / spacing[d])) if ((total_remove_3D[d] % 2) == 1): total_remove_3D[d] -= 1 new_origin_index[d] = (total_remove_3D[d] / 2) new_size[d] = (arr_shape[d] - total_remove_3D[d]) start_from[d] = total_remove_3D[d] / 2 start_from_new[d] = 0 from_old_size[d] = arr_shape[d] - total_remove_3D[d] # new_origin = origin + spacing * new_origin_index # new_origin = _transformIndextoPhysicalPoint(new_origin_index, spacing, direction, origin) new_origin = _transformIndextoPhysicalPoint_with_affine( affine, new_origin_index) new_affine = affine.copy() new_affine[0:3, 3] = new_origin if arr.ndim > 3: new_image = arr[start_from[0]:start_from[0] + from_old_size[0], start_from[1]:start_from[1] + from_old_size[1], start_from[2]:start_from[2] + from_old_size[2], :] else: new_image = arr[start_from[0]:start_from[0] + from_old_size[0], start_from[1]:start_from[1] + from_old_size[1], start_from[2]:start_from[2] + from_old_size[2]] return new_image, new_affine
def crop4D(image, new_FOV, b0_image): arr = image.get_data() affine = image.affine n = arr.ndim if isinstance(new_FOV, list): try: new_FOV = np.array(new_FOV) except: raise IOError("list of fields of view") direction, spacing = get_direction_and_spacings(affine, arr.ndim) # print(direction, spacing) arr_size = arr.size arr_shape = np.array(arr.shape) old_fov = np.abs(spacing.dot(direction) * arr_shape) origin = affine[:3, 3] print("Input Image has:" "FOVs: {} " "Our New FOVs: {}".format(old_fov, new_FOV)) doit = False for f, fov in enumerate(old_fov): if (abs(fov - new_FOV[f]) >= 2 * spacing[f]): doit = True if not doit: return image.get_data(), image.affine # get center of mass index and point center_index = _get_centerOfGravityPt(b0_image) center_pt = _transformIndextoPhysicalPoint(center_index, spacing, direction, origin) scl = direction[:3, :3] * np.diag(spacing) new_size = np.ceil(new_FOV / spacing) new_center_index = (new_size - 1) // 2 new_origin = np.zeros(3) # Find new_origin for r in range(3): sm = np.sum(scl[r, :] * new_center_index) new_origin[r] = center_pt[r] - sm spc4 = np.zeros(4) spc4[:-1] = spacing spc4[-1] = 1 dir4 = np.eye(4, 4) dir4[:3, :3] = direction[:3, :3] new_origin4 = np.zeros(4) new_origin4[:3] = new_origin destination_index = np.zeros(3).astype(int) source_start = np.zeros(3).astype(int) source_size = np.zeros(3).astype(int) for d in range(3): if (new_center_index[d] < center_index[d]): destination_index[d] = 0 source_start[d] = center_index[d] - new_center_index[d] if (source_start[d] + new_size[d] > arr.shape[d]): source_size[d] = arr.shape[d] - source_start[d] - 1 else: source_size[d] = new_size[d] else: destination_index[d] = new_center_index[d] - center_index[d] source_start[d] = 0 if (arr.shape[d] > new_size[d]): source_size[d] = new_size[d] else: source_size[d] = arr.shape[d] if arr.ndim > 3: new_image = arr[source_start[0]:source_start[0] + source_size[0], source_start[1]:source_start[1] + source_size[1], source_start[2]:source_start[2] + source_size[2], :] else: new_image = arr[source_start[0]:source_start[0] + source_size[0], source_start[1]:source_start[1] + source_size[1], source_start[2]:source_start[2] + source_size[2]] new_affine = affine new_affine[0:3, 3] = new_origin return new_image, new_affine