我有一个4D .nii文件,如" filtered_func_data.nii"来自:[https://nifti.nimh.nih.gov/nifti-1/data]
通过加载数据并访问img字段:
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
,大小为:
size(A)
回答=
64 64 21 180
因此,数据由64x64图像组成,深度/切片数为21,帧数为180。 有人可以帮我把这个.nii数据转换成21 * 180 = 3780 png图像,大小为64 * 64吗?另外,我想删除每个时间段的最后10个切片。
答案 0 :(得分:1)
首先,您可以按indexing the array删除最后10个图像卷,如下所示:
A = A(:, :, :, 1:170);
您还希望将数据从16-bit signed integers转换为16-bit unsigned integers,因为PNG文件不支持int16
(作为评论中的错误消息)显示)。我对这类医学图像的体验是,绝大多数图像数据位于正范围内,并且有一些虚假的负像素值,因此您可能只需将负值归零并转换为{ {3}}(您可能希望查看像素值的直方图以确定):
A = uint16(A); % Convert to unsigned, zeroing out negative values
现在,当您创建所有PNG图像时,您可能希望生成一个文件名,其中包含切片和时间索引,以便您可以更轻松地识别和排序它们。您可以遍历每个64 x 64图像,使用unsigned integer生成文件名,并使用sprintf
创建图像,如下所示:
[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
如果您想减少生成的文件数量,可以将每个图像卷的21个切片收集到5 x 5马赛克中,为您提供一个更大的图像(320-by- 320)每个时间点。您可以使用imwrite
,cell arrays和mat2cell
执行以下操作:
[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