Reputation: 99
I have a 4D .nii file like "filtered_func_data.nii" from: [https://nifti.nimh.nih.gov/nifti-1/data]
By loading the data and access the img field:
S = load_nii('filtered_func_data.nii')
S =
hdr: [1x1 struct]
filetype: 2
fileprefix: 'filtered_func_data'
machine: 'ieee-be'
img: [4-D int16]
original: [1x1 struct]
A = S.img
with size of:
size(A)
answer =
64 64 21 180
So the data consists of 64x64 images with a depth/number of slices of 21 and a number of frames of 180. Can someone please help me to convert this .nii data to 21*180= 3780 png images with the size of 64*64? Also, I want to remove the last 10 slices of each time course.
Upvotes: 2
Views: 1283
Reputation: 125854
Firstly, you can remove the last 10 image volumes by indexing the array like so:
A = A(:, :, :, 1:170);
You'll also want to convert your data from 16-bit signed integers to 16-bit unsigned integers, since int16
isn't supported for PNG files (as the error message in your comment shows). My experience with medical images like this is that the vast majority of the image data lies in the positive range, with a few spurious negative pixel values, so you'd probably be fine just zeroing out the negative values and converting to an unsigned integer (you may want to look at a histogram of your pixel values to be sure):
A = uint16(A); % Convert to unsigned, zeroing out negative values
Now, when you create all of your PNG images, you'll probably want to generate a file name that has the slice and time indices in it so you can identify and sort them easier. You can loop over every 64-by-64 image, generating a file name using sprintf
and using imwrite
to create the image like so:
[nRows, nCols, nSlices, nTimes] = size(A);
for iSlice = 1:nSlices
for iTime = 1:nTimes
fileName = sprintf('%s_%d_%d.png', S.fileprefix, iSlice, iTime);
imwrite(A(:, :, iSlice, iTime), fileName);
end
end
If you'd like to cut down on the number of files you generate, you could collect the 21 slices of each image volume into a 5-by-5 mosaic, giving you one larger image (320-by-320) per time point. You can do this as follows, using cell arrays, mat2cell
and cell2mat
:
[nRows, nCols, nSlices, nTimes] = size(A);
for iTime = 1:nTimes
C = cat(3, A(:, :, :, iTime), zeros(nRows, nCols, 4)); % Pad with 4 empty slices
C = mat2cell(C, nRows, nCols, ones(1, 25)); % Place each slice in a cell
C = cell2mat(reshape(C, 5, 5).'); % Reshape cell array and make mosaic
fileName = sprintf('%s_%d_.png', S.fileprefix, iTime);
imwrite(C, fileName);
end
Upvotes: 1