Skip to content

add comments for Volume.resize() method#80

Merged
jnolan14 merged 1 commit into
freesurfer:masterfrom
yhuang43:master
Jun 29, 2026
Merged

add comments for Volume.resize() method#80
jnolan14 merged 1 commit into
freesurfer:masterfrom
yhuang43:master

Conversation

@yhuang43

Copy link
Copy Markdown
Contributor
surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() works differently.

surfa.Volume.resize() logic:
1. keep the original image 'rotation' and 'center' parameters when computing the resampled image geom
2. resampled image crs0 remains the same as originial image. This may cause all voxels to be interpolated
3. force the originial and resampled image in the same RAS space when computing target-source vox2vox matrix
4. by default, 'linear' interpolation method is used

MRIupsampledN()/MRIdownsampleN() logic:
1. the RAS of a voxel is at the center of the voxel, so the image corner is located at CRS = [-.5 -.5 -.5]
2. the center of the resampled image crs0 = -0.5 + 1.0 / (2 * factor) in originial image voxel space (generally used in FS code)
3. the original and resampled images share the same RAS space (implicit)
4. the resampled image p0ras can be computed as p0ras = aff_orig @ crs0
5. re-compute the resampled image 'center' parameters after correcting p0ras of aff_resampled
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.

The target vox2ras from surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() are different,
but they share the same RAS space. Because the resulting target-source vox2vox is different, surfa.Volume.resize()
interpolates the voxel values from locations that are different from MRIupsampledN()/MRIdownsampleN().

    surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() works differently.

    surfa.Volume.resize() logic:
    1. keep the original image 'rotation' and 'center' parameters when computing the resampled image geom
    2. resampled image crs0 remains the same as originial image. This may cause all voxels to be interpolated
    3. force the originial and resampled image in the same RAS space when computing target-source vox2vox matrix
    4. by default, 'linear' interpolation method is used

    MRIupsampledN()/MRIdownsampleN() logic:
    1. the RAS of a voxel is at the center of the voxel, so the image corner is located at CRS = [-.5 -.5 -.5]
    2. the center of the resampled image crs0 = -0.5 + 1.0 / (2 * factor) in originial image voxel space (generally used in FS code)
    3. the original and resampled images share the same RAS space (implicit)
    4. the resampled image p0ras can be computed as p0ras = aff_orig @ crs0
    5. re-compute the resampled image 'center' parameters after correcting p0ras of aff_resampled
    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.

    The target vox2ras from surfa.Volume.resize() and freesurfer MRIupsampledN()/MRIdownsampleN() are different,
    but they share the same RAS space. Because the resulting target-source vox2vox is different, surfa.Volume.resize()
    interpolates the voxel values from locations that are different from MRIupsampledN()/MRIdownsampleN().
@yhuang43 yhuang43 requested a review from jnolan14 June 23, 2026 13:03
@jnolan14 jnolan14 merged commit eeb5c26 into freesurfer:master Jun 29, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants