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

Nat*_*man 20 matlab image-processing mathematical-optimization

我在MATLAB中有一个图像:

y = rgb2gray(imread('some_image_file.jpg'));
Run Code Online (Sandbox Code Playgroud)

我想对它做一些处理:

pic = some_processing(y);
Run Code Online (Sandbox Code Playgroud)

并找到输出的局部最大值.也就是说,其中的所有点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];
Run Code Online (Sandbox Code Playgroud)

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

(max_val, max_i) = max(three_d, 3);
result = find(max_i == 1);
Run Code Online (Sandbox Code Playgroud)

有没有更优雅的方式来做到这一点?这看起来像是一块垃圾.

Ste*_*ins 37

bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);
Run Code Online (Sandbox Code Playgroud)

  • @Nathan:IMDILATE对灰度图像的每个像素进行操作.3×3矩阵的中心位于每个像素处,并且像素值被在3×3矩阵中具有值1的相邻像素处找到的最大值替换.因此,对IMDILATE的调用返回一个新矩阵,其中每个点被其8个邻居的最大值替换(根据需要在边缘填充零),并且原始矩阵较大的点表示局部最大值. (4认同)
  • `imdilate`遍历每个像素并计算以其为中心的相邻像素的最大值,并由给定的掩码指定(注意中间的零以排除像素本身).然后我们将得到的图像与原始图像进行比较,以检查每个像素是否严格大于其邻域的最大值.请务必阅读形态学操作的文档页面:http://www.mathworks.com/access/helpdesk/help/toolbox/images/f18-12508.html (2认同)
  • 似乎imdilate是在图像处理工具箱中.有原生的matlab解决方案吗? (2认同)

gno*_*ice 18

如果您有图像处理工具箱,则可以使用IMREGIONALMAX函数:

BW = imregionalmax(y);
Run Code Online (Sandbox Code Playgroud)

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

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

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


Amr*_*mro 11

或者,您可以使用nlfilter并提供自己的函数以应用于每个邻域.

这个"查找严格最大值"功能只是检查邻域的中心是否严格大于该邻域中的所有其他元素,为此目的总是3x3.因此:

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