Skip to content

Commit

Permalink
python: support 2D image reslicing
Browse files Browse the repository at this point in the history
  • Loading branch information
ahoopes committed Apr 23, 2020
1 parent 862dd6d commit 03e5f68
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
18 changes: 14 additions & 4 deletions python/bindings/utils/volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ void Bridge::transferParameters(py::object& pyobj)
// grab number of basedims
const int ndims = pyobj.attr("basedims").cast<int>();

// extract resolution
if (ndims == 2) pyobj.attr("pixsize") = py::make_tuple(p_mri->xsize, p_mri->ysize);
if (ndims == 3) pyobj.attr("voxsize") = py::make_tuple(p_mri->xsize, p_mri->ysize, p_mri->zsize);

// extract the affine transform if it's an image or volume
if ((ndims == 2) || (ndims == 3)) {
pyobj.attr("voxsize") = py::make_tuple(p_mri->xsize, p_mri->ysize, p_mri->zsize);
if (p_mri->ras_good_flag == 1) {
MATRIX *matrix = extract_i_to_r(p_mri.get());
py::array affine = copyArray({4, 4}, MemoryOrder::C, matrix->data);
Expand Down Expand Up @@ -187,14 +190,21 @@ MRI* Bridge::mri()
mri->initSlices();
mri->initIndices();

if ((ndims == 2) || (ndims == 3)) {
// voxel size
// voxel size
if (ndims == 2) {
std::vector<float> pixsize = source.attr("pixsize").cast<std::vector<float>>();
mri->xsize = pixsize[0];
mri->ysize = pixsize[1];
mri->zsize = 1.0;
} else if (ndims == 3) {
std::vector<float> voxsize = source.attr("voxsize").cast<std::vector<float>>();
mri->xsize = voxsize[0];
mri->ysize = voxsize[1];
mri->zsize = voxsize[2];
}

// set the affine transform (must come after setting voxel size)
// set the affine transform (must come after setting voxel size)
if ((ndims == 2) || (ndims == 3)) {
py::object pyaffine = source.attr("affine");
if (pyaffine.is(py::none())) {
mri->ras_good_flag = 0;
Expand Down
42 changes: 39 additions & 3 deletions python/freesurfer/ndarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,52 @@ class Image(ArrayContainerTemplate, Transformable):
'''2D image with specific geometry.'''
basedims = 2

def __init__(self, data, affine=None):
def __init__(self, data, affine=None, pixsize=None):
'''Contructs an image from a 2D or 3D data array. The 3rd dimension is
always assumed to be the number of frames.'''
ArrayContainerTemplate.__init__(self, data)
self.affine = affine
self.voxsize = (1.0, 1.0, 1.0)
self.pixsize = pixsize if pixsize is not None else (1.0, 1.0)

def geometry(self):
'''Returns volume geometry as a `Geometry` instance.'''
return Geometry(self.shape, self.voxsize, self.affine)
return Geometry(self.shape, self.pixsize, self.affine)

def copy_geometry(self, image):
'''Copies pixsize and affine information from another image.'''
self.affine = image.affine
self.pixsize = image.pixsize

def reslice(self, pixsize, interp_method='linear', smooth_sigma=0):
'''
Returns the resampled image with a given resolution determined by pixel size in mm.
Parameters:
pixsize: Voxel size of target volume. Can be single value or list.
interp_method: Interpolation method. Must be 'linear' or 'nearest'. Default is 'linear'.
smooth_sigma: Apply gaussian smoothing before resampling (kernel size is
in voxel space). Default is 0.
'''

# convert single value to list
if not isinstance(pixsize, Iterable):
pixsize = [pixsize] * 2

# reshape image into '3D' array
src_shape_3d = (*self.shape[:2], 1)
if self.data.ndim != 2:
src_shape_3d = (*src_shape_3d, self.nframes)

# reslice the image as a 'volume'
src_vol = Volume(np.reshape(self.data, src_shape_3d), affine=self.affine, voxsize=(*self.pixsize[:2], 1.0))
trg_vol = src_vol.reslice((*pixsize[:2], 1.0), interp_method=interp_method, smooth_sigma=smooth_sigma)

# transfer back into image
trg_shape = trg_vol.shape[:2]
if self.data.ndim != 2:
trg_shape = (*trg_shape, self.nframes)
resliced_image = Image(np.reshape(trg_vol.data, trg_shape), affine=trg_vol.affine, pixsize=trg_vol.voxsize[:2])
return resliced_image


class Volume(ArrayContainerTemplate, Transformable):
Expand Down

0 comments on commit 03e5f68

Please sign in to comment.