OpenCV 비전 실무14장 · 영상 기하학 변환과 Affine, Perspective8 / 21← 이전목차다음 →MetaContents

14장. 영상 기하학 변환과 Affine, Perspective

옮기기와 아핀 변환의 짜임

놀이공원의 단체 사진 촬영을 떠올려 봅시다. 사진사가 "모두 오른쪽으로 세 걸음, 뒤로 한 걸음!" 하고 외치면 모든 사람이 같은 규칙으로 움직입니다. 규칙 하나로 모든 사람의 새 자리가 정해집니다. 아핀 변환도 같습니다. 점을 옮기는 규칙을 숫자 여섯 개로 적어 두면, 그림의 모든 칸이 그 규칙대로 옮겨 갑니다.

2×3 변환 표의 여섯 숫자와 점 (40, 40) 에 곱해 더해 새 자리 (100, 60) 을 구하는 손계산 그림

그림의 왼쪽이 2×3 변환 표, 가운데가 옮길 점, 오른쪽이 새 자리입니다. 표의 윗줄은 새 x 를, 아랫줄은 새 y 를 만듭니다. 줄마다 "첫째 숫자 × x + 둘째 숫자 × y + 셋째 숫자"를 계산합니다. 여기서 "오른쪽으로 세 걸음"이 표의 셋째 칸(옮길 거리)이고, 모든 사람이 같은 규칙을 따르는 것이 모든 칸에 같은 표를 쓰는 것입니다.

2×3 표를 손으로 계산하기

점 (40, 40) 을 오른쪽으로 60칸, 아래로 20칸 옮기는 표는 아래와 같습니다.

줄첫째 칸 (x 에 곱함)둘째 칸 (y 에 곱함)셋째 칸 (더함)계산새 값
윗줄 → 새 x10601 × 40 + 0 × 40 + 60100
아랫줄 → 새 y01200 × 40 + 1 × 40 + 2060

곱해서 더하는 계산 하나로 여러 변환을 적을 수 있습니다. 표의 숫자만 바꾸면 됩니다.

변환2×3 표점 (x, y) 가 가는 곳점 (40, 40) 의 예
그대로[[1, 0, 0], [0, 1, 0]](x, y)(40, 40)
옮기기[[1, 0, 60], [0, 1, 20]](x + 60, y + 20)(100, 60)
절반으로 줄이기[[0.5, 0, 0], [0, 0.5, 0]](0.5x, 0.5y)(20, 20)
가로로 2배[[2, 0, 0], [0, 1, 0]](2x, y)(80, 40)

옮기기는 더하기, 키우기와 줄이기는 곱하기입니다. 첫째·둘째 칸이 곱할 수, 셋째 칸이 더할 수입니다.

2×3 표 만들기, cv2.warpAffine 으로 옮기기, 빈 곳 채우기의 세 단계 흐름도

그림의 세 단계가 아핀 변환을 거는 순서입니다. 표는 np.float32 로 만들고, cv2.warpAffine 에 그림, 표, 결과 크기를 줍니다. 원본이 옮겨 가고 비는 곳은 borderValue 의 색으로 칠합니다.

짧은 예시

Python
import cv2
import numpy as np

img = cv2.imread("ch14_grid.png")
h, w = img.shape[:2]

# 오른쪽으로 60, 아래로 20 옮기는 2×3 표. 소수 자료형(float32)으로 만든다
M = np.float32([[1, 0, 60],
                [0, 1, 20]])

# 점 하나를 손계산과 같은 방법으로 옮겨 본다: 곱해서 더하기
x, y = 40, 40
print(M[0, 0] * x + M[0, 1] * y + M[0, 2], M[1, 0] * x + M[1, 1] * y + M[1, 2])   # 결과: 100.0 60.0

# cv2.warpAffine(그림, 2×3 표, 결과 크기 (가로, 세로))
moved = cv2.warpAffine(img, M, (w, h))
print(moved[60, 100])     # 결과: [ 40  40 220] → 빨간 점이 (100, 60) 으로 옮겨 갔다
print(moved[5, 5])        # 결과: [0 0 0] → 원본이 닿지 않는 빈 곳은 검정

주의할 점

  • 표는 반드시 2줄 3칸이고 소수 자료형(np.float32)이어야 합니다. 정수 목록 그대로 주면 오류가 납니다.
  • 결과 크기는 resize 처럼 (가로, 세로) 순서입니다. 원본 크기를 그대로 주면 밖으로 밀려난 칸은 잘려 나갑니다.
  • 빈 곳의 색은 borderValue=(255, 255, 255) 처럼 바꿀 수 있습니다. 기본은 검정입니다.
← 이전 절14장 · 뒤집기와 90도 돌리기다음 절 →14장 · 회전