def registration(diff, affine_diff, anat, affine_anat): #Affine trasformation beetween diffuson and anatomical data static = np.squeeze(diff)[..., 0] static_grid2world = affine_diff moving = anat moving_grid2world = affine_anat identity = np.eye(4) affine_map = AffineMap(identity, static.shape, static_grid2world, moving.shape, moving_grid2world) resampled = affine_map.transform(moving) regtools.overlay_slices(static, resampled, None, 0, "Static", "Moving", "resampled_0.png") regtools.overlay_slices(static, resampled, None, 1, "Static", "Moving", "resampled_1.png") regtools.overlay_slices(static, resampled, None, 2, "Static", "Moving", "resampled_2.png") c_of_mass = transform_centers_of_mass(static, static_grid2world, moving, moving_grid2world) transformed = c_of_mass.transform(moving) regtools.overlay_slices(static, transformed, None, 0, "Static", "Transformed", "transformed_com_0.png") regtools.overlay_slices(static, transformed, None, 1, "Static", "Transformed", "transformed_com_1.png") regtools.overlay_slices(static, transformed, None, 2, "Static", "Transformed", "transformed_com_2.png") nbins = 32 sampling_prop = None metric = MutualInformationMetric(nbins, sampling_prop) level_iters = [10000, 1000, 100] factors = [4, 2, 1] sigmas = [3.0, 1.0, 0.0] affreg = AffineRegistration(metric=metric, level_iters=level_iters, sigmas=sigmas, factors=factors) transform = TranslationTransform3D() params0 = None starting_affine = c_of_mass.affine translation = affreg.optimize(static, moving, transform, params0, static_grid2world, moving_grid2world, starting_affine=starting_affine) transformed = translation.transform(moving) regtools.overlay_slices(static, transformed, None, 0, "Static", "Transformed", "transformed_trans_0.png") regtools.overlay_slices(static, transformed, None, 1, "Static", "Transformed", "transformed_trans_1.png") regtools.overlay_slices(static, transformed, None, 2, "Static", "Transformed", "transformed_trans_2.png") transform = RigidTransform3D() params0 = None starting_affine = translation.affine rigid = affreg.optimize(static, moving, transform, params0, static_grid2world, moving_grid2world, starting_affine=starting_affine) transformed = rigid.transform(moving) regtools.overlay_slices(static, transformed, None, 0, "Static", "Transformed", "transformed_rigid_0.png") regtools.overlay_slices(static, transformed, None, 1, "Static", "Transformed", "transformed_rigid_1.png") regtools.overlay_slices(static, transformed, None, 2, "Static", "Transformed", "transformed_rigid_2.png") transform = AffineTransform3D() params0 = None starting_affine = rigid.affine affine = affreg.optimize(static, moving, transform, params0, static_grid2world, moving_grid2world, starting_affine=starting_affine) transformed = affine.transform(moving) regtools.overlay_slices(static, transformed, None, 0, "Static", "Transformed", "transformed_affine_0.png") regtools.overlay_slices(static, transformed, None, 1, "Static", "Transformed", "transformed_affine_1.png") regtools.overlay_slices(static, transformed, None, 2, "Static", "Transformed", "transformed_affine_2.png") inverse_map = AffineMap(starting_affine, static.shape, static_grid2world, moving.shape, moving_grid2world) resampled_inverse = inverse_map.transform_inverse(transformed, resample_only=True) nib.save(nib.Nifti1Image(resampled_inverse, affine_diff), 'brain.coreg.nii.gz') return transformed
def register(src, target=None, ROI=None, target_shape=Shape.mMR, src_resolution=Res.MR, target_resolution=Res.mMR, method="CoM", src_offset=None, dtype=np.float32): """ Transforms `src` into `target` space. @param src : ndarray. Volume to transform. @param target : ndarray, optional. If (default: None), perform a basic transform using the other params. If ndarray, use as reference static image for registration. @param ROI : tuple, optional. Ignored if `target` is unspecified. Region within `target` to use for registration. [default: ((0, None),)] for whole volume. Use e.g.: ((0, None), (100, -120), (110, -110)) to mean [0:, 100:-120, 110:-110]. @param target_shape : tuple, optional. Ignored if `target` is specified. @param src_offset : tuple, optional. Static initial translation [default: (0, 0, 0)]. Useful when no `target` is specified. @param method : str, optional. [default: "CoM"] : centre of mass. """ from dipy.align.imaffine import AffineMap, transform_centers_of_mass assert src.ndim == 3 if target is not None: assert target.ndim == 3 assert len(target_shape) == 3 assert len(src_resolution) == 3 assert len(target_resolution) == 3 if ROI is None: ROI = ((0, None), ) ROI = tuple(slice(i, j) for i, j in ROI) if src_offset is None: src_offset = (0, 0, 0) method = method.lower() moving = src # scale affine_init = np.diag((src_resolution / target_resolution).tolist() + [1]) # centre offset affine_init[:3, -1] = target.shape if target is not None else target_shape affine_init[:3, -1] -= moving.shape * src_resolution / target_resolution affine_init[:3, -1] /= 2 affine_init[:3, -1] += src_offset affine_map = AffineMap( np.eye(4), target_shape, np.eye(4), # unmoved target moving.shape, affine_init) src = affine_map.transform(moving) if target is not None: static = target if np.isnan(static).sum(): log.warn("NaNs in target reference - skipping") else: # remove noise outside ROI msk = np.zeros_like(static) msk[ROI] = 1 msk = affine_map.transform_inverse(msk) moving = np.array(moving) moving[msk == 0] = 0 if method == "com": method = transform_centers_of_mass(static, np.eye(4), moving, affine_init) else: raise KeyError("Unknown method:" + method) src = method.transform(moving) if dtype is not None: src = src.astype(dtype) return src