将 4D .nii 文件转换为 .png

convert 4D .nii file to .png

我有一个类似 "filtered_func_data.nii" 的 4D .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 图像组成,depth/number 切片为 21,帧数为 180。 有人可以帮我将这个 .nii 数据转换为 21*180= 3780 png 图像,大小为 64*64 吗?另外,我想删除每个时间段的最后 10 个切片。

首先,您可以通过 indexing the array 删除最后 10 个图像卷,如下所示:

A = A(:, :, :, 1:170);

您还需要转换来自 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 的数据(您可能需要查看像素值的直方图以确保):

A = uint16(A);  % Convert to unsigned, zeroing out negative values

现在,当您创建所有 PNG 图像时,您可能希望生成一个包含切片和时间索引的文件名,以便您可以更轻松地识别和排序它们。您可以遍历每个 64×64 图像,使用 sprintf and using imwrite 生成文件名来创建图像,如下所示:

[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×5 的马赛克中,从而得到一个更大的图像(320×- 320) 每个时间点。您可以按如下方式执行此操作,使用 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