Main Content

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 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. Axes object 1 with title Image contains an object of type image. 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 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차원 상호상관 행렬 또는 자기상관 행렬로, 행렬로 반환됩니다.

세부 정보

모두 축소

2차원 상호상관

M×N 행렬 X와 P×Q 행렬 H에 대한 2차원 상호상관은 크기가 M+P–1 x N+Q–1인 행렬 C입니다. 이 행렬의 요소는 다음과 같이 지정됩니다.

C(k,l)=m=0M1n=0N1X(m,n)H¯(mk,nl),(P1)kM1,(Q1)lN1,

여기서 H 위에 있는 막대는 켤레 복소수를 나타냅니다.

출력 행렬 C(k,l)은 음수, 양수의 행, 열 인덱스를 가집니다.

  • 음수 행 인덱스는 H의 행에 대한 위쪽 방향 이동에 해당합니다.

  • 음수 열 인덱스는 H의 열에 대한 왼쪽 방향 이동에 해당합니다.

  • 양수 행 인덱스는 H의 행에 대한 아래쪽 방향 이동에 해당합니다.

  • 양수 열 인덱스는 H의 열에 대한 오른쪽 방향 이동에 해당합니다.

MATLAB® 형식으로 인덱스를 형변환하려면 H의 크기를 더해야 합니다. 즉, 요소 C(k,l)은 작업 공간의 C(k+P,l+Q)에 대응됩니다.

예를 들어, 다음과 같은 2차원 상호상관을 살펴보겠습니다.

X = ones(2,3);
H = [1 2; 3 4; 5 6];  % H is 3 by 2
C = xcorr2(X,H)
C =
     6    11    11     5
    10    18    18     8
     6    10    10     4
     2     3     3     1

출력값의 C(1,1) 요소는 0부터 시작하는 인덱싱을 사용하는 정의 방정식에서 C(1–3,1–2) = C(–2,–1)에 대응됩니다. C(1,1) 요소를 계산하기 위해 H를 두 행 위로, 한 행 왼쪽으로 이동합니다. 이에 따라, 상호상관 합의 곱은 X(1,1)*H(3,2) = 6이 됩니다. 정의 방정식을 사용하면 다음과 같습니다.

C(2,1)=m=01n=02X(m,n)H¯(m+2,n+1)=X(0,0)H¯(2,1)=1×6=6,

여기서 이중합 내에 있는 다른 모든 항은 0입니다.

확장 기능

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

버전 내역

R2006a 이전에 개발됨

참고 항목

| |