私は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);
_
これを行うためのよりエレガントな方法はありますか?これはちょっとしたごまかしのようです。
bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);
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
または、 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)
画像処理ツールボックスにあるimdilate
に加えて、ordfilt2
を使用することもできます。
ordfilt2
は、ローカル近隣の値を並べ替え、n番目の値を選択します。 ( MathWorksの例 は、最大フィルターを実装する方法を示しています。)次のロジックでordfilt2
を使用して3x3ピークファインダーを実装することもできます。
中央のピクセル(8ピクセル)を含まない3x3ドメインを定義します。
>> mask = ones(3); mask(5) = 0 % 3x3 max
mask =
1 1 1
1 0 1
1 1 1
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
この出力を各近隣の中心値と比較します(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
または、優れたものを使用してください: extrema2.m