Example #1
0
def test_nonaffine():
    # resamples an image along a curve through the image.
    #
    # FIXME: use the reference.evaluate.Grid to perform this nicer
    # FIXME: Remove pylab references
    def curve(x):  # function accept N by 1, returns N by 2
        return np.vstack([5 * np.sin(x.T), 5 * np.cos(x.T)]).T + [52, 47]

    for names in (("xy", "ij", "t", "u"), ("ij", "xy", "t", "s")):
        in_names, out_names, tin_names, tout_names = names
        g = AffineTransform.from_params(in_names, out_names, np.identity(3))
        img = Image(np.ones((100, 90)), g)
        img[50:55, 40:55] = 3.0
        tcoordmap = AffineTransform.from_start_step(tin_names, tout_names, [0], [np.pi * 1.8 / 100])
        ir = resample(img, tcoordmap, curve, (100,))
    if gui_review:
        import pylab

        pylab.figure(num=3)
        pylab.imshow(img, interpolation="nearest")
        d = curve(np.linspace(0, 1.8 * np.pi, 100))
        pylab.plot(d[0], d[1])
        pylab.gca().set_ylim([0, 99])
        pylab.gca().set_xlim([0, 89])
        pylab.figure(num=4)
        pylab.plot(np.asarray(ir))
Example #2
0
def test_rotate2d():
    # Rotate an image in 2d on a square grid, should result in transposed image
    g = AffineTransform.from_params('ij', 'xy', np.diag([0.7,0.5,1]))
    g2 = AffineTransform.from_params('ij', 'xy', np.diag([0.5,0.7,1]))
    i = Image(np.ones((100,100)), g)
    # This sets the image data by writing into the array
    i.get_data()[50:55,40:55] = 3.
    a = np.array([[0,1,0],
                  [1,0,0],
                  [0,0,1]], np.float)
    ir = resample(i, g2, a, (100, 100))
    assert_array_almost_equal(ir.get_data().T, i.get_data())
Example #3
0
 def setUp(self):
     names = ['zspace', 'yspace', 'xspace']
     shape = (10,20,30)
     self.img = Image(np.zeros(shape), 
                      AffineTransform.from_start_step(names, names, (0,)*3, (1,)*3))
     self.img2 = Image(np.ones(shape), 
                       AffineTransform.from_start_step(names, names, (0,)*3, (1,)*3))
                    
     shape = (3,5,4)
     self.img3 = Image(np.zeros(shape), 
                       AffineTransform.from_start_step(names, names, (0,)*3, (1,)*3))
     self.img4 = Image(np.zeros(shape), 
                       AffineTransform.from_start_step(names, names, (0,)*3, (1,)*3))
Example #4
0
def test_rotate3d():
    # Rotate / transpose a 3d image on a non-square grid
    g = AffineTransform.from_params('ijk', 'xyz', np.diag([0.5,0.6,0.7,1]))
    g2 = AffineTransform.from_params('ijk', 'xyz', np.diag([0.5,0.7,0.6,1]))
    shape = (100,90,80)
    i = Image(np.ones(shape), g)
    i.get_data()[50:55,40:55,30:33] = 3.
    a = np.array([[1,0,0,0],
                  [0,0,1,0],
                  [0,1,0,0],
                  [0,0,0,1.]])
    ir = resample(i, g2, a, (100,80,90))
    assert_array_almost_equal(np.transpose(ir.get_data(), (0,2,1)),
                              i.get_data())
Example #5
0
def test_rotate3d():
    # Rotate / transpose a 3d image on a non-square grid

    g = AffineTransform.from_params("ijk", "xyz", np.diag([0.5, 0.6, 0.7, 1]))
    g2 = AffineTransform.from_params("ijk", "xyz", np.diag([0.5, 0.7, 0.6, 1]))

    shape = (100, 90, 80)
    i = Image(np.ones(shape), g)
    i[50:55, 40:55, 30:33] = 3.0

    a = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1.0]])

    ir = resample(i, g2, a, (100, 80, 90))
    yield assert_array_almost_equal, np.transpose(np.asarray(ir), (0, 2, 1)), i
Example #6
0
def test_rotate2d2():
    # Rotate an image in 2d on a non-square grid,
    # should result in transposed image

    g = AffineTransform.from_params("ij", "xy", np.diag([0.7, 0.5, 1]))
    g2 = AffineTransform.from_params("ij", "xy", np.diag([0.5, 0.7, 1]))

    i = Image(np.ones((100, 80)), g)
    i[50:55, 40:55] = 3.0

    a = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]], np.float)

    ir = resample(i, g2, a, (80, 100))
    yield assert_array_almost_equal, np.asarray(ir).T, i
Example #7
0
def test_slice_from_3d():
    # Resample a 3d image, returning a zslice, yslice and xslice
    #
    # This example creates a coordmap that coincides with
    # a given z, y, or x slice of an image, and checks that
    # resampling agrees with the data in the given slice.
    shape = (100,90,80)
    g = AffineTransform.from_params('ijk',
                                    'xyz',
                                    np.diag([0.5,0.5,0.5,1]))
    img = Image(np.ones(shape), g)
    img.get_data()[50:55,40:55,30:33] = 3
    I = np.identity(4)
    zsl = slices.zslice(26,
                        ((0,49.5), 100),
                        ((0,44.5), 90),
                        img.reference)
    ir = resample(img, zsl, I, (100, 90))
    assert_array_almost_equal(ir.get_data(), img[:,:,53].get_data())
    ysl = slices.yslice(22,
                        ((0,49.5), 100),
                        ((0,39.5), 80),
                        img.reference)
    ir = resample(img, ysl, I, (100, 80))
    assert_array_almost_equal(ir.get_data(), img[:,45,:].get_data())
    xsl = slices.xslice(15.5,
                        ((0,44.5), 90),
                        ((0,39.5), 80),
                        img.reference)
    ir = resample(img, xsl, I, (90, 80))
    assert_array_almost_equal(ir.get_data(), img[32,:,:].get_data())
Example #8
0
   def __init__(self, data, affine, axis_names, metadata={}, 
                lps=True):
      """ Creates a new nipy image with an affine mapping.

      Parameters
      ----------

      data : ndarray
         ndarray representing the data.

      affine : 4x4 ndarray
         affine transformation to the reference coordinate system

      axis_names : [string]
         names of the axes in the coordinate system.
      """

      if len(axis_names) < 3:
         raise ValueError('XYZImage must have a minimum of 3 axes')

      # The first three axes are assumed to be the
      # spatial ones
      xyz_transform = XYZTransform(affine, axis_names[:3], lps)
      nonspatial_names = axis_names[3:]
        
      if nonspatial_names:
         nonspatial_affine_transform = AffineTransform.from_start_step(nonspatial_names, nonspatial_names, [0]*(data.ndim-3), [1]*(data.ndim-3))
         full_dimensional_affine_transform = cmap_product(xyz_transform, nonspatial_affine_transform)
      else:
         full_dimensional_affine_transform = xyz_transform 

      self._xyz_transform = xyz_transform

      Image.__init__(self, data, full_dimensional_affine_transform,
                     metadata=metadata)
Example #9
0
    def __init__(self, data, affine, coord_sys, metadata=None):
        """ Creates a new nipy image with an affine mapping.

            Parameters
            ----------

            data : ndarray
                ndarray representing the data.
            affine : 4x4 ndarray
                affine transformation to the reference coordinate system
            coord_system : string
                name of the reference coordinate system.
        """

        function_domain = CoordinateSystem(['axis%d' % i for i in range(3)], 
                                        name=coord_sys)
        function_range = CoordinateSystem(['x','y','z'], name='world')
        spatial_coordmap = AffineTransform(function_domain, function_range,
                                           affine)

        nonspatial_names = ['axis%d' % i for i in range(3, data.ndim)]
        if nonspatial_names:
            nonspatial_coordmap = AffineTransform.from_start_step(nonspatial_names, nonspatial_names, [0]*(data.ndim-3), [1]*(data.ndim-3))
            full_coordmap = cmap_product(coordmap, nonspatial_coordmap)
        else:
            full_coordmap = spatial_coordmap 

        self._spatial_coordmap = spatial_coordmap

        self.coord_sys = coord_sys
        Image.__init__(self, data, full_coordmap) 
        if metadata is not None:
            self.metadata = metadata
Example #10
0
def test_resample2d2():
    g = AffineTransform.from_params("ij", "xy", np.diag([0.5, 0.5, 1]))
    i = Image(np.ones((100, 90)), g)
    i[50:55, 40:55] = 3.0
    a = np.identity(3)
    a[:2, -1] = 4.0
    A = np.identity(2)
    b = np.ones(2) * 4
    ir = resample(i, i.coordmap, (A, b), (100, 90))
    yield assert_array_almost_equal, ir[42:47, 32:47], 3.0
Example #11
0
def test_resample2d3():
    # Same as test_resample2d, only a different way of specifying
    # the transform: here it is an (A,b) pair
    g = AffineTransform.from_params('ij', 'xy', np.diag([0.5,0.5,1]))
    i = Image(np.ones((100,90)), g)
    i.get_data()[50:55,40:55] = 3.
    a = np.identity(3)
    a[:2,-1] = 4.
    ir = resample(i, i.coordmap, a, (100,90))
    assert_array_almost_equal(ir.get_data()[42:47,32:47], 3.)
Example #12
0
def test_resample2d2():
    g = AffineTransform.from_params('ij', 'xy', np.diag([0.5,0.5,1]))
    i = Image(np.ones((100,90)), g)
    i.get_data()[50:55,40:55] = 3.
    a = np.identity(3)
    a[:2,-1] = 4.
    A = np.identity(2)
    b = np.ones(2)*4
    ir = resample(i, i.coordmap, (A, b), (100,90))
    assert_array_almost_equal(ir.get_data()[42:47,32:47], 3.)
Example #13
0
def test_resample2d3():
    # Same as test_resample2d, only a different way of specifying
    # the transform: here it is an (A,b) pair
    g = AffineTransform.from_params("ij", "xy", np.diag([0.5, 0.5, 1]))
    i = Image(np.ones((100, 90)), g)
    i[50:55, 40:55] = 3.0
    a = np.identity(3)
    a[:2, -1] = 4.0
    ir = resample(i, i.coordmap, a, (100, 90))
    yield assert_array_almost_equal, ir[42:47, 32:47], 3.0
Example #14
0
def test_rotate2d3():
    # Another way to rotate/transpose the image, similar to
    # test_rotate2d2 and test_rotate2d, except the world of the
    # output coordmap is the same as the world of the
    # original image. That is, the data is transposed on disk, but the
    # output coordinates are still 'x,'y' order, not 'y', 'x' order as
    # above

    # this functionality may or may not be used a lot. if data is to
    # be transposed but one wanted to keep the NIFTI order of output
    # coords this would do the trick
    g = AffineTransform.from_params('xy', 'ij', np.diag([0.5,0.7,1]))
    i = Image(np.ones((100,80)), g)
    # This sets the image data by writing into the array
    i.get_data()[50:55,40:55] = 3.
    a = np.identity(3)
    g2 = AffineTransform.from_params('xy', 'ij', np.array([[0,0.5,0],
                                                  [0.7,0,0],
                                                  [0,0,1]]))
    ir = resample(i, g2, a, (80,100))
    assert_array_almost_equal(ir.get_data().T, i.get_data())
Example #15
0
def test_rotate2d3():
    # Another way to rotate/transpose the image, similar to
    # test_rotate2d2 and test_rotate2d except the world of the
    # output coordmap are the same as the world of the
    # original image. That is, the data is transposed on disk, but the
    # output coordinates are still 'x,'y' order, not 'y', 'x' order as
    # above

    # this functionality may or may not be used a lot. if data is to
    # be transposed but one wanted to keep the NIFTI order of output
    # coords this would do the trick

    g = AffineTransform.from_params("xy", "ij", np.diag([0.5, 0.7, 1]))
    i = Image(np.ones((100, 80)), g)
    i[50:55, 40:55] = 3.0

    a = np.identity(3)
    g2 = AffineTransform.from_params("xy", "ij", np.array([[0, 0.5, 0], [0.7, 0, 0], [0, 0, 1]]))
    ir = resample(i, g2, a, (80, 100))
    v2v = compose(g.inverse(), g2)
    yield assert_array_almost_equal, np.asarray(ir).T, i
Example #16
0
def test_2d_from_3d():
    # Resample a 3d image on a 2d affine grid
    # This example creates a coordmap that coincides with
    # the 10th slice of an image, and checks that
    # resampling agrees with the data in the 10th slice.
    shape = (100, 90, 80)
    g = AffineTransform.from_params("ijk", "xyz", np.diag([0.5, 0.5, 0.5, 1]))
    i = Image(np.ones(shape), g)
    i[50:55, 40:55, 30:33] = 3.0
    a = np.identity(4)
    g2 = ArrayCoordMap.from_shape(g, shape)[10]
    ir = resample(i, g2.coordmap, a, g2.shape)
    yield assert_array_almost_equal, np.asarray(ir), np.asarray(i[10])
Example #17
0
def test_resample2d1():
    # Tests the same as test_resample2d, only using a callable instead of
    # an AffineTransform instance
    g = AffineTransform.from_params('ij', 'xy', np.diag([0.5,0.5,1]))
    i = Image(np.ones((100,90)), g)
    i.get_data()[50:55,40:55] = 3.
    a = np.identity(3)
    a[:2,-1] = 4.
    A = np.identity(2)
    b = np.ones(2)*4
    def mapper(x):
        return np.dot(x, A.T) + b
    ir = resample(i, i.coordmap, mapper, (100,90))
    assert_array_almost_equal(ir.get_data()[42:47,32:47], 3.)
Example #18
0
   def __init__(self, affine, axis_names, lps=True):

      """
      >>> xyz = XYZTransform(np.diag([3,4,5,1]), 'ijk')
      >>> xyz
      XYZTransform(
         function_domain=CoordinateSystem(coord_names=('i', 'j', 'k'), name='voxel', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI'), name='world', coord_dtype=float64),
         affine=array([[ 3.,  0.,  0.,  0.],
                       [ 0.,  4.,  0.,  0.],
                       [ 0.,  0.,  5.,  0.],
                       [ 0.,  0.,  0.,  1.]])
      )
      >>> 
      """

      if affine.shape != (4,4):
          raise ValueError('affine must be a 4x4 matrix representing an affine transformation in homogeneous coordinates')
      if lps:
         xyz = lps_output_coordnames
      else:
         xyz = ras_output_coordnames
      AffineTransform.__init__(self, CS(axis_names, name='voxel'), 
                               CS(xyz, name='world'), affine)
Example #19
0
def test_resample2d():
    g = AffineTransform.from_params('ij', 'xy', np.diag([0.5,0.5,1]))
    i = Image(np.ones((100,90)), g)
    i.get_data()[50:55,40:55] = 3.
    # This mapping describes a mapping from the "target" physical
    # coordinates to the "image" physical coordinates.  The 3x3 matrix
    # below indicates that the "target" physical coordinates are related
    # to the "image" physical coordinates by a shift of -4 in each
    # coordinate.  Or, to find the "image" physical coordinates, given
    # the "target" physical coordinates, we add 4 to each "target
    # coordinate".  The resulting resampled image should show the
    # overall image shifted -8,-8 voxels towards the origin
    a = np.identity(3)
    a[:2,-1] = 4.
    ir = resample(i, i.coordmap, a, (100,90))
    assert_array_almost_equal(ir.get_data()[42:47,32:47], 3.)
Example #20
0
def output_resid(outfile, fmri_image, clobber=False):
    """
    Create an output file of the residuals parameter from the OLS pass of
    fmristat.

    Uses affine part of the first image to output resids unless
    fmri_image is an Image.

    Parameters
    ----------
    outfile :
    fmri_image : ``FmriImageList`` or 4D image
       If ``FmriImageList``, needs attributes ``volume_start_times``,
       supports len(), and object[0] has attributes ``affine``,
       ``coordmap`` and ``shape``, from which we create a new 4D
       coordmap and shape
       If 4D image, use the images coordmap and shape
    clobber : bool
       if True, overwrite previous output

    Returns
    -------
    regression_output : 
    """

    if isinstance(fmri_image, FmriImageList):
        n = len(fmri_image.list)
        T = np.zeros((5,5))
        g = fmri_image[0].coordmap
        T[1:,1:] = fmri_image[0].affine
        T[0,0] = (fmri_image.volume_start_times[1:] - 
                  fmri_image.volume_start_times[:-1]).mean()
        # FIXME: NIFTI specific naming here
        innames = ["l"] + list(g.input_coords.coord_names)
        outnames = ["t"] + list(g.output_coords.coord_names)
        cmap = AffineTransform.from_params(innames,
                                  outnames, T)
        shape = (n,) + fmri_image[0].shape
    elif isinstance(fmri_image, Image):
        cmap = fmri_image.coordmap
        shape = fmri_image.shape
    else:
        raise ValueError, "expecting FmriImageList or 4d Image"

    outim = ModelOutputImage(outfile, cmap, shape, clobber=clobber)
    return regression.RegressionOutput(outim, regression.output_resid)
Example #21
0
def test_resample3d():
    g = AffineTransform.from_params("ijk", "xyz", np.diag([0.5, 0.5, 0.5, 1]))
    shape = (100, 90, 80)
    i = Image(np.ones(shape), g)
    i[50:55, 40:55, 30:33] = 3.0
    # This mapping describes a mapping from the "target" physical
    # coordinates to the "image" physical coordinates.  The 4x4 matrix
    # below indicates that the "target" physical coordinates are related
    # to the "image" physical coordinates by a shift of -4 in each
    # coordinate.  Or, to find the "image" physical coordinates, given
    # the "target" physical coordinates, we add 4 to each "target
    # coordinate".  The resulting resampled image should show the
    # overall image shifted [-6,-8,-10] voxels towards the origin
    a = np.identity(4)
    a[:3, -1] = [3, 4, 5]
    ir = resample(i, i.coordmap, a, (100, 90, 80))
    yield assert_array_almost_equal, ir[44:49, 32:47, 20:23], 3.0
Example #22
0
def test_resample3d():
    g = AffineTransform.from_params('ijk', 'xyz', np.diag([0.5, 0.5, 0.5, 1]))
    shape = (100, 90, 80)
    i = Image(np.ones(shape), g)
    i.get_data()[50:55, 40:55, 30:33] = 3.
    # This mapping describes a mapping from the "target" physical
    # coordinates to the "image" physical coordinates.  The 4x4 matrix
    # below indicates that the "target" physical coordinates are related
    # to the "image" physical coordinates by a shift of -4 in each
    # coordinate.  Or, to find the "image" physical coordinates, given
    # the "target" physical coordinates, we add 4 to each "target
    # coordinate".  The resulting resampled image should show the
    # overall image shifted [-6,-8,-10] voxels towards the origin
    a = np.identity(4)
    a[:3, -1] = [3, 4, 5]
    ir = resample(i, i.coordmap, a, (100, 90, 80))
    assert_array_almost_equal(ir.get_data()[44:49, 32:47, 20:23], 3.)
Example #23
0
def output_resid(outfile, fmri_image, clobber=False):
    """
    Create an output file of the residuals parameter from the OLS pass of
    fmristat.

    Uses affine part of the first image to output resids unless
    fmri_image is an Image.

    Parameters
    ----------
    outfile :
    fmri_image : ``FmriImageList`` or 4D image
       If ``FmriImageList``, needs attributes ``volume_start_times``,
       supports len(), and object[0] has attributes ``affine``,
       ``coordmap`` and ``shape``, from which we create a new 4D
       coordmap and shape
       If 4D image, use the images coordmap and shape
    clobber : bool
       if True, overwrite previous output

    Returns
    -------
    regression_output :
    """
    if isinstance(fmri_image, FmriImageList):
        n = len(fmri_image.list)
        T = np.zeros((5, 5))
        g = fmri_image[0].coordmap
        T[1:, 1:] = fmri_image[0].affine
        T[0, 0] = (fmri_image.volume_start_times[1:] -
                   fmri_image.volume_start_times[:-1]).mean()
        # FIXME: NIFTI specific naming here
        innames = ["t"] + list(g.function_domain.coord_names)
        outnames = ["t"] + list(g.function_range.coord_names)
        cmap = AffineTransform.from_params(innames, outnames, T)
        shape = (n, ) + fmri_image[0].shape
    elif isinstance(fmri_image, Image):
        cmap = fmri_image.coordmap
        shape = fmri_image.shape
    else:
        raise ValueError, "expecting FmriImageList or 4d Image"

    outim = ModelOutputImage(outfile, cmap, shape, clobber=clobber)
    return outputters.RegressionOutput(outim, outputters.output_resid)
Example #24
0
def test_slice_from_3d():
    # Resample a 3d image, returning a zslice, yslice and xslice
    #
    # This example creates a coordmap that coincides with
    # the 10th slice of an image, and checks that
    # resampling agrees with the data in the 10th slice.
    shape = (100, 90, 80)
    g = AffineTransform.from_params("ijk", "xyz", np.diag([0.5, 0.5, 0.5, 1]))
    i = Image(np.ones(shape), g)
    i[50:55, 40:55, 30:33] = 3
    a = np.identity(4)
    zsl = slices.zslice(26, ((0, 44.5), 90), ((0, 39.5), 80), i.reference)
    ir = resample(i, zsl, a, (90, 80))
    yield assert_true(np.allclose(np.asarray(ir), np.asarray(i[53])))
    ysl = slices.yslice(22, (0, 49.5), (0, 39.5), i.reference, (100, 80))
    ir = resample(i, ysl.coordmap, a, ysl.shape)
    yield assert_true(np.allclose(np.asarray(ir), np.asarray(i[:, 45])))
    xsl = slices.xslice(15.5, (0, 49.5), (0, 44.5), i.reference, (100, 90))
    ir = resample(i, xsl.coordmap, a, xsl.shape)
    yield assert_true(np.allclose(np.asarray(ir), np.asarray(i[:, :, 32])))
Example #25
0
def generateTestingPair(betaGT):
    betaGTRads = np.array(betaGT, dtype=np.float64)
    betaGTRads[0:3] = np.copy(np.pi * betaGTRads[0:3] / 180.0)
    ns = 181
    nr = 217
    nc = 181
    left = np.fromfile('data/t2/t2_icbm_normal_1mm_pn0_rf0.rawb',
                       dtype=np.ubyte).reshape(ns, nr, nc)
    left = left.astype(np.float64)
    right = np.fromfile('data/t1/t1_icbm_normal_1mm_pn0_rf0.rawb',
                        dtype=np.ubyte).reshape(ns, nr, nc)
    right = right.astype(np.float64)
    right = rcommon.applyRigidTransformation3D(right, betaGTRads)
    affine_transform = AffineTransform(
        'ijk', ['aligned-z=I->S', 'aligned-y=P->A', 'aligned-x=L->R'],
        np.eye(4))
    left = Image(left, affine_transform)
    right = Image(right, affine_transform)
    nipy.save_image(left, 'moving.nii')
    nipy.save_image(right, 'fixed.nii')
Example #26
0
def test_slice_from_3d():
    # Resample a 3d image, returning a zslice, yslice and xslice
    #
    # This example creates a coordmap that coincides with
    # a given z, y, or x slice of an image, and checks that
    # resampling agrees with the data in the given slice.
    shape = (100, 90, 80)
    g = AffineTransform.from_params('ijk', 'xyz', np.diag([0.5, 0.5, 0.5, 1]))
    img = Image(np.ones(shape), g)
    img.get_data()[50:55, 40:55, 30:33] = 3
    I = np.identity(4)
    zsl = slices.zslice(26, ((0, 49.5), 100), ((0, 44.5), 90), img.reference)
    ir = resample(img, zsl, I, (100, 90))
    assert_array_almost_equal(ir.get_data(), img[:, :, 53].get_data())
    ysl = slices.yslice(22, ((0, 49.5), 100), ((0, 39.5), 80), img.reference)
    ir = resample(img, ysl, I, (100, 80))
    assert_array_almost_equal(ir.get_data(), img[:, 45, :].get_data())
    xsl = slices.xslice(15.5, ((0, 44.5), 90), ((0, 39.5), 80), img.reference)
    ir = resample(img, xsl, I, (90, 80))
    assert_array_almost_equal(ir.get_data(), img[32, :, :].get_data())
Example #27
0
def changeCoords2(affine, scale, coords):
    domain = coords.function_domain
    outrange = coords.function_range

    # Create a new matrix
    mod_affine = np.zeros((4, 4))
    # Set up the diagonals
    mod_affine[0, 0] = affine[0, 0] * scale
    mod_affine[1, 1] = affine[1, 1] * scale
    mod_affine[2, 2] = affine[2, 2] * scale
    mod_affine[
        3,
        3] = 1  # This is the new temporal dimension: each vol    ume is 2s apart
    # Pull the last column of the first 3 rows into the new matrix
    mod_affine[0, 3] = affine[0, 3] // scale
    mod_affine[1, 3] = affine[1, 3] // scale
    mod_affine[2, 3] = affine[2, 3] // scale

    modified = AffineTransform(domain, outrange, mod_affine)

    return modified
Example #28
0
def peelTemplateBrain():
    ns = 181
    nr = 217
    nc = 181
    gt_template = np.fromfile('data/phantom_1.0mm_normal_crisp.rawb',
                              dtype=np.ubyte).reshape((ns, nr, nc))
    t1_template = np.fromfile('data/t1/t1_icbm_normal_1mm_pn0_rf0.rawb',
                              dtype=np.ubyte).reshape((ns, nr, nc))
    t2_template = np.fromfile('data/t2/t2_icbm_normal_1mm_pn0_rf0.rawb',
                              dtype=np.ubyte).reshape((ns, nr, nc))
    #t1_template*=((1<=gt_template)*(gt_template<=3)+(gt_template==8))
    t1_template *= ((1 <= gt_template) * (gt_template <= 3))
    t2_template *= ((1 <= gt_template) * (gt_template <= 3))
    affine_transform = AffineTransform(
        'ijk', ['aligned-z=I->S', 'aligned-y=P->A', 'aligned-x=L->R'],
        np.eye(4))
    t1_template = Image(t1_template, affine_transform)
    t2_template = Image(t2_template, affine_transform)
    nipy.save_image(t1_template,
                    'data/t1/t1_icbm_normal_1mm_pn0_rf0_peeled.nii.gz')
    nipy.save_image(t2_template,
                    'data/t2/t2_icbm_normal_1mm_pn0_rf0_peeled.nii.gz')
Example #29
0
def testIntersubjectRigidRegistration(fname0, fname1, level, outfname):
    nib_left = nib.load(fname0)
    nib_right = nib.load(fname1)
    left = nib_left.get_data().astype(np.double).squeeze()
    right = nib_right.get_data().astype(np.double).squeeze()
    leftPyramid = [i for i in rcommon.pyramid_gaussian_3D(left, level)]
    rightPyramid = [i for i in rcommon.pyramid_gaussian_3D(right, level)]
    plotSlicePyramidsAxial(leftPyramid, rightPyramid)
    print 'Estimation started.'
    beta = estimateRigidTransformationMultiscale3D(leftPyramid, rightPyramid)
    print 'Estimation finished.'
    rcommon.applyRigidTransformation3D(left, beta)
    sl = np.array(left.shape) // 2
    sr = np.array(right.shape) // 2
    rcommon.overlayImages(left[sl[0], :, :], leftPyramid[0][sr[0], :, :])
    rcommon.overlayImages(left[sl[0], :, :], right[sr[0], :, :])
    affine_transform = AffineTransform(
        'ijk', ['aligned-z=I->S', 'aligned-y=P->A', 'aligned-x=L->R'],
        np.eye(4))
    left = Image(left, affine_transform)
    nipy.save_image(left, outfname)

    return beta
Example #30
0
def convert3DCoordsTo4D(orig):
    # Get the data from the original coordinates
    domain = orig.function_domain
    outrange = orig.function_range
    affine = orig.affine
    print(type(affine), affine)

    # Add the temporal dimension
    mod_domain = CoordinateSystem(domain.coord_names + ('t', ), domain.name,
                                  domain.coord_dtype)
    mod_range = CoordinateSystem(outrange.coord_names + ('t', ), outrange.name,
                                 outrange.coord_dtype)

    # Temporal is a little trickier in the affine matrix
    # Create a new matrix
    mod_affine = np.zeros((5, 5))
    # Set up the diagonals
    mod_affine[0, 0] = affine[0, 0]
    mod_affine[1, 1] = affine[1, 1]
    mod_affine[2, 2] = affine[2, 2]
    mod_affine[
        3,
        3] = 2  # This is the new temporal dimension: each volume is 2s apart
    mod_affine[
        4,
        4] = 1  # This is the last row in the matrix and should be all 0 except this column
    # Pull the last column of the first 3 rows into the new matrix
    mod_affine[0, 4] = affine[0, 3]
    mod_affine[1, 4] = affine[1, 3]
    mod_affine[2, 4] = affine[2, 3]

    print(mod_affine)

    modified = AffineTransform(mod_domain, mod_range, mod_affine)

    return modified
Example #31
0
def create(rootdir):

    out = None
    prev = None

    out_is_there = False

    dirs = sorted(os.listdir(rootdir))

    for d in dirs:

        files = os.listdir(os.path.join(rootdir, d))

        for f in files:
            input_image = tif.imread(os.path.join(rootdir, d, f))
            # print input_image
            # print type(input_image)
            # print 'ccc',input_image.flatten()
            if out_is_there:
                #out = np.concatenate([out, input_image.flatten()])
                out = np.dstack([out, input_image])
            else:
                # out = input_image.flatten()
                out = input_image
                out_is_there = True

    # return

    # i = 0
    # for root, dirs, files in os.walk(rootdir):

    #     fullpaths = [(os.path.join(root, name)) for name in files]

    #     for f in fullpaths:
    #       print f
    #       input_image = tif.imread(f)
    #       # print input_image
    #       # print type(input_image)
    #       # print 'ccc',input_image.flatten()
    #       if out_is_there:
    #         #out = np.concatenate([out, input_image.flatten()])
    #         out = np.dstack([out, input_image])
    #       else:
    #         # out = input_image.flatten()
    #         out = input_image
    #         out_is_there = True


#>>> from nipy.io.api import save_image
#>>> data = np.zeros((91,109,91), dtype=np.uint8)
#>>> cmap = AffineTransform('kji', 'zxy', np.eye(4))
#>>> img = Image(data, cmap)
#>>> fname1 = os.path.join(tmpdir, 'img1.nii.gz')
#>>> saved_img1 = save_image(img, fname1)

# image_data = PILImage.open(os.path.join(subdir,file))
# if image_data.mode != "RGB":
#   image_data = image_data.convert("RGB")

# print image_data.toString()
# break

# shutil.copy(os.path.join(subdir, file), '/tmp/'+str(i)+'.tif')
# i+=1
    length = out.shape[0]
    print 'aaa'
    print out
    # out = out.reshape((512, 512, length/512/512))
    print out
    cmap = AffineTransform('kji', 'zxy', np.eye(4))
    img = Image(out, cmap)
    save_image(img, '/tmp/out.nii.gz')
Example #32
0
def test_array_coord_map():
    # array coord map recreates the affine when you slice an image.  In
    # general, if you take an integer slice in some dimension, the
    # corresponding column of the affine will go, leaving a row for the
    # lost dimension, with all zeros, execpt for the translation in the
    # now-removed dimension, encoding the position of that particular
    # slice
    xz = 1.1; yz = 2.3; zz = 3.5
    xt = 10.0; yt = 11; zt = 12
    aff = np.diag([xz, yz, zz, 1])
    aff[:3,3] = [xt, yt, zt]
    shape = (2,3,4)
    cmap = AffineTransform.from_params('ijk', 'xyz', aff)
    acm = acs.ArrayCoordMap(cmap, shape)
    # slice the coordinate map for the first axis
    sacm = acm[1]
    # The affine has lost the first column, but has a remaining row (the
    # first) encoding the translation to get to this slice
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [0, 0, xz+xt],
                                  [yz, 0, yt],
                                  [0, zz, zt],
                                  [0, 0, 1]]))
    sacm = acm[:,1]
    # lost second column, remaining second row with translation
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [xz, 0, xt],
                                  [0, 0, yz+yt],
                                  [0, zz, zt],
                                  [0, 0, 1]]))
    sacm = acm[:,:,2]
    # ditto third column and row
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [xz, 0, xt],
                                  [0, yz, yt],
                                  [0, 0, 2*zz+zt],
                                  [0, 0, 1]]))
    # check ellipsis slicing is the same as [:,: ...
    sacm = acm[...,2]
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [xz, 0, xt],
                                  [0, yz, yt],
                                  [0, 0, 2*zz+zt],
                                  [0, 0, 1]]))
    # that ellipsis can follow other slice types
    sacm = acm[:,...,2]
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [xz, 0, xt],
                                  [0, yz, yt],
                                  [0, 0, 2*zz+zt],
                                  [0, 0, 1]]))
    # that there can be only one ellipsis
    assert_raises(ValueError, acm.__getitem__, (
        (Ellipsis, Ellipsis,2)))
    # that you can integer slice in all three dimensions, leaving only
    # the translation column
    sacm = acm[1,0,2]
    assert_array_almost_equal(sacm.coordmap.affine,
                              np.array([
                                  [xz+xt],
                                  [yt],
                                  [2*zz+zt],
                                  [1]]))
    # that anything other than an int, slice or Ellipsis is an error
    assert_raises(ValueError, acm.__getitem__, ([0,2],))
    assert_raises(ValueError, acm.__getitem__, (np.array([0,2]),))
Example #33
0
def ni_affine_pixdim_from_affine(affine_transform, strict=False):
    """

    Given a square affine_transform,
    return a new 3-dimensional AffineTransform
    and the pixel dimensions in dimensions 
    greater than 3.

    If strict is True, then an exception is raised if
    the affine matrix is not diagonal with
    positive entries in dimensions 
    greater than 3. 

    If strict is True, then the names of the range coordinates
    must be LPS:('x+LR','y+PA','z+SI') or RAS:('x+RL','y+AP','z+SI'). If strict is False, and the names
    are not either of these, LPS:('x+LR','y+PA','z+SI') are used.

    If the names are RAS:('x+RL','y+AA','z+SI'), then the affine is flipped
    so the result is in LPS:('x+LR','y+PA','z+SI').

    NIFTI images have the first 3 dimensions as spatial, and the
    remaining as non-spatial, with the 4th typically being time.

    Parameters
    ----------
    affine_transform : `AffineTransform`

    Returns
    -------
    nifti_transform: `AffineTransform`
       A 3-dimensional or less AffineTransform

    pixdim : ndarray(np.float)
       The pixel dimensions greater than 3.

    >>> outnames = CS(('x+LR','y+PA','z+SI') + ('t',))
    >>> innames = CS(['phase', 'j', 'frequency', 't'])
    >>> af_tr = AT(outnames, innames, np.diag([2,-2,3,3.5,1]))
    >>> print af_tr
    AffineTransform(
       function_domain=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI', 't'), name='', coord_dtype=float64),
       function_range=CoordinateSystem(coord_names=('phase', 'j', 'frequency', 't'), name='', coord_dtype=float64),
       affine=array([[ 2. ,  0. ,  0. ,  0. ,  0. ],
                     [ 0. , -2. ,  0. ,  0. ,  0. ],
                     [ 0. ,  0. ,  3. ,  0. ,  0. ],
                     [ 0. ,  0. ,  0. ,  3.5,  0. ],
                     [ 0. ,  0. ,  0. ,  0. ,  1. ]])
    )

    >>> af_tr3dorless, p = ni_affine_pixdim_from_affine(af_tr)
    >>> print af_tr3dorless
    AffineTransform(
       function_domain=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI'), name='', coord_dtype=float64),
       function_range=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI'), name='', coord_dtype=float64),
       affine=array([[ 2.,  0.,  0.,  0.],
                     [ 0., -2.,  0.,  0.],
                     [ 0.,  0.,  3.,  0.],
                     [ 0.,  0.,  0.,  1.]])
    )
    >>> print p
    [ 3.5]

    """ 

    if ((not isinstance(affine_transform, AT)) or
        (affine_transform.ndims[0] != affine_transform.ndims[1])):
        raise ValueError('affine_transform must be a square AffineTransform' + 
                         ' to save as a NIFTI file')
    
    ndim = affine_transform.ndims[0]
    ndim3 = min(ndim, 3)
    range_names = affine_transform.function_range.coord_names
    if range_names[:ndim3] not in [lps_output_coordnames[:ndim3],
                               ras_output_coordnames[:ndim3]]:
        if strict:
            raise ValueError('strict is true and the range is not LPS or RAS, assuming LPS')
        warnings.warn('range is not LPS or RAS, assuming LPS')
        range_names = list(range_names)
        range_names[:ndim3] = lps_output_coordnames[:ndim3]
        range_names = tuple(range_names)

    ndim = affine_transform.ndims[0]
    nifti_indim = 'ijk'[:ndim] + 'tuvw'[ndim3:ndim]
    nifti_outdim = range_names[:ndim3] + \
        ('t', 'u', 'v', 'w' )[ndim3:ndim]

    nifti_transform = AT(CS(nifti_indim),
                         CS(nifti_outdim),
                         affine_transform.affine)

    domain_names = affine_transform.function_domain.coord_names[:ndim3]
    nifti_transform = nifti_transform.renamed_domain(dict(zip('ijk'[:ndim3],
                                                         domain_names)))


    # now find the pixdims

    A = nifti_transform.affine[3:,3:]
    if (not np.allclose(np.diag(np.diag(A)), A)
        or not np.all(np.diag(A) > 0)):
        msg = "affine transformation matrix is not diagonal " + \
              " with positive entries on diagonal, some information lost"
        if strict:
            raise ValueError('strict is true and %s' % msg)
        warnings.warn(msg)
    pixdim = np.fabs(np.diag(A)[:-1])

    # find the 4x4 (or smaller)

    A3d = np.identity(ndim3+1)
    A3d[:ndim3,:ndim3] = nifti_transform.affine[:ndim3, :ndim3]
    A3d[:ndim3,-1] = nifti_transform.affine[:ndim3, -1]

    range_names = nifti_transform.function_range.coord_names[:ndim3]
    nifti_3dorless_transform = AT(CS(domain_names),
                                  CS(range_names),
                                  A3d)

    # if RAS, we flip, with a warning

    if range_names[:ndim3] == ras_output_coordnames[:ndim3]:
        signs = [-1,-1,1,1][:(ndim3+1)]
        # silly, but 1d case is handled for consistency
        if signs == [-1,-1]:
            signs = [-1,1]
        ras_to_lps = AT(CS(ras_output_coordnames[:ndim3]),
                        CS(lps_output_coordnames[:ndim3]),
                        np.diag(signs))
        warnings.warn('affine_transform has RAS output_range, flipping to LPS')
        nifti_3dorless_transform = compose(ras_to_lps, nifti_3dorless_transform)

    return nifti_3dorless_transform, pixdim
Example #34
0
def affine_transform_from_array(affine, ijk, pixdim):
    """Generate a AffineTransform from an affine transform.

    This is a convenience function to create a AffineTransform from image
    attributes.  It assumes that the first three axes in the image (and
    therefore affine) are spatial (in 'ijk' in input and equal to 'xyz'
    in output), and appends the standard names for further dimensions
    (e.g. 'l' as the 4th in input, 't' as the 4th in output).

    Parameters
    ----------
    affine : array
       affine for affine_transform

    ijk : sequence
       sequence, some permutation of 'ijk', giving spatial axis
       ordering.  These are the spatial input axis names

    pixdim : sequence of floats
       Pixdims for dimensions beyond 3.

    Returns
    -------

    3daffine_transform : ``AffineTransform``
       affine transform corresponding to `affine` and `ijk` domain names
       with LPS range names

    full_transform: ``AffineTransform``
       affine transform corresponding to `affine` and `ijk` domain names
       for first 3 coordinates, diagonal with pixdim values beyond
       
    Examples
    --------
    >>> af_tr3d, af_tr = affine_transform_from_array(np.diag([2,3,4,1]), 'ijk', [])
    >>> af_tr.function_domain.coord_names
    ('i', 'j', 'k')
    >>> af_tr3d.function_domain.coord_names
    ('i', 'j', 'k')
    
    >>> af_tr.function_range.coord_names
    ('x+LR', 'y+PA', 'z+SI')
    >>> af_tr3d.function_range.coord_names
    ('x+LR', 'y+PA', 'z+SI')
    >>> af_tr3d, af_tr = affine_transform_from_array(np.diag([2,3,4,1]), 'kij', [3.5])
    >>> af_tr.function_domain.coord_names
    ('k', 'i', 'j', 't')
    >>> af_tr.function_range.coord_names
    ('x+LR', 'y+PA', 'z+SI', 't')
    >>> af_tr3d.function_domain.coord_names
    ('k', 'i', 'j')
    >>> af_tr3d.function_range.coord_names
    ('x+LR', 'y+PA', 'z+SI')
    >>> print af_tr3d
    AffineTransform(
       function_domain=CoordinateSystem(coord_names=('k', 'i', 'j'), name='', coord_dtype=float64),
       function_range=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI'), name='', coord_dtype=float64),
       affine=array([[ 2.,  0.,  0.,  0.],
                     [ 0.,  3.,  0.,  0.],
                     [ 0.,  0.,  4.,  0.],
                     [ 0.,  0.,  0.,  1.]])
    )

    >>> print af_tr
    AffineTransform(
       function_domain=CoordinateSystem(coord_names=('k', 'i', 'j', 't'), name='product', coord_dtype=float64),
       function_range=CoordinateSystem(coord_names=('x+LR', 'y+PA', 'z+SI', 't'), name='product', coord_dtype=float64),
       affine=array([[ 2. ,  0. ,  0. ,  0. ,  0. ],
                     [ 0. ,  3. ,  0. ,  0. ,  0. ],
                     [ 0. ,  0. ,  4. ,  0. ,  0. ],
                     [ 0. ,  0. ,  0. ,  3.5,  0. ],
                     [ 0. ,  0. ,  0. ,  0. ,  1. ]])
    )


    FIXME: This is an internal function and should be revisited when
    the AffineTransform is refactored.

    """
    if affine.shape != (4, 4) or len(ijk) != 3:
        raise ValueError('affine must be square, 4x4, ijk of length 3')
    innames = tuple(ijk) + tuple('tuvw'[:len(pixdim)])
    incoords = CS(innames, 'voxel')
    outnames = lps_output_coordnames + tuple('tuvw'[:len(pixdim)])
    outcoords = CS(outnames, 'world')
    transform3d = AT(CS(incoords.coord_names[:3]), 
                     CS(outcoords.coord_names[:3]), affine)
    if pixdim:
        nonspatial = AT.from_params(incoords.coord_names[3:], 
                                    outcoords.coord_names[3:],
                                    np.diag(list(pixdim) + [1]))
        transform_full = mapping_product(transform3d, nonspatial)
    else:
        transform_full = transform3d
    return transform3d, transform_full
Example #35
0
    def smooth(self, inimage, clean=False, is_fft=False):
        """
        :Parameters:
            inimage : `core.api.Image`
                The image to be smoothed
            clean : ``bool``
                Should we call ``nan_to_num`` on the data before smoothing?
            is_fft : ``bool``
                Has the data already been fft'd?

        :Returns: `Image`
        """
        if inimage.ndim == 4:
            _out = np.zeros(inimage.shape)
            nslice = inimage.shape[0]
        elif inimage.ndim == 3:
            nslice = 1
        else:
            raise NotImplementedError, 'expecting either 3 or 4-d image.'

        for _slice in range(nslice):
            if inimage.ndim == 4:
                data = inimage[_slice]
            elif inimage.ndim == 3:
                data = inimage[:]

            if clean:
                data = np.nan_to_num(data)
            if not is_fft:
                data = self._presmooth(data)
                data *= self.fkernel 
            else:
                data *= self.fkernel

            data = fft.irfftn(data) / self.norms[self.normalization]

            gc.collect()
            _dslice = [slice(0, self.bshape[i], 1) for i in range(3)]
            if self.scale != 1:
                data = self.scale * data[_dslice]

            if self.location != 0.0:
                data += self.location

            gc.collect()

            # Write out data 

            if inimage.ndim == 4:
                _out[_slice] = data
            else:
                _out = data
            _slice += 1

        gc.collect()
        _out = _out[[slice(self._kernel.shape[i]/2, self.bshape[i] +
                           self._kernel.shape[i]/2) for i in range(len(self.bshape))]]
        if inimage.ndim == 3:
            return Image(_out, coordmap=self.coordmap)
        else:
            concat_affine = AffineTransform.identity('concat')
            return Image(_out, coordmap=product(self.coordmap, concat_affine))
Example #36
0
 def __repr__(self):
     s_split = AffineTransform.__repr__(self).split('\n')
     s_split[0] = 'XYZTransform('
     return '\n'.join(s_split)
Example #37
0
def test_affine_transform_from_array():
    X = np.random.standard_normal((4, 4))
    X[-1] = [0, 0, 0, 1]
    function_domain = CoordinateSystem("ijk", "input")
    function_range = CoordinateSystem(lps, "output")
    cmap = AffineTransform(function_domain, function_range, X)

    A, _ = niref.affine_transform_from_array(X, "ijk", [])

    yield assert_almost_equal, X, A.affine
    yield assert_raises, ValueError, niref.affine_transform_from_array, X[:, 1:], "ijk", []
    yield assert_raises, ValueError, niref.affine_transform_from_array, X, "ij", []

    threed, fourd = niref.affine_transform_from_array(X, "ijk", [3.5])
    yield assert_almost_equal, X, threed.affine
    yield assert_almost_equal, fourd.affine[3:, 3:], np.diag([3.5, 1])

    # get the pixdim back out
    A, p = niref.ni_affine_pixdim_from_affine(fourd)

    yield assert_almost_equal, X, A.affine
    yield assert_almost_equal, p, 3.5

    # try strict
    A, p = niref.ni_affine_pixdim_from_affine(fourd, strict=True)

    # try using RAS

    cmap = fourd.renamed_range(dict(zip(lps, ras_output_coordnames)))
    A, p = niref.ni_affine_pixdim_from_affine(cmap, strict=True)

    # will have been flipped to LPS

    yield assert_almost_equal, A.affine, np.dot(np.diag([-1, -1, 1, 1]), X)
    yield assert_equal, A.function_range.coord_names, lps

    # use coordinates that aren't OK and strict raises an exception

    cmap = fourd.renamed_range(dict(zip(lps, "xyz")))
    yield assert_raises, ValueError, niref.ni_affine_pixdim_from_affine, cmap, True

    # use coordinates that aren't OK and not strict just guesses LPS

    cmap4 = fourd.renamed_range(dict(zip(lps, "xyz")))
    A, p = niref.ni_affine_pixdim_from_affine(cmap4, False)

    yield assert_almost_equal, A.affine, X
    yield assert_equal, A.function_range.coord_names, lps
    yield assert_almost_equal, p, 3.5

    # non-square affine fails

    Z = np.random.standard_normal((5, 4))
    Z[-1] = [0, 0, 0, 1]
    affine = AffineTransform.from_params("ijk", "xyzt", Z)
    yield assert_raises, ValueError, niref.ni_affine_pixdim_from_affine, affine

    # CoordinateMap fails

    ijk = CoordinateSystem("ijk")
    xyz = CoordinateSystem("xzy")
    cmap = CoordinateMap(ijk, xyz, np.exp)

    yield assert_raises, ValueError, niref.ni_affine_pixdim_from_affine, cmap, True

    # non-diagonal above 3rd dimension, with strict True raises an exception

    cmap5 = cmap4.renamed_range(dict(zip("xyz", lps)))
    cmap5.affine[3, -1] = 4.0

    yield assert_raises, ValueError, niref.ni_affine_pixdim_from_affine, cmap5, True
    B, p = niref.ni_affine_pixdim_from_affine(cmap5)
    yield assert_equal, p, 3.5
Example #38
0
    def smooth(self, inimage, clean=False, is_fft=False):
        """ Apply smoothing to `inimage`

        Parameters
        ----------
        inimage : ``Image``
           The image to be smoothed.  Should be 3D.
        clean : bool, optional
           Should we call ``nan_to_num`` on the data before smoothing?
        is_fft : bool, optional
           Has the data already been fft'd?

        Returns
        -------
        s_image : `Image`
           New image, with smoothing applied
        """
        if inimage.ndim == 4:
            # we need to generalize which axis to iterate over.  By
            # default it should probably be the last.
            raise NotImplementedError('Smoothing volumes in a 4D series '
                                      'is broken, pending a rethink')
            _out = np.zeros(inimage.shape)
            # iterate over the first (0) axis - this is confusing - see
            # above
            nslice = inimage.shape[0]
        elif inimage.ndim == 3:
            nslice = 1
        else:
            raise NotImplementedError('expecting either 3 or 4-d image')
        in_data = inimage.get_data()
        for _slice in range(nslice):
            if in_data.ndim == 4:
                data = in_data[_slice]
            elif in_data.ndim == 3:
                data = in_data[:]
            if clean:
                data = np.nan_to_num(data)
            if not is_fft:
                data = self._presmooth(data)
            data *= self.fkernel
            data = fft.irfftn(data) / self.norms[self.normalization]
            gc.collect()
            _dslice = [slice(0, self.bshape[i], 1) for i in range(3)]
            if self.scale != 1:
                data = self.scale * data[_dslice]
            if self.location != 0.0:
                data += self.location
            gc.collect()
            # Write out data 
            if in_data.ndim == 4:
                _out[_slice] = data
            else:
                _out = data
            _slice += 1
        gc.collect()
        _out = _out[[slice(self._kernel.shape[i]/2, self.bshape[i] +
                           self._kernel.shape[i]/2) for i in range(len(self.bshape))]]
        if inimage.ndim == 3:
            return Image(_out, coordmap=self.coordmap)
        else:
            # This does not work as written.  See above
            concat_affine = AffineTransform.identity('concat')
            return Image(_out, coordmap=product(self.coordmap, concat_affine))
Example #39
0
 def __init__(self, function_domain, function_range, matrix):
     ndim = matrix.shape[0]
     T = np.identity(ndim + 1, dtype=matrix.dtype)
     T[:-1, :-1] = matrix
     AffineTransform.__init__(self, function_domain, function_range, T)
Example #40
0
def test_array_coord_map():
    # array coord map recreates the affine when you slice an image.  In
    # general, if you take an integer slice in some dimension, the
    # corresponding column of the affine will go, leaving a row for the
    # lost dimension, with all zeros, execpt for the translation in the
    # now-removed dimension, encoding the position of that particular
    # slice
    xz = 1.1; yz = 2.3; zz = 3.5
    xt = 10.0; yt = 11; zt = 12
    aff = np.diag([xz, yz, zz, 1])
    aff[:3,3] = [xt, yt, zt]
    shape = (2,3,4)
    cmap = AffineTransform.from_params('ijk', 'xyz', aff)
    acm = acs.ArrayCoordMap(cmap, shape)
    # slice the coordinate map for the first axis
    sacm = acm[1]
    # The affine has lost the first column, but has a remaining row (the
    # first) encoding the translation to get to this slice
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [0, 0, xz+xt],
                [yz, 0, yt],
                [0, zz, zt],
                [0, 0, 1]]))
    sacm = acm[:,1]
    # lost second column, remaining second row with translation
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [xz, 0, xt],
                [0, 0, yz+yt],
                [0, zz, zt],
                [0, 0, 1]]))
    sacm = acm[:,:,2]
    # ditto third column and row
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [xz, 0, xt],
                [0, yz, yt],
                [0, 0, 2*zz+zt],
                [0, 0, 1]]))
    # check ellipsis slicing is the same as [:,: ...
    sacm = acm[...,2]
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [xz, 0, xt],
                [0, yz, yt],
                [0, 0, 2*zz+zt],
                [0, 0, 1]]))
    # that ellipsis can follow other slice types
    sacm = acm[:,...,2]
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [xz, 0, xt],
                [0, yz, yt],
                [0, 0, 2*zz+zt],
                [0, 0, 1]]))
    # that there can be only one ellipsis
    yield assert_raises(ValueError, acm.__getitem__, (
            (Ellipsis,Ellipsis,2)))
    # that you can integer slice in all three dimensions, leaving only
    # the translation column
    sacm = acm[1,0,2]
    yield assert_array_almost_equal(sacm.coordmap.affine,
                             np.array([
                [xz+xt],
                [yt],
                [2*zz+zt],
                [1]]))
    # that anything other than an int, slice or Ellipsis is an error
    yield assert_raises(ValueError, acm.__getitem__, ([0,2],))
    yield assert_raises(ValueError, acm.__getitem__, (np.array([0,2]),))
Example #41
0
    def smooth(self, inimage, clean=False, is_fft=False):
        """ Apply smoothing to `inimage`

        Parameters
        ----------
        inimage : ``Image``
           The image to be smoothed.  Should be 3D.
        clean : bool, optional
           Should we call ``nan_to_num`` on the data before smoothing?
        is_fft : bool, optional
           Has the data already been fft'd?

        Returns
        -------
        s_image : `Image`
           New image, with smoothing applied
        """
        if inimage.ndim == 4:
            # we need to generalize which axis to iterate over.  By
            # default it should probably be the last.
            raise NotImplementedError('Smoothing volumes in a 4D series '
                                      'is broken, pending a rethink')
            _out = np.zeros(inimage.shape)
            # iterate over the first (0) axis - this is confusing - see
            # above
            nslice = inimage.shape[0]
        elif inimage.ndim == 3:
            nslice = 1
        else:
            raise NotImplementedError('expecting either 3 or 4-d image')
        in_data = inimage.get_data()
        for _slice in range(nslice):
            if in_data.ndim == 4:
                data = in_data[_slice]
            elif in_data.ndim == 3:
                data = in_data[:]
            if clean:
                data = np.nan_to_num(data)
            if not is_fft:
                data = self._presmooth(data)
            data *= self.fkernel
            data = fft.irfftn(data) / self.norms[self.normalization]
            gc.collect()
            _dslice = [slice(0, self.bshape[i], 1) for i in range(3)]
            if self.scale != 1:
                data = self.scale * data[_dslice]
            if self.location != 0.0:
                data += self.location
            gc.collect()
            # Write out data
            if in_data.ndim == 4:
                _out[_slice] = data
            else:
                _out = data
            _slice += 1
        gc.collect()
        _out = _out[[
            slice(self._kernel.shape[i] / 2,
                  self.bshape[i] + self._kernel.shape[i] / 2)
            for i in range(len(self.bshape))
        ]]
        if inimage.ndim == 3:
            return Image(_out, coordmap=self.coordmap)
        else:
            # This does not work as written.  See above
            concat_affine = AffineTransform.identity('concat')
            return Image(_out, coordmap=product(self.coordmap, concat_affine))
Example #42
0
 def __init__(self, function_domain, function_range, matrix):
     ndim = matrix.shape[0]
     T = np.identity(ndim+1, dtype=matrix.dtype)
     T[:-1,:-1] = matrix
     AffineTransform.__init__(self, function_domain, function_range, T)