web-dev-qa-db-ja.com

MATLABの画像で極大値を見つけるにはどうすればよいですか?

私は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);
_

これを行うためのよりエレガントな方法はありますか?これはちょっとしたごまかしのようです。

20
Nathan Fellman
bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);
37
Steve Eddins

Image Processing Toolbox がある場合は、 [〜#〜] imregionalmax [〜#〜] 関数を使用できます。

BW = imregionalmax(y);

変数BWは、yと同じサイズの論理行列になり、1は極大値を示し、それ以外の場合は0を示します。

注:ご指摘のとおり、IMREGIONALMAXは、隣接するものよりも大きいまたは等しい最大値を検出します。 。同じ値を持つ隣接する最大値を除外する場合(つまり、単一ピクセルである最大値を見つける場合)、 [〜#〜] bwconncomp [〜#〜] 関数を使用できます。以下は、隣接するBW内のポイントを削除し、単一のピクセルのみを残す必要があります。

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

または、 nlfilter を使用して、各近隣に適用される独自の関数を指定することもできます。

この "find strict max"関数は、近隣の中心がその近隣の他のすべての要素(常に3x3)よりも厳密に大きいかどうかを単純にチェックします。この目的のために。したがって:

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

画像処理ツールボックスにあるimdilateに加えて、ordfilt2を使用することもできます。

ordfilt2は、ローカル近隣の値を並べ替え、n番目の値を選択します。 ( MathWorksの例 は、最大フィルターを実装する方法を示しています。)次のロジックで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
    
2
chappjc

または、優れたものを使用してください: extrema2.m

2
Alex Cohen