Как мне найти локальные максимумы на изображении в MATLAB? - PullRequest
20 голосов
/ 06 декабря 2009

У меня есть изображение в 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);

Есть ли более элегантный способ сделать это? Это кажется чем-то вроде клуджа.

Ответы [ 5 ]

37 голосов
/ 07 декабря 2009
bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);
18 голосов
/ 06 декабря 2009

Если у вас есть Панель инструментов обработки изображений , вы можете использовать функцию IMREGIONALMAX :

BW = imregionalmax(y);

Переменная 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
11 голосов
/ 07 декабря 2009

Кроме того, вы можете использовать nlfilter и предоставить свою собственную функцию, которая будет применяться к каждому району.

Эта функция "найти строгий максимум" просто проверяет, является ли центр окрестности строго большим, чем все другие элементы в этой окрестности, что для этой цели всегда 3x3. Поэтому:

I = imread('tire.tif');
BW = nlfilter(I, [3 3], @(x) all(x(5) > x([1:4 6:9])) );
imshow(BW)
2 голосов
/ 27 апреля 2015

В дополнение к imdilate, который находится в наборе инструментов обработки изображений, вы также можете использовать ordfilt2.

ordfilt2 сортирует значения в локальных окрестностях и выбирает n-е значение. ( Пример MathWorks демонстрирует, как реализовать фильтр max.) Вы также можете реализовать пиковый искатель 3x3 с ordfilt2 со следующей логикой:

  1. Определите домен 3x3, который не включает центральный пиксель (8 пикселей).

    >> mask = ones(3); mask(5) = 0 % 3x3 max
    mask =
         1     1     1
         1     0     1
         1     1     1
    
  2. Выберите наибольшее (восьмое) значение с помощью ordfilt2.

    >> 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
    
2 голосов
/ 08 декабря 2009

или просто используйте отлично: extrema2.m

...