图像快速特征提取

时间:2015-01-28 13:43:59

标签: performance matlab image-processing feature-extraction

我在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(顺便说一句,顺便说一下,这是我的情况)。

有关如何加速我的代码的任何建议?

6 个答案:

答案 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,它既可以是内置函数,也可以是您创建的函数。你应该检查它的速度,但我认为这是最快的方法。