5.31. 변위 매칭

템플릿 매칭은 이 패치가 프레임 안 어디에 있는가 에 답하고, 유사도 점수는 이 두 이미지가 전체적으로 얼마나 비슷한가 에 답합니다. 그 사이에 또 다른 질문이 자리합니다. 두 프레임이 같은 장면을 보여주지만, 그 사이에 카메라(또는 장면)가 움직였다 – 얼마나? 이것이 변위(displacement) 문제이며, image 모듈은 단일 위상 상관(phase-correlation) 메서드로 이를 해결합니다.

5.31.1. 위상 상관 변위

find_displacement()위상 상관 을 사용하여 같은 크기의 두 이미지 사이의 강체(rigid) 정렬을 추정합니다 – 위상 상관은 각 이미지에 대해 고속 푸리에 변환(FFT)을 실행하고, 그 위상을 교차 상관시킨 다음, 결과에서 피크를 찾아내는 주파수 영역 방법입니다. 피크 위치는 두 이미지를 정렬하는 평행이동입니다:

d = img.find_displacement(template)

print("shift:", d.x_translation, d.y_translation,
      " response:", d.response)

반환된 Displacementx_translationy_translation – 각 축에서의 픽셀 이동 – 에 더해, 0.0 부터 1.0 까지의 신뢰도 점수인 response 를 담고 있으며, 1.0 은 완벽한 피크를 의미합니다. response > 0.3 보다 낮은 검출을 걸러내면 위상 상관이 깨끗한 피크를 전혀 찾지 못한 가짜 결과를 버립니다.

rotationscale 은 기본 모드에서 각각 0.0과 1.0입니다. 이들은 logpolar=True 일 때만 실제 값을 가집니다(아래 참조).

이 메서드에는 두 가지 실용적인 제약이 따릅니다. 첫째는 2의 거듭제곱 크기 입니다. 위상 상관의 핵심인 FFT는 32x32, 64x64, 128x128 같은 크기에서 가장 빠르며 – 카메라에서는 그 크기에서만 완전히 지원됩니다. 가장 깔끔한 설정은 해상도를 튜플로 framesize() 에 전달하여 그러한 크기 중 하나로 직접 캡처하는 것입니다:

csi0.framesize((64, 64))

더 큰 프레임으로부터 변위가 필요한 애플리케이션은 대신 관심 영역에서 2의 거듭제곱 패치를 크롭하여 그것에 대해 매처를 실행합니다.

둘째는 같은 크기의 입력 입니다. roitemplate_roi 는 동일한 너비와 높이를 선택해야 하며, 그렇지 않으면 매처가 호출을 거부합니다. 같은 카메라로 같은 구성에서 캡처한 두 장면은 이를 자동으로 만족합니다. 로드된 참조와 비교되는 캡처 프레임은 먼저 둘 다 일치하는 2의 거듭제곱 패치로 크롭해야 합니다.

5.31.2. 로그-폴라를 통한 회전 및 스케일

기본 모드는 평행이동만 찾습니다. 두 프레임이 선택한 중심을 기준으로 회전 하거나 같은 중심을 기준으로 스케일 에서도 차이가 날 때, 각 이미지의 로그-폴라(log-polar) 재투영에 대해 위상 상관을 실행하면 그러한 매개변수가 로그-폴라 좌표계에서의 평행이동으로 변환됩니다 – 동일한 위상 상관 매처가 이를 복원할 수 있습니다:

d = img.find_displacement(template, logpolar=True)

print("rotation rad:", d.rotation,
      " scale:", d.scale,
      " response:", d.response)

logpolar=True 를 사용하면, 메서드는 원본 대신 로그-폴라로 투영된 이미지에 대해 동일한 매칭 파이프라인을 실행합니다. 결과의 rotationscale 필드가 채워져 반환됩니다. rotation 은 두 프레임 사이의 라디안 단위 각도이고, scale 은 둘 사이의 스케일 계수입니다. 이 모드에서는 x_translationy_translation 이 무의미해집니다(로그-폴라 축을 따른 평행이동은 원본에서의 선형 평행이동에 대응하지 않습니다).

fix_rotation_scale=True 키워드는 그 중간 사례를 다룹니다. 두 이미지가 평행이동과 회전/스케일 둘 다 에서 차이가 나고, 애플리케이션이 회전과 스케일을 보정한 후 평행이동만 필요로 하는 경우입니다. 매처는 먼저 로그-폴라 패스를 실행하여 회전과 스케일을 복원하고, 두 이미지 중 하나에 역변환을 적용한 다음, 평행이동 패스를 실행하여 남은 이동을 복원합니다. 이 플래그는 logpolar=False 일 때만 의미가 있습니다 – 평행이동 모드 매처에게 먼저 회전/스케일을 제거하도록 요청하는 것입니다.

폴라 변환에서 나온 패턴 – 직교 좌표 → 폴라 → 매칭 – 이 바로 logpolar=Truefind_displacement() 가 한 번의 호출로 수행하는 것입니다. 애플리케이션은 시작 시 참조 로그-폴라 패치를 저장하고, 각 실시간 프레임을 캡처하여 로그-폴라 변환하며, 메서드가 그들 사이의 회전-및-스케일 차이를 복원합니다. 회전 및 스케일 불변 추적기가 필요한 애플리케이션 – 목표에 접근하면서 카메라가 기울고 줌하는 도킹 로봇, 이미지가 참조에 대해 어떻게 회전하는지 알아야 하는 안정화 짐벌 – 의 경우, 이것이 표준적인 구성입니다.

5.31.3. 고전적인 사용

find_displacement() 의 가장 흔한 용도는 움직이는 카메라를 처리하는 파이프라인에서의 프레임 간 모션 추정 입니다. 캠은 프레임 N에서 작은 2의 거듭제곱 패치를 캡처하고, 프레임 N+1에서 같은 크기의 패치를 캡처한 다음, 그 둘에 대해 find_displacement() 를 실행하여 그들 사이의 픽셀 이동을 읽어냅니다. 이 이동은 두 캡처 사이 카메라(또는 누구의 기준 프레임이 중요한지에 따라 장면)의 추정된 움직임이며, 다음 용도에 유용합니다:

  • 광학 흐름 방식의 센싱 – 아래를 향한 카메라를 가진 호버 드론은 프레임별 변위를 사용하여 횡 방향 움직임을 추정하고 이를 비행 컨트롤러에 피드백합니다.

  • 이미지 안정화 – 연속된 프레임 사이의 변위가 캡처된 이미지에서 차감된 후 기록 또는 전송되어, 더 부드러운 비디오 스트림을 생성합니다.

  • 검사 정렬 – 컨베이어를 따라 이동하는 스캐닝 캠은 프레임별 변위를 사용하여 각 프레임을 다음 프레임에 정합시키고 전체 부품의 스티칭된 뷰를 구축합니다.

이러한 각 애플리케이션은 동일한 형태를 취합니다. 캡처하고, 변위를 구하고, 누적 추정치에 합산하고, 다시 캡처합니다.