如何在图像中找到局部最大值

时间:2014-03-06 07:36:57

标签: matlab local feature-detection

问题是关于特征检测概念。 在找到图像的角落后我被困住了,我想知道如何在计算角落内找到特征点。

假设我的灰度图像有这样的数据

A = [ 1 1 1 1 1 1 1 1;
      1 3 3 3 1 1 4 1;
      1 3 5 3 1 4 4 4;
      1 3 3 3 1 4 4 4; 
      1 1 1 1 1 4 6 4;
      1 1 1 1 1 4 4 4]

如果我使用

B = imregionalmax(A);

结果就像这样

B = [ 0 0 0 0 0 0 0 0;
      0 1 1 1 0 0 1 0;
      0 1 1 1 0 1 1 1;
      0 1 1 1 0 1 1 1;
      0 0 0 0 0 1 1 1;
      0 0 0 0 0 1 1 1]

问题是我如何在最大局部区域内选择最高峰(在样本中我如何从3中选择5和从4中选择6)?

我的想法是使用B检测每个区域并再次使用imregionalmax(),但我不擅长编码,我需要一些建议或其他想法。

2 个答案:

答案 0 :(得分:4)

还有其他几种简单的方法可以实现2D峰值查找器:ordfilt2imdilate

ordfilt2

最直接的方法是使用ordfilt2,它对本地社区中的值进行排序并选择第n个值。 (The MathWorks example演示了如何实现最大过滤器。)您还可以使用ordfilt2实现3x3峰值查找器,(1)使用不包含中心像素的3x3域,(2)选择最大(第8)值,(3)与中心值比较:

>> mask = ones(3); mask(5) = 0 % 3x3 max
mask =
     1     1     1
     1     0     1
     1     1     1

此掩码中考虑了8个值,因此第8个值是最大值。过滤器输出:

>> B = ordfilt2(A,8,mask)
B =
     3     3     3     3     3     4     4     4
     3     5     5     5     4     4     4     4
     3     5     3     5     4     4     4     4
     3     5     5     5     4     6     6     6
     3     3     3     3     4     6     4     6
     1     1     1     1     4     6     6     6

诀窍是将其与A进行比较,>> peaks = A > B peaks = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 是每个社区的中心值:

imdilate

imdilate

图像扩张通常在二进制图像上完成,但灰度图像扩张只是一个最大过滤器(参见ordfilt2 docs的Definitions section)。与B = imdilate(A, mask); peaks = A > B; 一起使用的相同技巧适用于此:定义不包含中心邻域像素的邻域,应用过滤器并与未过滤的图像进行比较:

{{1}}

注意:这些方法只能找到一个像素峰值。如果任何邻居具有相同的值,则不会是峰值。

答案 1 :(得分:1)

函数imregionalmax为您提供包含最大值及其8个邻居(即您所看到的3x3区域)的8连通区域。然后,您可以使用具有相同3x3结构元素的morphological operations将这些区域稀疏到其中心。 E.g。

 B = imregionalmax(A);
 C = imerode(B, ones(3));

或等效

 B = imregionalmax(A);
 D =  bwmorph(B, 'erode');

或者,您可以使用block-processing编写自己的最大查找功能:

 fun = @(block) % your code working on 'block' goes here ...
 B = blockproc(A, ones(3), fun)

但很可能这会比内置功能慢。 (我现在没有工具箱,所以我不能尝试。)

同时查看herehere