주요 콘텐츠

xcorr2

2차원 상호상관

설명

c = xcorr2(a,b)는 스케일링 없이 행렬 ab에 대한 상호상관을 반환합니다. xcorr2xcorr의 2차원 버전입니다.

예제

c = xcorr2(a)는 입력 행렬 a의 자기상관 행렬입니다. 이 구문은 xcorr2(a,a)와 동일합니다.

예제

모두 축소

두 개의 행렬 M1M2를 생성합니다.

M1 = [17 24  1  8 15;
      23  5  7 14 16;
       4  6 13 20 22;
      10 12 19 21  3;
      11 18 25  2  9];

M2 = [8 1 6;
      3 5 7;
      4 9 2];

M1은 5×5이고, M2는 3×3이므로, 이들의 상호상관 크기는 (5+3-1)×(5+3-1), 즉 7×7입니다. 지연 측면에서 결과로 반환되는 행렬은 다음과 같습니다.

C=(c-2,-2c-2,-1c-2,0c-2,1c-2,2c-2,3c-2,4c-1,-2c-1,-1c-1,0c-1,1c-1,2c-1,3c-1,4c0,-2c0,-1c0,0c0,1c0,2c0,3c0,4c1,-2c1,-1c1,0c1,1c1,2c1,3c1,4c2,-2c2,-1c2,0c2,1c2,2c2,3c2,4c3,-2c3,-1c3,0c3,1c3,2c3,3c3,4c4,-2c4,-1c4,0c4,1c4,2c4,3c4,4).

이에 대한 예로, 요소 c0,2(또는 M2는 3×3이므로 MATLAB®의 경우 C(3,5))를 계산해 보겠습니다. 두 행렬의 (1,1) 요소가 일치하도록 두 행렬을 정렬합니다. 이 배치는 c0,0에 해당합니다. c0,2를 구하기 위해 M2의 두 행을 오른쪽으로 밉니다.

이제, M2가 행렬 M1(1:3,3:5)에 겹쳐졌습니다. 요소별 곱을 계산하고 이에 대한 합을 구합니다. 그 결과는 다음과 같습니다.

1×8+7×3+13×4+8×1+14×5+20×9+15×6+16×7+22×2=585.

[r2,c2] = size(M2);

CC = sum(sum(M1(0+(1:r2),2+(1:c2)).*M2))
CC = 
585

xcorr2를 사용하여 결과를 확인합니다.

D = xcorr2(M1,M2);

DD = D(0+r2,2+c2)
DD = 
585

크기가 M×N인 행렬 X와 크기가 P×Q인 행렬 H가 주어진 경우, 이들의 2차원 상호상관 C=XH는 다음 요소가 포함된 크기가 (M+P-1)×(N+Q-1)인 행렬입니다.

C(k,l)=Tr{XHkl}1kM+P-1,1lN+Q-1.

Tr은 대각합 함수이며 칼 모양은 에르미트(Hermitian) 켤레를 나타냅니다. 행렬 XHkl은 크기가 (M+2(P-1))×(N+2(Q-1))이고 다음으로 지정되는 0이 아닌 요소를 포함합니다.

X(m,n)=X(m-P+1,n-Q+1),PmM+P-1,QnN+Q-1

Hkl(p,q)=H(p-k+1,q-l+1),kpP+k-1,lqQ+l-1.

임의 크기의 일반적인 복소수 행렬에 대해 xcorr2를 호출하는 것도 위와 동일합니다.

크기가 7×22인 복소수 행렬 X와 크기가 6×17인 복소수 행렬 H를 생성합니다.

X = randn([7 22])+1j*randn([7 22]);
H = randn([6 17])+1j*randn([6 17]);

[M,N] = size(X);
m = 1:M;
n = 1:N;

[P,Q] = size(H);
p = 1:P;
q = 1:Q;

XC를 초기화합니다.

Xt = zeros([M+2*(P-1) N+2*(Q-1)]);
Xt(m+P-1,n+Q-1) = X;
C = zeros([M+P-1 N+Q-1]);

kl을 순환하여 C의 요소를 계산합니다. 각 단계에서 Hkl을 0으로 재설정합니다. 곱하여 대각합을 얻는 대신 요소의 곱의 총합을 구하여 시간과 메모리를 절약합니다.

for k = 1:M+P-1
    for l = 1:N+Q-1
        Hkl = zeros([M+2*(P-1) N+2*(Q-1)]);
        Hkl(p+k-1,q+l-1) = H;
        C(k,l) = sum(sum(Xt.*conj(Hkl)));
    end
end

max(max(abs(C-xcorr2(X,H))))
ans = 
1.5139e-14

결과는 xcorr2의 출력값과 기계 정밀도가 일치합니다.

상호상관을 사용하여 영상 일부가 전체의 어디에 해당하는지 찾습니다. 상호상관을 하면 두 개의 신호에서 서로 가장 유사한 영역을 찾을 수 있습니다. 영상과 같은 2차원 신호에서는 xcorr2를 사용합니다.

흑백 테스트 영상을 작업 공간으로 불러옵니다. 이 영상을 imagesc로 표시합니다.

load durer
img = X;
White = max(max(img));

imagesc(img)
axis image off
colormap gray
title('Original')

Figure contains an axes object. The hidden axes object with title Original contains an object of type image.

영상의 일부를 사각형으로 선택합니다. 해당 부분이 누락된 더 큰 영상을 표시합니다.

x = 435;
X = 535;
szx = x:X;

y = 62;
Y = 182;
szy = y:Y;

Sect = img(szx,szy);

kimg = img;
kimg(szx,szy) = White;

kumg = White*ones(size(img));
kumg(szx,szy) = Sect;

subplot(1,2,1)
imagesc(kimg)
axis image off
colormap gray
title('Image')

subplot(1,2,2)
imagesc(kumg)
axis image off
colormap gray
title('Section')

Figure contains 2 axes objects. Hidden axes object 1 with title Image contains an object of type image. Hidden axes object 2 with title Section contains an object of type image.

xcorr2를 사용하여 작은 영상이 더 큰 영상의 어디에 해당되는지 위치를 찾습니다. 음의 값과 양의 값의 개수가 대략적으로 같아지도록 평균값을 뺍니다.

nimg = img-mean(mean(img));
nSec = nimg(szx,szy);

crr = xcorr2(nimg,nSec);

상호상관의 최댓값은 잘라낸 조각의 오른쪽 아래 코너 위치에 대한 추정값입니다. ind2sub를 사용하여 최댓값의 1차원적 위치를 2차원 좌표로 변환합니다.

[ssr,snd] = max(crr(:));
[ij,ji] = ind2sub(size(crr),snd);

figure
plot(crr(:))
title('Cross-Correlation')
hold on
plot(snd,ssr,'or')
hold off
text(snd*1.05,ssr,'Maximum')

Figure contains an axes object. The axes object with title Cross-Correlation contains 3 objects of type line, text. One or more of the lines displays its values using only markers

더 큰 영상 안에 더 작은 영상을 배치합니다. MATLAB®에서 영상을 표시하는 데 사용하는 규칙을 따르도록 더 작은 영상을 회전합니다. 이 영상 주위에 사각형을 그립니다.

img(ij:-1:ij-size(Sect,1)+1,ji:-1:ji-size(Sect,2)+1) = rot90(Sect,2);

imagesc(img)
axis image off
colormap gray
title('Reconstructed')
hold on
plot([y y Y Y y],[x X X x x],'r')
hold off

Figure contains an axes object. The hidden axes object with title Reconstructed contains 2 objects of type image, line.

알려진 크기만큼 템플릿을 이동한 후 상호상관을 사용하여 이 이동을 복원합니다.

11×11 행렬로 템플릿을 생성합니다. 22×22 행렬을 생성하고 원래 템플릿을 행 차원을 따라 8만큼, 열 차원을 따라 6만큼 이동합니다.

template = 0.2*ones(11);
template(6,3:9) = 0.6;
template(3:9,6) = 0.6;
offsetTemplate = 0.2*ones(22);
offset = [8 6];
offsetTemplate((1:size(template,1))+offset(1), ...
    (1:size(template,2))+offset(2)) = template;

원래 템플릿과 이동된 템플릿을 플로팅합니다.

imagesc(offsetTemplate)
colormap gray
hold on
imagesc(template)
axis equal

Figure contains an axes object. The axes object contains 2 objects of type image.

두 행렬에 대해 상호상관을 수행하고 상호상관의 최대 절댓값을 구합니다. 최대 절댓값의 위치를 사용하여 템플릿의 이동 거리를 알아냅니다. 이 결과를 알려진 이동 크기와 비교합니다.

cc = xcorr2(offsetTemplate,template);
[max_cc, imax] = max(abs(cc(:)));
[ypeak, xpeak] = ind2sub(size(cc),imax(1));
corr_offset = [(ypeak-size(template,1)) (xpeak-size(template,2))];

isequal(corr_offset,offset)
ans = logical
   1

상호상관을 통해 구한 이동 거리가 행 차원과 열 차원의 알려진 템플릿 이동 크기와 같습니다.

이 예제를 수행하려면 Parallel Computing Toolbox™가 필요합니다. 지원되는 GPU를 보려면 GPU 연산 요구 사항 (Parallel Computing Toolbox) 항목을 참조하십시오.

알려진 크기만큼 템플릿을 이동한 후 상호상관을 사용하여 이 이동을 복원합니다.

11×11 행렬로 템플릿을 생성합니다. 22×22 행렬을 생성하고 원래 템플릿을 행 차원을 따라 8만큼, 열 차원을 따라 6만큼 이동합니다.

template = 0.2*ones(11); 
template(6,3:9) = 0.6;   
template(3:9,6) = 0.6;
offsetTemplate = 0.2*ones(22); 
offset = [8 6];
offsetTemplate((1:size(template,1))+offset(1), ...
    (1:size(template,2))+offset(2)) = template;

gpuArray 객체를 사용하여 원래 템플릿 행렬과 이동된 템플릿 행렬을 GPU에 배치합니다.

template = gpuArray(template);
offsetTemplate = gpuArray(offsetTemplate);

GPU에서 상호상관을 계산합니다.

cc = xcorr2(offsetTemplate,template);

gather를 사용하여 MATLAB® 작업 공간으로 결과를 반환합니다. 상호상관의 최대 절댓값을 사용하여 이동 거리를 확인하고 그 결과를 알려진 이동 크기와 비교합니다.

cc = gather(cc);
[max_cc,imax] = max(abs(cc(:)));
[ypeak,xpeak] = ind2sub(size(cc),imax(1));
corr_offset = [(ypeak-size(template,1)) (xpeak-size(template,2))];
isequal(corr_offset,offset)
ans = logical
   1

입력 인수

모두 축소

입력 배열로, 행렬로 지정됩니다.

예: sin(2*pi*(0:9)'/10)*sin(2*pi*(0:13)/20)은 2차원 정현파 곡면을 지정합니다.

데이터형: single | double
복소수 지원 여부:

출력 인수

모두 축소

2차원 상호상관 행렬 또는 자기상관 행렬로, 행렬로 반환됩니다.

세부 정보

모두 축소

확장 기능

모두 확장

C/C++ 코드 생성
MATLAB® Coder™를 사용하여 C 코드나 C++ 코드를 생성할 수 있습니다.

버전 내역

R2006a 이전에 개발됨

참고 항목

| |