【问题标题】:How can I find local maxima in an image in MATLAB?如何在 MATLAB 中找到图像中的局部最大值?
【发布时间】:2010-12-23 19:03:33
【问题描述】:

我在 MATLAB 中有一张图片:

y = rgb2gray(imread('some_image_file.jpg'));

我想对其进行一些处理:

pic = some_processing(y);

并找到输出的局部最大值。也就是说,y 中大于其所有邻居的所有点。

我似乎无法找到一个 MATLAB 函数来很好地做到这一点。我能想到的最好的是:

[dim_y,dim_x]=size(pic);
enlarged_pic=[zeros(1,dim_x+2);
              zeros(dim_y,1),pic,zeros(dim_y,1);
              zeros(1,dim_x+2)];

% now build a 3D array
% each plane will be the enlarged picture
% moved up,down,left or right,
% to all the diagonals, or not at all

[en_dim_y,en_dim_x]=size(enlarged_pic);

three_d(:,:,1)=enlarged_pic;
three_d(:,:,2)=[enlarged_pic(2:end,:);zeros(1,en_dim_x)];
three_d(:,:,3)=[zeros(1,en_dim_x);enlarged_pic(1:end-1,:)];
three_d(:,:,4)=[zeros(en_dim_y,1),enlarged_pic(:,1:end-1)];
three_d(:,:,5)=[enlarged_pic(:,2:end),zeros(en_dim_y,1)];
three_d(:,:,6)=[pic,zeros(dim_y,2);zeros(2,en_dim_x)];
three_d(:,:,7)=[zeros(2,en_dim_x);pic,zeros(dim_y,2)];
three_d(:,:,8)=[zeros(dim_y,2),pic;zeros(2,en_dim_x)];
three_d(:,:,9)=[zeros(2,en_dim_x);zeros(dim_y,2),pic];

然后看第3维的最大值是否出现在第1层(即:three_d(:,:,1)):

(max_val, max_i) = max(three_d, 3);
result = find(max_i == 1);

有没有更优雅的方法来做到这一点?这似乎有点杂乱无章。

【问题讨论】:

标签: matlab image-processing mathematical-optimization


【解决方案1】:
bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);

【讨论】:

  • 是的,这个更快:)
  • +1 我忘记了 IMDILATE 如何处理灰度图像(我通常只使用逻辑蒙版)。
  • @Nathan:IMDILATE 对灰度图像的每个像素进行操作。 3×3 矩阵的中心位于每个像素处,像素值替换为在 3×3 矩阵中值为 1 的相邻像素处找到的最大值。因此,对 IMDILATE 的调用会返回一个新矩阵,其中每个点都替换为其 8 个邻居的最大值(根据需要在边缘填充零),原始矩阵较大的点表示局部最大值。
  • imdilate 遍历每个像素并计算以它为中心并由给定掩码指定的相邻像素的最大值(注意中间的零以排除像素本身)。然后我们将生成的图像与原始图像进行比较,以检查每个像素是否严格大于其邻域的最大值。请务必阅读有关形态学操作的文档页面:mathworks.com/access/helpdesk/help/toolbox/images/…
  • 似乎 imdilate 在图像处理工具箱中。有原生的matlab解决方案吗?
【解决方案2】:

如果你有Image Processing Toolbox,你可以使用IMREGIONALMAX函数:

BW = imregionalmax(y);

变量BW 将是一个与y 大小相同的逻辑矩阵,其中1 表示局部最大值,否则为零。

注意:正如您所指出的,IMREGIONALMAX 会找到大于或等于其邻居的最大值。如果您想排除具有相同值的相邻最大值(即查找单个像素的最大值),您可以使用 BWCONNCOMP 函数。以下应删除 BW 中具有任何邻居的点,只留下单个像素:

CC = bwconncomp(BW);
for i = 1:CC.NumObjects,
  index = CC.PixelIdxList{i};
  if (numel(index) > 1),
    BW(index) = false;
  end
end

【讨论】:

  • 谢谢!我看到 imregionalmax 找到大于或等于其邻居的最大值。你知道我怎么才能只找到那些比他们的邻居更大但不等于他们的人吗?
  • @Nathan:那么,如果你要找到一组相等的相邻最大值,你会选择其中一个,还是排除所有?
  • 哦...我解决了这个问题以表明我正在使用灰度。
  • 史蒂夫的回答确实更优雅。
  • @Dynamite:您可以先反转图像,使最小值变为最大值,然后使用与上述相同的方法。例如,如果你有一个无符号的 8 位整数图像,你可以用 "255 - y" 反转它。
【解决方案3】:

或者,您可以使用nlfilter 并提供您自己的函数以应用于每个社区。​​p>

“find strict max” 函数将简单地检查邻域的中心是否严格大于该邻域中的所有其他元素,为此目的始终为 3x3。因此:

I = imread('tire.tif');
BW = nlfilter(I, [3 3], @(x) all(x(5) > x([1:4 6:9])) );
imshow(BW)

【讨论】:

    【解决方案4】:

    除了图像处理工具箱中的imdilate,您还可以使用ordfilt2

    ordfilt2 对本地邻域中的值进行排序并选择第 n 个值。 (The MathWorks example 演示了如何实现最大过滤器。)您还可以使用 ordfilt2 实现 3x3 峰值查找器,其逻辑如下:

    1. 定义一个 不包括中心像素(8 个像素)的 3x3 域。

      >> mask = ones(3); mask(5) = 0 % 3x3 max
      mask =
           1     1     1
           1     0     1
           1     1     1
      
    2. 使用ordfilt2 选择最大(第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
      
    3. 将此输出与每个邻域的中心值进行比较(仅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
      

    【讨论】:

    • 这是这里最正确的解决方案。它在 Matlab 中原生,计算时间比 nfilter 少。
    • @Franzd'Anconia 但我回答晚了 5 年,所以它在底部。 :)
    • 很好的答案。是否可以包含原始矩阵A?您的处理链中似乎缺少它。我可以轻松地对其进行逆向工程,但最好包括它的自包含内容:)。谢谢!
    【解决方案5】:

    或者,只使用优秀的:extrema2.m

    【讨论】:

      猜你喜欢
      • 2017-01-04
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      相关资源
      最近更新 更多