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 = Affine.from_params(in_names, out_names, np.identity(3)) img = Image(np.ones((100,90)), g) img[50:55,40:55] = 3. tcoordmap = Affine.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))
def test_rotate2d2(): # Rotate an image in 2d on a non-square grid, # should result in transposed image g = Affine.from_params('ij', 'xy', np.diag([0.7,0.5,1])) g2 = Affine.from_params('ij', 'xy', np.diag([0.5,0.7,1])) i = Image(np.ones((100,80)), g) i[50:55,40:55] = 3. 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
def test_rotate3d(): # Rotate / transpose a 3d image on a non-square grid g = Affine.from_params('ijk', 'xyz', np.diag([0.5,0.6,0.7,1])) g2 = Affine.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. 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)) yield assert_array_almost_equal, np.transpose(np.asarray(ir), (0,2,1)), i
def test_resample2d3(): # Same as test_resample2d, only a different way of specifying # the transform: here it is an (A,b) pair g = Affine.from_params('ij', 'xy', np.diag([0.5,0.5,1])) i = Image(np.ones((100,90)), g) i[50:55,40:55] = 3. a = np.identity(3) a[:2,-1] = 4. ir = resample(i, i.coordmap, a, (100,90)) yield assert_array_almost_equal, ir[42:47,32:47], 3.
def test_resample2d2(): g = Affine.from_params('ij', 'xy', np.diag([0.5,0.5,1])) i = Image(np.ones((100,90)), g) i[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)) yield assert_array_almost_equal, ir[42:47,32:47], 3.
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 = Affine.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]),))
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 = Affine.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) 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])
def test_rotate2d3(): # Another way to rotate/transpose the image, similar to # test_rotate2d2 and test_rotate2d except the output_coords of the # output coordmap are the same as the output_coords 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 = Affine.from_params('xy', 'ij', np.diag([0.5,0.7,1])) i = Image(np.ones((100,80)), g) i[50:55,40:55] = 3. a = np.identity(3) g2 = Affine.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
def test_resample2d1(): # Tests the same as test_resample2d, only using a callable instead of # an Affine instance g = Affine.from_params('ij', 'xy', np.diag([0.5,0.5,1])) i = Image(np.ones((100,90)), g) i[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)) yield assert_array_almost_equal, ir[42:47,32:47], 3.
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 = Affine.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)
def test_resample3d(): g = Affine.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. # 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.
def test_resample2d(): g = Affine.from_params('ij', 'xy', np.diag([0.5,0.5,1])) i = Image(np.ones((100,90)), g) i[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)) yield assert_array_almost_equal, ir[42:47,32:47], 3.
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 = Affine.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), (0,39.5), i.coordmap.output_coords, (90,80)) ir = resample(i, zsl.coordmap, a, zsl.shape) yield assert_true, np.allclose(np.asarray(ir), np.asarray(i[53])) ysl = slices.yslice(22, (0,49.5), (0,39.5), i.coordmap.output_coords, (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.coordmap.output_coords, (100,90)) ir = resample(i, xsl.coordmap, a, xsl.shape) yield assert_true, np.allclose(np.asarray(ir), np.asarray(i[:,:,32]))
################################################################################ # 1) Create a CoordinateMap from the affine transform which specifies # the mapping from input to output coordinates. # Specify the axis order of the input coordinates input_coords = ['k', 'j', 'i'] output_coords = ['z','y','x'] #or innames = ('kji') outnames = ('zyx') # either way works # Build a CoordinateMap to create the image with affine_coordmap = Affine.from_params(innames, outnames, affine_array) # 2) Create a nipy image from the array and CoordinateMap # Create new image newimg = fromarray(arr, innames=innames, outnames=outnames, coordmap=affine_coordmap) ################################################################################ # END HERE, for testing purposes only. ################################################################################ # Imports used just for development and testing. Users typically # would not uses these when creating an image. from tempfile import mkstemp from nipy.testing import assert_equal