How to resize and save a slice from a nii file as a PNG image in Python?

  • Context: Python 
  • Thread starter Thread starter BRN
  • Start date Start date
  • Tags Tags
    File
Click For Summary

Discussion Overview

The discussion focuses on extracting a slice from a NIfTI (.nii) file, resizing it to 256x256 pixels, and saving it as a PNG image using Python. Participants explore issues related to image dimensions and the methods used for saving images.

Discussion Character

  • Technical explanation
  • Exploratory

Main Points Raised

  • One participant shares a code snippet for extracting and resizing a slice from a NIfTI file but encounters an issue where the saved PNG images do not have the expected dimensions of 256x256 pixels.
  • Another participant suggests checking the images in different viewers and questions whether the Image class has a save method, implying it might help with the issue.
  • A participant responds that while the Pillow Image class does have a save method, it does not support 32-bit images, leading to quality loss. They note that the images appear correct in size but have empty side bands.
  • One participant identifies that the issue was caused by the 'matshow()' function, which adds padding around the figure, and shares a revised code snippet that uses 'imsave()' instead to save the image without additional spaces.

Areas of Agreement / Disagreement

Participants express differing views on the behavior of the 'matshow()' function and its impact on image dimensions, with one participant resolving their issue while others continue to discuss potential solutions.

Contextual Notes

Some participants mention limitations related to image quality and the handling of 32-bit images, as well as the specific behavior of different image saving methods in Python.

BRN
Messages
107
Reaction score
10
Hello everyone,

I have to extract a slice from a nii files and resize it with dimensions 256x256. Once this is done, I have to save it as a PNG image.

This is my code:

[CODE lang="python" title="slice from nii file"]def img_from_nii(height, width, n_slice, label, in_path, temp_path):

filenames = os.listdir(in_path)

for i in range(len(filenames)):
mri_file = in_path + filenames
img_data = nib.load(mri_file).get_fdata()
img_data = np.transpose(img_data, (2, 1, 0))
slice_2D = Image.fromarray(img_data[:, :, n_slice]).resize((height, width))

resized_slice = plt.matshow(slice_2D, cmap = 'gray', fignum = 0)
plt.axis('off')
plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
plt.margins(0, 0)

plt.savefig(temp_path + label + '_ADNI_' + 'slc' + str(n_slice) + '_' + str(i + 1) + '.png')
plt.close()

print('dataset done!')[/CODE]

The problem is that PNG files are correctly created, but if you check the image size I do not get 256x256. How is it possible?

[CODE lang="python" title="check size"]
im = Image.open('./outputs/ADNI_png_temp/P_ADNI_slc150_3.png')

width, height = im.size

print('width:', width)
print('height:', height)[/CODE]

[CODE title="outputs"]
width: 432
height: 288
[/CODE]

How can I solve?

Thanks.
 
Technology news on Phys.org
Have you looked at the images in Paint or something? From memory savefig pads the images the same way show() does.

Doesn't the Image class have a save method? Have you tried that?
 
If as Image class you mean that of Pillow, yes there is the save method, but it does not support 32-bit images and I lose quality.

By opening the image with any reader, I see the image in the correct size 256x256, but I also have two completely empty side bands.

I believe that the save method of Matplotlib does not provide for the cropping.
 
Oops! I forgot to update this post ...:-p

The problem was given by the 'Mathshow ()' function that adds additional spaces around the figure even if the axes are hidden.

I solved this way:
[CODE lang="python" title="slice from nii file ok"]def img_from_nii(height, width, n_slice, label, in_path, temp_path):

filenames = os.listdir(in_path)

for i in range(len(filenames)):
mri_file = in_path + filenames
img_data = nib.load(mri_file).get_fdata()
img_data = np.transpose(img_data, (2, 1, 0))
slice_2D = Image.fromarray(img_data[:, :, n_slice]).resize((height, width), resample = Image.Resampling.LANCZOS)

plt.imsave(temp_path + label + '_ADNI_' + 'slc' + str(n_slice) + '_' + str(i + 1) + '.png', slice_2D)

plt.close()

print('ADNI ' + label + ' dataset done!')[/CODE]
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
5K