Применять (с как можно меньшим количеством циклов) функцию к заданным элементам / вокселям (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
Другие вопросы по тегам