14장. 영상 기하학 변환과 Affine, Perspective
기하학 변환이란
방 안의 가구를 옮기는 날을 떠올려 봅시다. 소파의 색을 칠하는 것은 아니고, 소파를 창가로 밀고, 책상을 돌려 놓고, 작은 의자를 큰 의자로 바꿔 놓습니다. 가구는 그대로이고 자리만 바뀝니다. 3장부터 11장까지 한 일은 대부분 칸의 값을 바꾸는 일이었습니다(밝게, 흐리게, 흑백으로). 이 장의 기하학 변환은 칸의 값이 아니라 칸의 자리를 옮깁니다.
왼쪽 상자는 앞 장들에서 한 일, 오른쪽 상자는 이 장에서 할 일입니다. 여기서 소파의 색이 칸의 값이고, 소파가 놓인 자리가 칸의 좌표 (x, y) 입니다. 비유와 다른 점이 하나 있습니다. 가구는 옮겨도 그대로지만, 그림은 줄이거나 돌리면 칸 수가 바뀌어 값이 조금씩 달라질 수 있습니다. 이 점은 뒤의 보간법에서 봅니다.
같은 모눈 그림에 이 장의 변환 다섯 가지를 걸었습니다. 네 구석의 색 점(왼쪽 위 빨강, 오른쪽 위 초록, 오른쪽 아래 파랑, 왼쪽 아래 주황)이 어디로 갔는지 보면 변환이 점을 어떻게 옮겼는지 알 수 있습니다. 모눈의 곧은 선은 어느 변환에서도 곧게 남습니다.
이 장의 변환 한눈에
| 변환 | 하는 일 | OpenCV 함수 | 이 장의 절 |
|---|---|---|---|
| 크기 바꾸기 | 칸 수를 늘리거나 줄인다 | cv2.resize | 크기 바꾸기, 보간법 |
| 자르기·여백 | 일부만 남기거나 둘레를 덧댄다 | 슬라이싱, cv2.copyMakeBorder | 자르기와 크기 맞추기 |
| 뒤집기·90도 | 거울처럼 바꾸거나 직각으로 돌린다 | cv2.flip, cv2.rotate | 뒤집기와 90도 돌리기 |
| 아핀 변환 | 옮기기, 돌리기, 키우기, 기울이기 | cv2.warpAffine | 옮기기, 회전, 세 점으로 아핀 |
| 원근 변환 | 비스듬한 평면을 바로 편다 | cv2.warpPerspective | 원근 변환 |
짧은 예시
import cv2
# 변환이 잘 보이게 그린 모눈 그림(가상의 그림)
img = cv2.imread("ch14_grid.png")
print(img.shape) # 결과: (240, 320, 3)
# 왼쪽 위 빨간 점의 자리 (x, y) = (40, 40). 배열은 [행, 열] = [y, x] 순서로 읽는다
print(img[40, 40]) # 결과: [ 40 40 220] → BGR 로 빨강
# cv2.flip(그림, 1): 좌우로 뒤집는다. 칸의 값은 그대로이고 자리만 바뀐다
flipped = cv2.flip(img, 1)
print(flipped[40, 279]) # 결과: [ 40 40 220] → 빨간 점이 오른쪽 끝(x=279)으로 옮겨 갔다뒤집은 그림에서 빨간 점은 x = 40 에서 x = 279 로 옮겨 갔습니다. 가로 칸이 320개(0~319)이므로 319 − 40 = 279 입니다. 숫자 [40, 40, 220] 은 그대로입니다.
주의할 점
- 그림 함수와 변환 함수는 점을 (x, y) 순서로 받고, 배열은 [행, 열] = [y, x] 순서로 읽습니다. 2장에서 본 두 순서가 이 장 내내 섞여 나오므로 늘 확인합니다.
- 기하학 변환은 새 그림을 돌려주고 원본은 그대로 둡니다. 결과를 변수에 받아야 합니다.