преобразовать файл 4D .nii в .png

У меня есть файл 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 фрагментов каждого временного курса.


person user1603454    schedule 03.08.2017    source источник


Ответы (1)


Во-первых, вы можете удалить последние 10 томов изображений с помощью индексации массив вот так:

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

Вы также можете преобразовать свои данные из 16-битных signed< /em> целые числа в 16-разрядные без знака целые числа, так как int16 не поддерживается для файлов PNG (как показывает сообщение об ошибке в вашем комментарии). Мой опыт работы с такими медицинскими изображениями состоит в том, что подавляющее большинство данных изображения находится в положительном диапазоне с несколькими ложными отрицательными значениями пикселей, поэтому вам, вероятно, будет достаточно просто обнулить отрицательные значения и преобразовать в целое число без знака (вы можете посмотреть на гистограмму ваших значений пикселей, чтобы Конечно):

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

Теперь, когда вы создаете все свои PNG-изображения, вы, вероятно, захотите сгенерировать имя файла, в котором будут индексы среза и времени, чтобы вам было легче их идентифицировать и сортировать. Вы можете просмотреть каждое изображение 64 на 64, сгенерировав имя файла, используя sprintf и с помощью 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) на момент времени. . Вы можете сделать это следующим образом, используя массивы ячеек, mat2cell и 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
person gnovice    schedule 03.08.2017
comment
Спасибо за ваш ответ. Я попробовал это, и это дало мне эту ошибку: Предупреждение: потеря данных и неожиданные результаты могут произойти с подписанными данными пикселей. › В imwrite (строка 447) Ошибка при использовании writepng›parseInputs (строка 290) Ожидаемый ввод будет одного из следующих типов: double, single, logical, uint8, uint16 Вместо этого его тип был int16. Ошибка в writepng (строка 20) [результаты, несоответствующие] = parseInputs(data,map,filename,varargin{:}); Ошибка в imwrite (строка 472) feval(fmt_s.write, -- и она не создала никакого png-файла, а имя_файла — это просто вектор 1*26 с одной ячейкой, заполненной filtered_func_data_1_1.png - person user1603454; 03.08.2017
comment
@ user1603454: я обновил ответ, чтобы устранить ошибку. - person gnovice; 03.08.2017