我在matlab中定义了一个在真实比例(0,1)上定义的图像和一个在整数范围内定义的掩码。
实施例
mask = [ 1 1 1 3 4 ;
1 1 1 2 4 ;
1 1 2 2 2 ]
img = [ 0.1 0.1 0.2 0.2 0.3 ;
0.1 0.1 0.2 0.3 0.3 ;
0.1 0.1 0.3 0.3 0.3 ]
并且对于掩模中的每个区域(即1,2,3,4),我想在相应图像的强度上计算某个特征(比如平均值)。
我使用的算法是
for i = labels
region = img(mask==i);
feature(i) = mean(region);
end
现在,对于尺寸为300x400x500且图片集基数为>的图像,此算法非常慢。 40000(顺便说一句,顺便说一下,这是我的情况)。
有关如何加速我的代码的任何建议?
答案 0 :(得分:3)
图像处理工具箱中的regionprops功能应该为您完成。例如,使用以下语法:
stats = regionprops(L,I, 'MeanIntensity');
获取每个地区的平均值。 L是包含标签的数组。我是你的形象。
答案 1 :(得分:1)
bsxfun
和 fast matrix-multiplication
基于获取平均值的方法 -
num_labels = max(mask(:)); %// number of labels used
labels = 1:num_labels; %// array of all labels
%// Get a 2D mask for all labels, with each column representing a label.
%// This is a setup for use with matix-multiplication later on
mask_labels = bsxfun(@eq,mask(:),labels);
%// Perform fast matrix multiplication as a way to perform summation for
%// all labels and then do elementwise division to get the mean values
feature_out = (img(:)'*mask_labels)./sum(mask_labels,1);
答案 2 :(得分:1)
要优雅地获得平均值(尽管它可能不是绝对最快的方法),您可以使用accumarray
:
meanFeatures = accumarray(mask(:),image(:),[],@mean);
如果你想要,例如mean和std,你用
meanAndStd = cell2mat(accumarray(mask(:),image(:),[],@(x){mean(x), std(x)}));
答案 3 :(得分:0)
我认为我们需要了解更多信息:
如果为面具的每个元素指定值的公式可以进行矢量化,那么访问您的卷也是如此。
在一般情况下,我会说使用Mex文件很容易做到这一点。
如果你想这样做,我建议使用my tiny library来简化向Mex的过渡,但你需要使用C ++ 11(-std=c++0x
标志)进行编译。
如果您想留在Matlab中,并且只想计算这些区域的平均值,那么accumarray
就是您要寻找的功能。
答案 4 :(得分:0)
据我所知,这不是Matlab非常擅长的那种问题。我会尝试天真 - 非Matlab方法:
label_sum = zeros(1,num_labels);
label_size = zeros(1,num_labels);
for z=1:500,
for x=1:400,
for y=1:300,
label = labels(y, x, z);
label_sum(label) += img(y, x, z);
label_size(label) += 1;
end
end
end
label_sum(label_size > 0) ./ label_size(label_size > 0)
这不太理想,但可能会在不到10分钟的时间内完成......
答案 5 :(得分:0)
您可以使用arrayfun并避免使用for循环。使用要迭代的labels
值向量,它将变为:
features=arrayfun(@(x) mean(img(mask==x)), labels);
语法@(x)
将迭代labels
的每个元素,以这种方式替换for循环。您也可以使用任何函数而不是mean
,它既可以是内置函数,也可以是您创建的函数。你应该检查它的速度,但我认为这是最快的方法。