我的名字是Lorenzo,我是意大利的博士后研究员。我的工作与使用同步辐射的断层摄影成像有关。这对我来说是一个新领域,我开始面对Matlab编写一些代码。
我是断层扫描成像的新手,Matlab为我展示了新的挑战。 我的实际问题是从堆叠的平行图像投影创建正弦图。 对于不在该领域的人,正弦图是检测样本中特征位置的探测器上的投影的映射,作为X射线束与样本之间角度的函数。
我从实验中得到的是一系列不同角度的二维放射成像,你可以看到它是一个矩形的"体积"其中尺寸分别是单个投影中的行数和列数,而体积是从角度数给出的。正弦图只是这个体积的横向切割。这意味着不是从侧面而是从顶部读取体积,因此我将创建一个新的图像阵列,其尺寸是列数和投影数,并且数组长度为投影中的行数。 为了给出这个实验中的数字,我有4000个投影,大小为2048x1370像素,所以对于我的计算机技能来说,这是一个巨大的计算问题。
我需要你的帮助才能更快地执行某些操作。 我在第一部分的代码分配一个数组来包含所有图像,这是一个34 Gb数组,但我有130 Gb RAM,所以没问题。执行此操作的代码使用imread循环:
for i=2:num_proj
filename=strcat(path_im,list_proj(i).name);
image=imread(filename);
imArray(:,:,i)=image;
end
这不是最快的方法,现在创建这个阵列需要332秒。我找到了几种解决方案来改善这一点,我会这样做。
第二步是划分平场(没有样本拍摄的图像)。 我的代码采用平面并使用imdivide将数组中的每个图像划分为平面图像:
for i=1:size(imArray, 3);
imArray(:,:,i)=imdivide(imArray(:,:,i), flat);
end
这一步似乎很快,但它被称为4000次。你有什么建议吗?有没有更好的方法来执行它?
现在我最大的问题是如何以最快的方式拍摄投影体中的水平切割? 我的基本想法是从" top"中读取音量。如下所述,它确实起作用,但需要很长时间:
for i=1:size(sinogram, 3)
for k=1:size(sinogram, 1)
sinogram(k,:,i)=imArray(i,:,k);
end
end
你能帮助我加快这项手术吗? 我希望我的问题很清楚,否则请问,我会尽力解释一下。
答案 0 :(得分:0)
你最终找到了你想要的答案吗?我将在这里介绍一些以供将来参考:
for i=2:num_proj
filename=strcat(path_im,list_proj(i).name);
image=imread(filename);
imArray(:,:,i)=image;
end
改善第一个循环:
预分配在MATLAB中至关重要。如果动态分配图像,MATLAB必须在每次向其添加图像时创建新的imArray。我假设你已经这样做,因为循环从2开始并且相当快。如果没有,你应该调查一下。
parfor 可用于在一定程度上加速imread。根据我的经验,imread似乎通常是I / O有限,但我已经看到使用它的收益。
对于我在具有快速ssd(假设CPU限制)的相当旧的双核笔记本电脑上的100张图像的基准测试:
imArray = cell([100,1])
parfor i=1:100
imArray{i} = imread(filenames{i})
end
imArray = cat(3, imArray{:});
花了47.506717秒。
VS。连续形式:
firstI = imread(files{1});
imArray = zeros(size(firstI,1),size(firstI,2),100, 'uint8');
imArray(:,:,1) = firstI;
for i=2:100
imArray(:,:,i)=imread(filenames{i})
end
其中耗时55.928427秒。但是,您的情况可能不会像这样。您甚至可能会看到由于第一次启动parpool和在以后的运行中分配工作人员而导致的高额管理费用造成的损失。根据您的工作,可能值得一试。我只是在第一次运行后将我的CT数据集保存在mat文件中,使用它们要快得多。
除以平场:
由于MATLAB现在使用JIT编译器,矢量化可能很费力,有时收益甚微。但是,在某些情况下,它仍然可以提供帮助,而且这里只有一个函数调用:
for i=1:size(imArray, 3);
imArray(:,:,i)=imdivide(imArray(:,:,i), flat);
end
花了3.809438秒
虽然:
imArray = imArray ./ repmat(flat,1,1,size(imArray,3));
耗时1.268413秒
甚至更好:
imArray = bsxfun(@rdivide, imArray, flat);
花了0.970662秒
出于某种原因,bsxfun似乎很受欢迎。它默认是多线程的。正弦图:
您只是在这里切换尺寸吗?如果是这样,请尝试:
sinogram = permute(imArray, [3,2,1]);