メインコンテンツ

正規化された相互相関を使用したイメージのレジストレーション

この例では、正規化された相互相関を使用して 2 つのイメージを位置合わせするために必要な変換を決定する方法を示します。

イメージの読み取り

2 つのイメージを読み取って表示します。この例では、イメージのサイズが異なります。

onion = imread("onion.png");
imshow(onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

peppers = imread("peppers.png");
imshow(peppers)

Figure contains an axes object. The hidden axes object contains an object of type image.

各イメージの部分領域の選択

相互相関行列のピークが識別しやすくなるように各イメージの部分領域を選択します。似ている領域を選択することが重要です。イメージ sub_onion はテンプレートであり、イメージ sub_peppers より小さくなければなりません。次のコマンドを使用すると、これらの部分領域を取得できます。

rect_onion = [111 33 65 58];
rect_peppers = [163 47 143 151];
sub_onion = imcrop(onion,rect_onion);
sub_peppers = imcrop(peppers,rect_peppers);

部分領域を対話的に選択する場合は、次のコマンドを使用できます。

[sub_onion,rect_onion] = imcrop(onion); % Choose the pepper below the onion
[sub_peppers,rect_peppers] = imcrop(peppers); % Choose the whole onion

部分領域を表示します。

imshow(sub_onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

imshow(sub_peppers)

Figure contains an axes object. The hidden axes object contains an object of type image.

正規化した相互相関の計算とピークの座標の検出

正規化した相互相関を計算し、表面プロットとして表示します。相互相関行列のピークは、サブイメージが最適相関である場合に発生します。normxcorr2 は、グレースケール イメージでのみ機能するため、関数には各サブイメージの最初のチャネルを渡します。

c = normxcorr2(sub_onion(:,:,1),sub_peppers(:,:,1));
surf(c) 
shading flat

Figure contains an axes object. The axes object contains an object of type surface.

ピークの座標を検出します。

[max_c,imax] = max(abs(c(:)));
[ypeak,xpeak] = ind2sub(size(c),imax(1));

イメージ間の全オフセットの検出

イメージ間の全オフセットまたは平行移動は、相互相関行列のピークの位置と、サブイメージのサイズおよび位置によって異なります。

% Offset found by correlation
corr_offset = [(xpeak-size(sub_onion,2)) 
               (ypeak-size(sub_onion,1))];

% Relative offset of position of subimages
rect_offset = [(rect_peppers(1)-rect_onion(1)) 
               (rect_peppers(2)-rect_onion(2))];

% Total offset
offset = corr_offset + rect_offset;
xoffset = offset(1);
yoffset = offset(2);

イメージのレジストレーションと結果の検証

onionpeppers の内に収まる場所について考えます。

xbegin = round(xoffset + 1);
xend   = round(xoffset + size(onion,2));
ybegin = round(yoffset + 1);
yend   = round(yoffset + size(onion,1));

% Extract region from peppers and compare to onion
extracted_onion = peppers(ybegin:yend,xbegin:xend,:);
if isequal(onion,extracted_onion) 
   disp("onion.png was extracted from peppers.png")
end
onion.png was extracted from peppers.png

上記で決定したオフセットを使用して、onion イメージをパディングし、peppers に重ね書きします。

recovered_onion = uint8(zeros(size(peppers)));
recovered_onion(ybegin:yend,xbegin:xend,:) = onion;
imshow(recovered_onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

アルファ ブレンディングを使用して、peppers イメージの 1 つの平面を recovered_onion イメージとともに表示して、レジストレーションを確認します。

imshowpair(peppers(:,:,1),recovered_onion,"blend")

Figure contains an axes object. The hidden axes object contains an object of type image.

参考

|