Skip to content

Commit eeb5c26

Browse files
authored
Merge pull request #80 from yhuang43/master
add comments for Volume.resize() method
2 parents 393aab4 + 03b9a66 commit eeb5c26

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

surfa/image/framed.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,28 @@ def crop_to_bbox(self, margin=None, crop_like=None):
265265
else:
266266
return self[self.bbox(margin=margin)]
267267

268+
269+
"""
270+
surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() works differently.
271+
272+
surfa.Volume.resize() logic:
273+
1. keep the original image 'rotation' and 'center' parameters when computing the resampled image geom
274+
2. resampled image crs0 remains the same as originial image. This may cause all voxels to be interpolated
275+
3. force the originial and resampled image in the same RAS space when computing target-source vox2vox matrix
276+
4. by default, 'linear' interpolation method is used
277+
278+
MRIupsampledN()/MRIdownsampleN() logic:
279+
1. the RAS of a voxel is at the center of the voxel, so the image corner is located at CRS = [-.5 -.5 -.5]
280+
2. the center of the resampled image crs0 = -0.5 + 1.0 / (2 * factor) in originial image voxel space (generally used in FS code)
281+
3. the original and resampled images share the same RAS space (implicit)
282+
4. the resampled image p0ras can be computed as p0ras = aff_orig @ crs0
283+
5. re-compute the resampled image 'center' parameters after correcting p0ras of aff_resampled
284+
6. The way the offset/center is set up, some voxels will fall in the same spot as the original volume which means they will not have any interpolation effects.
285+
286+
The target vox2ras from surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() are different,
287+
but they share the same RAS space. Because the resulting target-source vox2vox is different, surfa.Volume.resize()
288+
interpolates the voxel values from locations that are different from MRIupsampledN()/MRIdownsampleN().
289+
"""
268290
def resize(self, voxsize, method='linear', copy=True):
269291
"""
270292
Reslice image to a specified voxel size.
@@ -304,6 +326,11 @@ def resize(self, voxsize, method='linear', copy=True):
304326
target_shape = np.asarray(self.geom.voxsize, dtype='float') * baseshape3D / voxsize
305327
target_shape = tuple(np.ceil(target_shape).astype(int))
306328

329+
"""
330+
'target_geom' is computed differently than freesurfer MRIupsampledN()/MRIdownsampleN().
331+
The resulting target-source vox2vox is different. surfa.Volume.resize() interpolates
332+
the voxel values from locations that are different from MRIupsampledN()/MRIdownsampleN()
333+
"""
307334
target_geom = ImageGeometry(
308335
shape=target_shape,
309336
voxsize=voxsize,

0 commit comments

Comments
 (0)