在MATLAB中从多个结构(nifti)的子场中取出给定元素/体素(x,y,z)的函数(尽可能少的循环)?

时间:2018-04-23 15:55:07

标签: matlab imaging nifti

我有一个n nifti(.nii)图像的数据集。理想情况下,我希望能够从每个图像中获取相同体素/元素的值,并将函数应用于n个数据点。我想为整个图像中的每个体素/元素执行此操作,以便我可以将结果重新转换回.nii格式。

我已使用Tools for NIfTI and ANALYZE image toolbox加载我的图片:

data(1)=load_nii('C:\file1.nii');
data(2)=load_nii('C:\file2.nii');
...
data(n)=load_nii('C:\filen.nii');

我从中获取一个struct对象,每个子字段包含一个加载的nifti。这些中的每一个都有一个子域'img',对应于我想要处理的图像数据。问题来自于尝试在每个img字段的数据(1)到数据(n)中选择给定的xyz。正如我发现的那样,不可能以这种方式选择:

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)不起作用。谷歌再次搜索是如何选择和连接结构中的字段,或跨多个结构的给定字段。但是我找不到任何问题:从结构对象的子结构中的非标量子字段中选择一个元素(使用最少的循环)。最后,我需要输出为矩阵的形式,上面的工具箱可以变成一个nifti。

任何和所有建议,线索,提示和帮助非常感谢!

1 个答案:

答案 0 :(得分:0)

您可以将图像连接为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