예제 #1
0
파일: xyz_image.py 프로젝트: cournape/nipy
   def xyz_ordered(self, positive=False):
      """ 
      Returns an image with the affine diagonal, (optionally
      with positive entries),
      in the XYZ coordinate system.

      Parameters
      ----------
      
      positive : bool, optional
         If True, also ensures that the diagonal entries are positive.

      Notes
      -----
      This may possibly transpose the data array.

      If positive is True, this may involve
      creating a new array with data
      
      self.get_data()[::-1,::-1]

      """
      A, b = to_matrix_vector(self.affine)
      if not np.all((np.abs(A) > 0.001).sum(axis=0) == 1):
         raise ValueError(
            'Cannot reorder the axis: the image affine contains rotations'
            )
      axis_numbers = list(np.argmax(np.abs(A), axis=1))
      im = self.reordered_axes(axis_numbers + range(3, self.ndim))

      if not positive:
         return im
      else:
         # Determine which axes, if any, have to be flipped in the array
         slice_list = []
         diag_values = np.diag(im.affine)
         for value in np.diag(im.affine)[:-1]:
            if value < 0:
               slice_list.append(slice(None,None,-1))
            else:
               slice_list.append(slice(None,None,None))

         if slice_list == [slice(None,None,None)]*3:
            # do nothing
            return im
         else:
            from nipy.core.image.image import subsample
            im = subsample(im.to_image(), tuple(slice_list))
            return XYZImage.from_image(im)
예제 #2
0
 def xyz_ordered(self):
     """ Returns an image with the affine diagonal and positive
         in its coordinate system.
     """
     A, b = to_matrix_vector(self.affine)
     if not np.all((np.abs(A) > 0.001).sum(axis=0) == 1):
         raise CoordSystemError(
             'Cannot reorder the axis: the image affine contains rotations'
             )
     axis_numbers = list(np.argmax(np.abs(A), axis=1))
     axis_names = [self.spatial_coordmap.function_domain.coord_names[a] for a in axis_numbers]
     reordered_coordmap = self.spatial_coordmap.reordered_domain(axis_names)
     data = self.get_data()
     transposed_data = np.transpose(data, axis_numbers + range(3, self.ndim))
     return AffineImage(transposed_data, reordered_coordmap.affine,
                        reordered_coordmap.function_domain.name)
예제 #3
0
    def __init__(self, affine, input_coords, output_coords):
        """
        Return an CoordinateMap specified by an affine transformation
        in homogeneous coordinates.
        
        Parameters
        ----------
        affine : array-like
           affine homogenous coordinate matrix
        input_coords : :class:`CoordinateSystem`
           input coordinates
        output_coords : :class:`CoordinateSystem`
           output coordinates

        Notes
        -----
        The dtype of the resulting matrix is determined by finding a
        safe typecast for the input_coords, output_coords and affine.
        """
        affine = np.asarray(affine)
        dtype = safe_dtype(affine.dtype,
                           input_coords.coord_dtype,
                           output_coords.coord_dtype)
        inaxes = input_coords.coord_names
        outaxes = output_coords.coord_names
        self._input_coords = CoordinateSystem(inaxes,
                                              input_coords.name,
                                              dtype)
        self._output_coords = CoordinateSystem(outaxes,
                                               output_coords.name,
                                               dtype)
        affine = np.asarray(affine, dtype=dtype)
        if affine.shape != (self.ndim[1]+1, self.ndim[0]+1):
            raise ValueError('coordinate lengths do not match '
                             'affine matrix shape')
        self._affine = affine
        A, b = affines.to_matrix_vector(affine)
        def _mapping(x):
            value = np.dot(x, A.T)
            value += b
            return value
        self._mapping = _mapping
예제 #4
0
파일: resample.py 프로젝트: cindeem/xipy
def resample(image, target, mapping, shape, order=3, **interp_kws):
    """
    Resample an image to a target CoordinateMap with a "world-to-world" mapping
    and spline interpolation of a given order.

    Here, "world-to-world" refers to the fact that mapping should be
    a callable that takes a physical coordinate in "target"
    and gives a physical coordinate in "image". 

    Parameters
    ----------
    image : Image instance that is to be resampled
    target :target CoordinateMap for output image
    mapping : transformation from target.function_range
               to image.coordmap.function_range, i.e. 'world-to-world mapping'
               Can be specified in three ways: a callable, a
               tuple (A, b) representing the mapping y=dot(A,x)+b
               or a representation of this in homogeneous coordinates. 
    shape : shape of output array, in target.function_domain
    order : what order of interpolation to use in `scipy.ndimage`
    interp_kws : keyword arguments for ndimage interpolator routine

    Returns
    -------
    output : Image instance with interpolated data and output.coordmap == target
                  
    """

    if not callable(mapping):
        if type(mapping) is type(()):
            A, b = mapping
            ndimout = b.shape[0]
            ndimin = A.shape[1]
            mapping  = np.zeros((ndimout+1, ndimin+1))
            mapping[:ndimout,:ndimin] = A
            mapping[:ndimout,-1] = b
            mapping[-1,-1] = 1.

     # image world to target world mapping

        TW2IW = AffineTransform(target.function_range, image.coordmap.function_range, mapping)
    else:
        TW2IW = CoordinateMap(mapping, target.function_range, image.coordmap.function_range)

    function_domain = target.function_domain
    function_range = image.coordmap.function_range

    # target voxel to image world mapping
    TV2IW = compose(TW2IW, target)

    # CoordinateMap describing mapping from target voxel to
    # image world coordinates

    if not isinstance(TV2IW, AffineTransform):
        # interpolator evaluates image at values image.coordmap.function_range,
        # i.e. physical coordinates rather than voxel coordinates
        grid = ArrayCoordMap.from_shape(TV2IW, shape)
        interp = ImageInterpolator(image, order=order)
        idata = interp.evaluate(grid.transposed_values, **interp_kws)
        del(interp)
    else:
        TV2IV = compose(image.coordmap.inverse(), TV2IW)
        if isinstance(TV2IV, AffineTransform):
            A, b = affines.to_matrix_vector(TV2IV.affine)
            data = np.asarray(image)
            idata = affine_transform(data, A,
                                     offset=b,
                                     output_shape=shape,
                                     output=data.dtype,
                                     order=order,
                                     **interp_kws)
        else:
            interp = ImageInterpolator(image, order=order)
            grid = ArrayCoordMap.from_shape(TV2IV, shape)
            idata = interp.evaluate(grid.values, **interp_kws)
            del(interp)
            
    return Image(idata, target)
예제 #5
0
파일: test_affines.py 프로젝트: FNNDSC/nipy
def test_to_matrix_vector():
    mat, vec, xform = build_xform()
    newmat, newvec = affines.to_matrix_vector(xform)
    yield assert_equal, newmat, mat
    yield assert_equal, newvec, vec