Применять (с как можно меньшим количеством циклов) функцию к заданным элементам / вокселям (x,y,z), взятым из подполей нескольких структур (нифти) в MATLAB?
У меня есть набор данных n nifti (.nii) изображений. В идеале я хотел бы иметь возможность получить значение одного и того же вокселя / элемента для каждого изображения и применить функцию к n точкам данных. Я хотел бы сделать это для каждого вокселя / элемента по всему изображению, чтобы я мог преобразовать результат обратно в формат.nii.
Я использовал инструменты для инструментов NIfTI и ANALYZE для загрузки изображений:
data(1)=load_nii('C:\file1.nii');
data(2)=load_nii('C:\file2.nii');
...
data(n)=load_nii('C:\filen.nii');
Из которого я получаю объект структуры с каждым подполем, содержащим один загруженный nifti. У каждого из них есть подполе 'img', соответствующее данным изображения, над которыми я хочу работать. Проблема заключается в попытке выбрать данный xyz в каждом поле img data(1) для data(n). Как я обнаружил, невозможно выбрать таким образом:
data(:).img(x,y,z)
или же
data(1:n).img(x,y,z)
потому что Matlab не поддерживает это. Содержимое первых скобок должно быть скалярным для вызова работы. Решение от поиска в Google, похоже, представляет собой цикл, который создает временную переменную:
for z = 1:nz
for x = 1:nx
for y = 1:ny
for i=1:n;
points(i)=data(i).img(x,y,z);
end
[p1(x,y,z,:),~,p2(x,y,z)] = fit_data(a,points,b);
end
end
end
который работает, но занимает слишком много времени (несколько дней) для одного набора изображений, учитывая размер nx, ny, nz (несколько сотен каждый).
Я искал решение для ускорения кода, который, я считаю, зависит от удаления этих циклов путем векторизации, предварительного выбора полей img (через getfield?) И их конкатенации, а также применения чего-то вроде arrayfun / cellfun / structfun, но я Честно говоря, немного растерялся, как это сделать. Я могу только думать о способах предварительного выбора, для которых самим требуются циклы, что, кажется, лишает цели упражнения (хотя решение с меньшим количеством циклов или, по меньшей мере, меньшим количеством вложенных циклов, может сделать это), или увлекаться той же проблемой это вызывает как данные (:).img(x,y,z) не работает. поиск в Google снова приводит к выбору и объединению полей внутри структуры или заданного поля в нескольких структурах. Но я не могу найти ничего для моей проблемы: выберите элемент из нескалярного подполя в подструктуре объекта структуры (с минимумом циклов). Наконец, мне нужно, чтобы выходные данные были в форме матрицы, которую приведенный выше набор инструментов может превратить в нифти.
Любые предложения, подсказки, подсказки и помощь очень ценятся!
1 ответ
Вы можете объединять изображения в виде 4D-массива и использовать линейные индексы для ускорения вычислений:
img = cat(4,data.img);
p1 = zeros(nx,ny,nz,n);
p2 = zeros(nx,ny,nz);
sz = ny*nx*nz;
for k = 1 : sz
points = img(k:sz:end);
[p1(k:sz:end),~,p2(k)] = fit_data(a,points,b);
end