예제 #1
0
def get_synthetic_warped_circle(nslices):
    #get a subsampled circle
    fname_cicle = get_data('reg_o')
    circle = np.load(fname_cicle)[::4,::4].astype(floating)

    #create a synthetic invertible map and warp the circle
    d, dinv = vfu.create_harmonic_fields_2d(64, 64, 0.1, 4)
    d = np.asarray(d, dtype=floating)
    dinv = np.asarray(dinv, dtype=floating)
    mapping = DiffeomorphicMap(2, (64, 64))
    mapping.forward, mapping.backward = d, dinv
    wcircle = mapping.transform(circle)

    if(nslices == 1):
        return circle, wcircle

    #normalize and form the 3d by piling slices
    circle = (circle-circle.min())/(circle.max() - circle.min())
    circle_3d = np.ndarray(circle.shape + (nslices,), dtype=floating)
    circle_3d[...] = circle[...,None]
    circle_3d[...,0] = 0
    circle_3d[...,-1] = 0

    #do the same with the warped circle
    wcircle = (wcircle-wcircle.min())/(wcircle.max() - wcircle.min())
    wcircle_3d = np.ndarray(wcircle.shape + (nslices,), dtype=floating)
    wcircle_3d[...] = wcircle[...,None]
    wcircle_3d[...,0] = 0
    wcircle_3d[...,-1] = 0

    return circle_3d, wcircle_3d
예제 #2
0
def read_mapping(disp, domain_img, codomain_img, prealign=None):
    """
    Read a syn registration mapping from a nifti file

    Parameters
    ----------
    disp : str, Nifti1Image, or ndarray
        If string, file must of an image or ndarray.
        If image, contains the mapping displacement field in each voxel
        Shape (x, y, z, 3, 2)
        If ndarray, contains affine transformation used for mapping

    domain_img : str or Nifti1Image

    codomain_img : str or Nifti1Image

    Returns
    -------
    A :class:`DiffeomorphicMap` object
    """
    if isinstance(disp, str):
        if "nii.gz" in disp:
            disp = nib.load(disp)
        else:
            disp = np.load(disp)

    if isinstance(domain_img, str):
        domain_img = nib.load(domain_img)

    if isinstance(codomain_img, str):
        codomain_img = nib.load(codomain_img)

    if isinstance(disp, nib.Nifti1Image):
        mapping = DiffeomorphicMap(3, disp.shape[:3],
                                   disp_grid2world=np.linalg.inv(disp.affine),
                                   domain_shape=domain_img.shape[:3],
                                   domain_grid2world=domain_img.affine,
                                   codomain_shape=codomain_img.shape,
                                   codomain_grid2world=codomain_img.affine,
                                   prealign=prealign)

        disp_data = disp.get_fdata().astype(np.float32)
        mapping.forward = disp_data[..., 0]
        mapping.backward = disp_data[..., 1]
        mapping.is_inverse = True
    else:
        from AFQ.definitions.mapping import ConformedAffineMapping
        mapping = ConformedAffineMapping(
            disp,
            domain_grid_shape=reduce_shape(
                domain_img.shape),
            domain_grid2world=domain_img.affine,
            codomain_grid_shape=reduce_shape(
                codomain_img.shape),
            codomain_grid2world=codomain_img.affine)

    return mapping
예제 #3
0
def get_warped_stacked_image(image, nslices, b, m):
    r""" Creates a volume by stacking copies of a deformed image

    The image is deformed under an invertible field, and a 3D volume is
    generated as follows:
    the first and last `nslices`//3 slices are filled with zeros
    to simulate background. The remaining middle slices are filled with
    copies of the deformed `image` under the action of the invertible
    field.

    Parameters
    ----------
    image : 2d array shape(r, c)
        the image to be deformed
    nslices : int
        the number of slices in the final volume
    b, m : float
        parameters of the harmonic field (as in [1]).

    Returns
    -------
    vol : array shape(r, c) if `nslices`==1 else (r, c, `nslices`)
        the volumed generated using the undeformed image
    wvol : array shape(r, c) if `nslices`==1 else (r, c, `nslices`)
        the volumed generated using the warped image

    References
    ----------
    [1] Chen, M., Lu, W., Chen, Q., Ruchala, K. J., & Olivera, G. H. (2008).
        A simple fixed-point approach to invert a deformation field.
        Medical Physics, 35(1), 81. doi:10.1118/1.2816107
    """
    shape = image.shape
    # create a synthetic invertible map and warp the circle
    d, dinv = vfu.create_harmonic_fields_2d(shape[0], shape[1], b, m)
    d = np.asarray(d, dtype=floating)
    dinv = np.asarray(dinv, dtype=floating)
    mapping = DiffeomorphicMap(2, shape)
    mapping.forward, mapping.backward = d, dinv
    wimage = mapping.transform(image)

    if (nslices == 1):
        return image, wimage

    # normalize and form the 3d by piling slices
    image = image.astype(floating)
    image = (image - image.min()) / (image.max() - image.min())
    zero_slices = nslices // 3
    vol = np.zeros(shape=image.shape + (nslices, ))
    vol[..., zero_slices:(2 * zero_slices)] = image[..., None]
    wvol = np.zeros(shape=image.shape + (nslices, ))
    wvol[..., zero_slices:(2 * zero_slices)] = wimage[..., None]

    return vol, wvol
예제 #4
0
파일: test_imwarp.py 프로젝트: MPDean/dipy
def get_warped_stacked_image(image, nslices, b, m):
    r""" Creates a volume by stacking copies of a deformed image

    The image is deformed under an invertible field, and a 3D volume is
    generated as follows:
    the first and last `nslices`//3 slices are filled with zeros
    to simulate background. The remaining middle slices are filled with
    copies of the deformed `image` under the action of the invertible
    field.

    Parameters
    ----------
    image : 2d array shape(r, c)
        the image to be deformed
    nslices : int
        the number of slices in the final volume
    b, m : float
        parameters of the harmonic field (as in [1]).

    Returns
    -------
    vol : array shape(r, c) if `nslices`==1 else (r, c, `nslices`)
        the volumed generated using the undeformed image
    wvol : array shape(r, c) if `nslices`==1 else (r, c, `nslices`)
        the volumed generated using the warped image

    References
    ----------
    [1] Chen, M., Lu, W., Chen, Q., Ruchala, K. J., & Olivera, G. H. (2008).
        A simple fixed-point approach to invert a deformation field.
        Medical Physics, 35(1), 81. doi:10.1118/1.2816107
    """
    shape = image.shape
    # create a synthetic invertible map and warp the circle
    d, dinv = vfu.create_harmonic_fields_2d(shape[0], shape[1], b, m)
    d = np.asarray(d, dtype=floating)
    dinv = np.asarray(dinv, dtype=floating)
    mapping = DiffeomorphicMap(2, shape)
    mapping.forward, mapping.backward = d, dinv
    wimage = mapping.transform(image)

    if(nslices == 1):
        return image, wimage

    # normalize and form the 3d by piling slices
    image = image.astype(floating)
    image = (image - image.min()) / (image.max() - image.min())
    zero_slices = nslices // 3
    vol = np.zeros(shape=image.shape + (nslices,))
    vol[..., zero_slices:(2 * zero_slices)] = image[..., None]
    wvol = np.zeros(shape=image.shape + (nslices,))
    wvol[..., zero_slices:(2 * zero_slices)] = wimage[..., None]

    return vol, wvol
예제 #5
0
def read_mapping(disp, domain_img, codomain_img, prealign=None):
    """
    Read a syn registration mapping from a nifti file

    Parameters
    ----------
    disp : str or Nifti1Image
        A file of image containing the mapping displacement field in each voxel
        Shape (x, y, z, 3, 2)

    domain_img : str or Nifti1Image

    codomain_img : str or Nifti1Image

    Returns
    -------
    A :class:`DiffeomorphicMap` object.

    Notes
    -----
    See :func:`write_mapping` for the data format expected.
    """
    if isinstance(disp, str):
        disp_data, disp_affine = load_nifti(disp)

    if isinstance(domain_img, str):
        domain_img = nib.load(domain_img)

    if isinstance(codomain_img, str):
        codomain_img = nib.load(codomain_img)

    mapping = DiffeomorphicMap(3,
                               disp_data.shape[:3],
                               disp_grid2world=np.linalg.inv(disp_affine),
                               domain_shape=domain_img.shape[:3],
                               domain_grid2world=domain_img.affine,
                               codomain_shape=codomain_img.shape,
                               codomain_grid2world=codomain_img.affine,
                               prealign=prealign)

    mapping.forward = disp_data[..., 0]
    mapping.backward = disp_data[..., 1]
    mapping.is_inverse = True

    return mapping
예제 #6
0
def read_mapping(disp, domain_img, codomain_img, prealign=None):
    """
    Read a syn registration mapping from a nifti file

    Parameters
    ----------
    disp : str or Nifti1Image
        A file of image containing the mapping displacement field in each voxel
        Shape (x, y, z, 3, 2)

    domain_img : str or Nifti1Image

    codomain_img : str or Nifti1Image

    Returns
    -------
    A :class:`DiffeomorphicMap` object
    """
    if isinstance(disp, str):
        disp = nib.load(disp)

    if isinstance(domain_img, str):
        domain_img = nib.load(domain_img)

    if isinstance(codomain_img, str):
        codomain_img = nib.load(codomain_img)

    mapping = DiffeomorphicMap(3,
                               disp.shape[:3],
                               disp_grid2world=np.linalg.inv(disp.affine),
                               domain_shape=domain_img.shape[:3],
                               domain_grid2world=domain_img.affine,
                               codomain_shape=codomain_img.shape,
                               codomain_grid2world=codomain_img.affine,
                               prealign=prealign)

    disp_data = disp.get_fdata().astype(np.float32)
    mapping.forward = disp_data[..., 0]
    mapping.backward = disp_data[..., 1]
    mapping.is_inverse = True

    return mapping
예제 #7
0
def read_mapping(disp, domain_img, codomain_img):
    """
    Read a syn registration mapping from a nifti file

    Parameters
    ----------
    disp : str or Nifti1Image
        A file of image containing the mapping displacement field in each voxel
        Shape (x, y, z, 3, 2)

    domain_img : str or Nifti1Image

    codomain_img : str or Nifti1Image

    Returns
    -------
    A :class:`DiffeomorphicMap` object
    """
    if isinstance(disp, str):
        disp = nib.load(disp)

    if isinstance(domain_img, str):
        domain_img = nib.load(domain_img)

    if isinstance(codomain_img, str):
        codomain_img = nib.load(codomain_img)

    mapping = DiffeomorphicMap(3, disp.shape[:3],
                               disp_grid2world=np.linalg.inv(disp.affine),
                               domain_shape=domain_img.shape[:3],
                               domain_grid2world=domain_img.affine,
                               codomain_shape=codomain_img.shape,
                               codomain_grid2world=codomain_img.affine)

    disp_data = disp.get_data()
    mapping.forward = disp_data[..., 0]
    mapping.backward = disp_data[..., 1]
    mapping.is_inverse = True

    return mapping
예제 #8
0
def register_demons_sym_diffeom(img_sense,
                                img_ref,
                                smooth_sigma=1.,
                                params=DIPY_DEAMONS_PARAMS,
                                inverse=False,
                                verbose=False):
    """ Register the image and reconstruction from atlas
    on the end we smooth the final deformation by a gaussian filter

    :param ndarray img_sense:
    :param ndarray img_ref:
    :param float smooth_sigma:
    :param dict params:
    :param bool verbose: whether show debug time measurements
    :return tuple(ndarray,ndarray):

    >>> np.random.seed(0)
    >>> img_ref = np.zeros((10, 10), dtype=int)
    >>> img_ref[2:6, 1:7] = 1
    >>> img_ref[5:9, 4:10] = 1
    >>> img_ref
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
           [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    >>> from skimage.morphology import erosion, dilation
    >>> img_ref_fuz = np.zeros((10, 10), dtype=float)
    >>> img_ref_fuz[dilation(img_ref, np.ones((3, 3))) == 1] = 0.1
    >>> img_ref_fuz[img_ref == 1] = 0.5
    >>> img_ref_fuz[erosion(img_ref, np.ones((3, 3))) == 1] = 1.0
    >>> img_ref_fuz
    array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
           [ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0. ,  0. ],
           [ 0.1,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.1,  0. ,  0. ],
           [ 0.1,  0.5,  1. ,  1. ,  1. ,  1. ,  0.5,  0.1,  0. ,  0. ],
           [ 0.1,  0.5,  1. ,  1. ,  1. ,  1. ,  0.5,  0.1,  0.1,  0.1],
           [ 0.1,  0.5,  0.5,  0.5,  0.5,  1. ,  0.5,  0.5,  0.5,  0.5],
           [ 0.1,  0.1,  0.1,  0.1,  0.5,  1. ,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0. ,  0. ,  0.1,  0.5,  1. ,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0. ,  0. ,  0.1,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5],
           [ 0. ,  0. ,  0. ,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1]])
    >>> d_deform = register_demons_sym_diffeom(img_ref_fuz, img_ref,
    ...                         smooth_sigma=1.5, inverse=True, verbose=True)
    >>> img_warp = warp2d_transform_image(img_ref, d_deform, method='nearest',
    ...                                   inverse=True)
    >>> np.round(img_warp.astype(float), 1)
    array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.],
           [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
           [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.],
           [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.],
           [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.],
           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
    >>> img_sense = np.zeros(img_ref.shape, dtype=int)
    >>> img_sense[4:9, 3:10] = 1
    >>> img_sense
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
    >>> d_deform = register_demons_sym_diffeom(img_sense, img_ref, smooth_sigma=0.)
    >>> img_warp = warp2d_transform_image(img_sense, d_deform)
    >>> np.round(img_warp.astype(float), 1)  # doctest: +SKIP
    array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
           [ 0. ,  0.3,  0.5,  0.3,  0.1,  0. ,  0. ,  0. ,  0. ,  0. ],
           [ 0. ,  1. ,  1. ,  1. ,  1. ,  0.8,  0.4,  0.1,  0. ,  0. ],
           [ 0. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  0.5,  0. ],
           [ 0. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0.2,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0. ,  0.6,  0.9,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0. ,  0.2,  0.4,  0.5,  0.8,  1. ,  1. ,  1. ,  1. ],
           [ 0. ,  0. ,  0. ,  0.2,  0.2,  0.3,  0.4,  0.6,  0.7,  1. ],
           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])
    >>> np.round(img_warp - img_sense, 1)  # doctest: +SKIP
    """
    if img_ref.max() == 0 or img_sense.max() == 0:
        logging.debug(
            'skip image registration (demons): max values for '
            'RECONST=%d and SENSE=%d', img_ref.max(), img_sense.max())
        return {'mapping': None, 'mapping-inv': None, 'package': 'dipy'}

    sdr_params = {k: params[k] for k in params if k in LIST_SDR_PARAMS}
    sdr = SmoothSymmetricDiffeomorphicRegistration(metric=SSDMetric(
        img_ref.ndim),
                                                   smooth_sigma=smooth_sigma,
                                                   **sdr_params)
    sdr.verbosity = VerbosityLevels.NONE

    t = time.time()
    mapping = sdr.optimize(img_ref.astype(float), img_sense.astype(float))
    if verbose:
        logging.debug('demons took: %d s', time.time() - t)

    mapping.forward = smooth_deform_field(mapping.forward, sigma=smooth_sigma)
    mapping.backward = smooth_deform_field(mapping.backward,
                                           sigma=smooth_sigma)

    # img_warped = mapping.transform(img_moving, 'linear')

    # mapping_inv = sdr.moving_to_ref
    if inverse:
        mapping_inv = DiffeomorphicMap(img_ref.ndim, img_ref.shape, None,
                                       img_ref.shape, None, img_ref.shape,
                                       None, None)
        mapping_inv.forward = smooth_deform_field(sdr.moving_to_ref.forward,
                                                  sigma=smooth_sigma)
        mapping_inv.backward = smooth_deform_field(sdr.moving_to_ref.backward,
                                                   sigma=smooth_sigma)
    else:
        mapping_inv = None

    if verbose:
        logging.debug('smoothing and warping took: %d s', time.time() - t)

    dict_deform = {
        'mapping': mapping,
        'mapping-inv': mapping_inv,
        'package': 'dipy'
    }

    return dict_deform