Example #1
0
def field_conversion_method(field_image, image=None,
                            get_position_field=True):
    data = np.zeros_like(field_image.data, dtype=np.float32)

    # Matrix to go from voxel to world space
    if image is not None:
        voxel_2_xyz = image.voxel_2_mm
        vol_ext = image.vol_ext
        field = Image.from_data(data, image.get_header())
    else:
        voxel_2_xyz = field_image.voxel_2_mm
        vol_ext = field_image.vol_ext
        field = Image.from_data(data, field_image.get_header())

    voxels = np.mgrid[[slice(i) for i in vol_ext]]
    voxels = [d.reshape(vol_ext, order='F') for d in voxels]
    mms = [voxel_2_xyz[i][3] + sum(voxel_2_xyz[i][k] * voxels[k]
                                   for k in range(len(voxels)))
           for i in range(len(voxel_2_xyz) - (4 - len(vol_ext)))]

    input_data = np.squeeze(field_image.data)
    field_data = np.squeeze(data)
    mms = np.squeeze(mms)
    if get_position_field:
        for i in range(data.shape[-1]):
            # Output is the deformation/position field
            field_data[..., i] = input_data[..., i] + mms[i]
    else:
        for i in range(data.shape[-1]):
            # Output is the displacement field
            field_data[..., i] = input_data[..., i] - mms[i]

    return field
Example #2
0
def initialise_field(im, affine=None):
        """
        Create a field image from the specified target image.
        Sets the data to 0.

        Parameters:
        -----------
        :param im: The target image. Mandatory.
        :param affine: The initial affine transformation
        :return: Return the created field object
        """
        vol_ext = im.vol_ext
        dims = list()
        dims.extend(vol_ext)
        while len(dims) < 4:
            dims.extend([1])
        dims.extend([len(vol_ext)])

        # Inititalise with zero
        data = np.zeros(dims, dtype=np.float32)
        field = Image.from_data(data, im.get_header())

        # We have supplied an affine transformation
        if affine is not None:
            if affine.shape != (4, 4):
                raise RegError('Input affine transformation '
                               'should be a 4x4 matrix.')
            # The updated transformation
            transform = affine * im.voxel_2_mm
            field.update_transformation(transform)

        return field
Example #3
0
def initialise_jacobian_field(im, affine=None):
    """
    Create a jacobian field image from the specified target image/field.
    Sets the data to 0.

    Parameters:
    -----------
    :param im: The target image/field. Mandatory.
    :param affine: The initial affine transformation
    :return: Return the created jacobian field object. Each jacobian is stored in a vector of size 9 in row major order
    """
    vol_ext = np.array(im.vol_ext)
    dims = list()
    dims.extend(vol_ext)
    while len(dims) < 4:
        dims.extend([1])
    num_dims = len(vol_ext[vol_ext>1])
    dims.extend([num_dims**2])

    # Inititalise with zero
    data = np.zeros(dims, dtype=np.float32)
    jacfield = Image.from_data(data, im.get_header())
    jacfield.set_matrix_data_attributes(num_dims, num_dims)

    # We have supplied an affine transformation
    if affine is not None:
        if affine.shape != (4, 4):
            raise RegError('Input affine transformation '
                           'should be a 4x4 matrix.')
        # The updated transformation
        transform = affine * im.voxel_2_mm
        jacfield.update_transformation(transform)

    return jacfield
Example #4
0
    def exponentiate(self):
        """
        Compute the exponential of this velocity field using the
        scaling and squaring approach.

        The velocity field is in the tangent space of the manifold and the
        displacement field is the actual manifold and the transformation
        between the velocity field and the displacement field is given by
        the exponential chart.

        :param disp_image: Displacement field image that will be
        updated with the exponentiated velocity field.
        """

        self.__do_init_check()
        data = self.field.data
        result_data = np.zeros(self.field.data.shape)
        result = Image.from_data(result_data, self.field.get_header())

        # Important: Need to specify which axes to use
        norm = np.linalg.norm(data, axis=data.ndim-1)
        max_norm = np.max(norm[:])

        if max_norm < 0:
            raise ValueError('Maximum norm is invalid.')
        if max_norm == 0:
            return result

        pix_dims = np.asarray(self.field.zooms)
        # ignore NULL dimensions
        min_size = np.min(pix_dims[pix_dims > 0])
        num_steps = max(0,np.ceil(np.log2(max_norm / (min_size / 2))).astype('int'))

        # Approximate the initial exponential
        init = 1 << num_steps
        result.data = data / init

        dfc = DisplacementFieldComposer()
        # Do the squaring step to perform the integration
        # The exponential is num_steps times recursive composition of
        # the field with itself, which is equivalant to integration over
        # the unit interval.
        for _ in range(0, num_steps):
            result = dfc.compose(result, result)

        return result