주요 콘텐츠

정규화된 상호상관을 사용하여 영상 정합하기

이 예제에서는 정규화된 상호상관을 사용하여 두 영상을 정렬하는 데 필요한 평행 이동을 결정하는 방법을 보여줍니다.

영상 읽어 들이기

영상 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

위에서 구한 오프셋을 사용하여 peppers 위에 onion 영상을 겹쳐서 표시하기 위해, 이 영상에 채우기를 수행합니다.

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 영상의 한 평면을 recovered_onion 영상과 함께 표시하여 정합을 확인합니다.

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

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

참고 항목

|