def test_checked_values(): cs = CoordinateSystem('ijk', name='voxels', coord_dtype=np.float32) x = np.array([1, 2, 3], dtype=np.int16) xc = cs._checked_values(x) yield np.allclose, xc, x # wrong shape yield assert_raises, ValueError, cs._checked_values, x.reshape(3,1) # wrong length yield assert_raises, ValueError, cs._checked_values, x[0:2] # wrong dtype x = np.array([1,2,3], dtype=np.float64) yield assert_raises, ValueError, cs._checked_values, x
def resample_image(input_image, new_size, new_size_type, interpolation='linear', verbose=1): """This function will resample the specified input image to the target size. :param input_image: The input image. :param new_size: The target size, i.e. '0.25x0.25' :param new_size_type: Unit of resample (mm, vox, factor) :param interpolation: The interpolation type :param verbose: Verbosity level :return: The resampled image. """ data = input_image.get_data() # Get dimensions of data p = input_image.header.get_zooms() n = input_image.header.get_data_shape() sct.printv(' pixdim: ' + str(p), verbose) sct.printv(' shape: ' + str(n), verbose) # Calculate new dimensions sct.printv('\nCalculate new dimensions...', verbose) # parse input argument new_size = new_size.split('x') # if 4d, add resampling factor to 4th dimension if len(p) == 4: new_size.append('1') # compute new shape based on specific resampling method if new_size_type == 'vox': n_r = tuple([int(new_size[i]) for i in range(len(n))]) elif new_size_type == 'factor': if len(new_size) == 1: # isotropic resampling new_size = tuple([new_size[0] for i in range(len(n))]) # compute new shape as: n_r = n * f n_r = tuple( [int(round(n[i] * float(new_size[i]))) for i in range(len(n))]) elif new_size_type == 'mm': if len(new_size) == 1: # isotropic resampling new_size = tuple([new_size[0] for i in range(len(n))]) # compute new shape as: n_r = n * (p_r / p) n_r = tuple([ int(round(n[i] * float(p[i]) / float(new_size[i]))) for i in range(len(n)) ]) else: sct.printv('\nERROR: new_size_type is not recognized.', 1, 'error') sct.printv(' new shape: ' + str(n_r), verbose) affine = input_image.coordmap.affine sct.printv(' affine matrix: \n' + str(affine)) # create ref image arr_r = np.zeros(n_r) R = np.eye(len(n) + 1) for i in range(len(n)): R[i, i] = n[i] / float(n_r[i]) affine_r = np.dot(affine, R) coordmap_r = input_image.coordmap coordmap_r.affine = affine_r nii_r = nipy.core.api.Image(arr_r, coordmap_r) sct.printv('\nCalculate affine transformation...', verbose) # create affine transformation transfo = R # if data are 4d, delete temporal dimension if len(p) == 4: transfo = np.delete(transfo, 3, 0) transfo = np.delete(transfo, 3, 1) # translate to account for voxel size (otherwise resulting image will be shifted by half a voxel). Modify the three first rows of the last column, corresponding to the translation. transfo[:3, -1] = np.array( ((R[0, 0] - 1) / 2, (R[1, 1] - 1) / 2, (R[2, 2] - 1) / 2), dtype='f8') sct.printv(' transfo: \n' + str(transfo), verbose) # set interpolation method if interpolation == 'nn': interp_order = 0 elif interpolation == 'linear': interp_order = 1 elif interpolation == 'spline': interp_order = 2 # create 3d coordmap because resample only accepts 3d data (jcohenadad 2016-07-26) if len(n) == 4: coordmap3d = copy.deepcopy(input_image.coordmap) from nipy.core.reference.coordinate_system import CoordinateSystem coordmap3d.function_domain = CoordinateSystem('xyz') # create 3d affine transfo affine3d = np.delete(affine, 3, 0) affine3d = np.delete(affine3d, 3, 1) coordmap3d.affine = affine3d # resample data if len(n) == 3: data_r = n_resample(input_image, transform=transfo, reference=nii_r, mov_voxel_coords=True, ref_voxel_coords=True, dtype='double', interp_order=interp_order, mode='nearest') elif len(n) == 4: data_r = np.zeros(n_r) # loop across 4th dimension for it in range(n[3]): # create 3d nipy-like data arr3d = data[:, :, :, it] nii3d = nipy.core.api.Image(arr3d, coordmap3d) arr_r3d = arr_r[:, :, :, it] nii_r3d = nipy.core.api.Image(arr_r3d, coordmap3d) # resample data data3d_r = n_resample(nii3d, transform=transfo, reference=nii_r3d, mov_voxel_coords=True, ref_voxel_coords=True, dtype='double', interp_order=interp_order, mode='nearest') data_r[:, :, :, it] = data3d_r.get_data() nii_r = nipy.core.api.Image(data_r, coordmap_r) return nii_r
def test_index(): cs = CoordinateSystem('ijk') yield assert_equal, cs.index('i'), 0 yield assert_equal, cs.index('j'), 1 yield assert_equal, cs.index('k'), 2 yield assert_raises, ValueError, cs.index, 'x'
def resample(): """ Resample data using nipy. Note: we cannot use msct_image because coordmap needs to be used. :return: """ import nipy from nipy.algorithms.registration.resample import resample import numpy as np verbose = param.verbose # Load data sct.printv('\nLoad data...', verbose) nii = nipy.load_image(param.fname_data) data = nii.get_data() # Get dimensions of data p = nii.header.get_zooms() n = nii.header.get_data_shape() sct.printv(' pixdim: ' + str(p), verbose) sct.printv(' shape: ' + str(n), verbose) # Calculate new dimensions sct.printv('\nCalculate new dimensions...', verbose) # parse input argument new_size = param.new_size.split('x') # if 4d, add resampling factor to 4th dimension if len(p) == 4: new_size.append('1') # compute new shape based on specific resampling method if param.new_size_type == 'vox': n_r = tuple([int(new_size[i]) for i in range(len(n))]) elif param.new_size_type == 'factor': if len(new_size) == 1: # isotropic resampling new_size = tuple([new_size[0] for i in range(len(n))]) # compute new shape as: n_r = n * f n_r = tuple([int(round(n[i] * float(new_size[i]))) for i in range(len(n))]) elif param.new_size_type == 'mm': if len(new_size) == 1: # isotropic resampling new_size = tuple([new_size[0] for i in range(len(n))]) # compute new shape as: n_r = n * (p_r / p) n_r = tuple([int(round(n[i] * float(p[i]) / float(new_size[i]))) for i in range(len(n))]) else: sct.printv('\nERROR: param.new_size_type is not recognized.', 1, 'error') sct.printv(' new shape: ' + str(n_r), verbose) # get_base_affine() affine = nii.coordmap.affine # if len(p) == 4: # affine = np.delete(affine, 3, 0) # affine = np.delete(affine, 3, 1) sct.printv(' affine matrix: \n' + str(affine)) # create ref image arr_r = np.zeros(n_r) R = np.eye(len(n) + 1) for i in range(len(n)): R[i, i] = n[i] / float(n_r[i]) affine_r = np.dot(affine, R) coordmap_r = nii.coordmap coordmap_r.affine = affine_r nii_r = nipy.core.api.Image(arr_r, coordmap_r) sct.printv('\nCalculate affine transformation...', verbose) # create affine transformation transfo = R # if data are 4d, delete temporal dimension if len(p) == 4: transfo = np.delete(transfo, 3, 0) transfo = np.delete(transfo, 3, 1) # translate to account for voxel size (otherwise resulting image will be shifted by half a voxel). Modify the three first rows of the last column, corresponding to the translation. transfo[:3, -1] = np.array(((R[0, 0] - 1) / 2, (R[1, 1] - 1) / 2, (R[2, 2] - 1) / 2), dtype='f8') # sct.printv(transfo) sct.printv(' transfo: \n' + str(transfo), verbose) # set interpolation method if param.interpolation == 'nn': interp_order = 0 elif param.interpolation == 'linear': interp_order = 1 elif param.interpolation == 'spline': interp_order = 2 # create 3d coordmap because resample only accepts 3d data (jcohenadad 2016-07-26) if len(n) == 4: from copy import deepcopy coordmap3d = deepcopy(nii.coordmap) from nipy.core.reference.coordinate_system import CoordinateSystem coordmap3d.__setattr__('function_domain', CoordinateSystem('xyz')) # create 3d affine transfo affine3d = np.delete(affine, 3, 0) affine3d = np.delete(affine3d, 3, 1) coordmap3d.affine = affine3d # resample data if len(n) == 3: data_r = resample(nii, transform=transfo, reference=nii_r, mov_voxel_coords=True, ref_voxel_coords=True, dtype='double', interp_order=interp_order, mode='nearest') elif len(n) == 4: data_r = np.zeros(n_r) # data_r = np.zeros(n_r[0:3]) # data_r = np.expand_dims(data_r, 3) # loop across 4th dimension for it in range(n[3]): # create 3d nipy-like data arr3d = data[:, :, :, it] nii3d = nipy.core.api.Image(arr3d, coordmap3d) arr_r3d = arr_r[:, :, :, it] nii_r3d = nipy.core.api.Image(arr_r3d, coordmap3d) # resample data data3d_r = resample(nii3d, transform=transfo, reference=nii_r3d, mov_voxel_coords=True, ref_voxel_coords=True, dtype='double', interp_order=interp_order, mode='nearest') # data_r = np.concatenate((data_r, data3d_r), axis=3) data_r[:, :, :, it] = data3d_r.get_data() # build output file name if param.fname_out == '': fname_out = sct.add_suffix(param.fname_data, '_r') else: fname_out = param.fname_out # save data nii_r = nipy.core.api.Image(data_r, coordmap_r) nipy.save_image(nii_r, fname_out) # to view results sct.printv('\nDone! To view results, type:', verbose) sct.printv('fslview ' + fname_out + ' &', verbose, 'info') # new_im = Image(param=new_data) # new_im.absolutepath = param.fname_out # new_im.path = path_out # new_im.file_name = file_out # new_im.ext = ext_out # zooms_to_set = list(new_zooms) # if dim == 4: # zooms_to_set.append(nt) # new_im.hdr = input_im.hdr # new_im.hdr.set_zooms(zooms_to_set) # Set the new sform and qform: # new_im.hdr.set_sform(new_affine) # new_im.hdr.set_qform(new_affine) # # new_im.save() # extract resampling factor # sct.printv('\nParse resampling factor...', param.verbose) # new_size_split = param.new_size.split('x') # new_size = [float(new_size_split[i]) for i in range(len(new_size_split))] # # check if it has three values # if not len(new_size) == 3: # sct.printv('\nERROR: new size should have three dimensions. E.g., 2x2x1.\n', 1, 'error') # else: # ns_x, ns_y, ns_z = new_size # # # Extract path/file/extension # path_data, file_data, ext_data = sct.extract_fname(param.fname_data) # path_out, file_out, ext_out = '', file_data, ext_data # else: # file_out += param.file_suffix # param.fname_out = path_out+file_out+ext_out # # input_im = Image(param.fname_data) # import numpy as np # affine_new = np.array([[2., 0., 0., 1], # [0., 2., 0., 1], # [0., 0., 2., 0], # [0., 0., 0., 1.]]) # import nibabel # img = nibabel.Nifti1Image(input_im.data, affine=affine_new) # from nilearn.image import resample_img # new_data = resample_img(img, target_affine=np.eye(4), target_shape=(60, 60, 27)) # sct.printv(new_data.shape) # display # from matplotlib.pylab import * # matshow(data[:, :, 15], cmap=cm.gray), show() # matshow(data_r[:, :, 15], cmap=cm.gray), show() # # translate before interpolation to account for voxel size # from skimage import transform # transform.resize() # # # zooms = (px, py, pz) # input_im.hdr.get_zooms()[:3] # affine = input_im.hdr.get_qform() # get_base_affine() # new_zooms = (px_new, py_new, pz_new) # # if type(param.interpolation) == int: # order = param.interpolation # elif type(param.interpolation) == str and param.interpolation in param.x_to_order.keys(): # order = param.x_to_order[param.interpolation] # else: # order = 1 # sct.printv('WARNING: wrong input for the interpolation. Using default value = linear', param.verbose, 'warning') import numpy as np