14장. 영상 기하학 변환과 Affine, Perspective
크기 바꾸기
복사기의 "축소·확대" 단추를 떠올려 봅시다. "A4 를 A5 로"처럼 종이 크기를 정해 줄 수도 있고, "50%"처럼 비율로 줄 수도 있습니다. cv2.resize 도 두 가지로 크기를 받습니다. 새 크기를 직접 주는 dsize, 그리고 가로·세로 배율을 주는 fx, fy 입니다.
그림의 세 상자가 크기를 정하는 세 가지 방법입니다. 여기서 "A5 로"가 dsize, "50%"가 fx, fy 입니다. 셋째 상자처럼 가로만 정하고 세로는 비율로 계산하면 사진이 찌그러지지 않습니다.
가운데 그림은 가로와 세로를 똑같이 절반으로 줄여 모양이 그대로입니다. 오른쪽 그림은 4:3 그림을 1:1 로 억지로 맞춰서 글자 F 와 동그란 점이 옆으로 홀쭉해졌습니다. 종횡비를 지키지 않으면 물건의 모양이 바뀝니다.
cv2.resize 의 인자
| 인자 | 뜻 | 예 |
|---|---|---|
src | 바꿀 그림(source, 원본) | img |
dsize | 새 크기(destination size). (가로, 세로) 순서 | (160, 120) |
fx, fy | 가로 배율, 세로 배율(factor x, factor y). dsize 를 None 으로 줄 때 쓴다 | fx=0.5, fy=0.5 |
interpolation | 새 칸을 채우는 방법. 다음 절에서 본다 | cv2.INTER_AREA |
비율을 지켜 크기 정하기
가로를 200 으로 줄이고 싶다면 세로는 같은 비율로 줄입니다. 배율은 200 ÷ 320 = 0.625 이고, 새 세로는 240 × 0.625 = 150 입니다. 칸 수는 정수여야 하므로 계산 결과를 round 로 반올림합니다.
| 원본 (가로×세로) | 정한 가로 | 배율 | 새 세로 |
|---|---|---|---|
| 320×240 | 200 | 200 ÷ 320 = 0.625 | 240 × 0.625 = 150 |
| 320×180 | 128 | 128 ÷ 320 = 0.4 | 180 × 0.4 = 72 |
| 160×240 | 128 | 128 ÷ 160 = 0.8 | 240 × 0.8 = 192 |
짧은 예시
import cv2
img = cv2.imread("ch14_grid.png")
h, w = img.shape[:2] # shape 는 (세로, 가로, 채널) 순서
# 방법 1. dsize 로 새 크기를 (가로, 세로) 순서로 준다
a = cv2.resize(img, (160, 120))
# 방법 2. dsize 는 None, 배율 fx·fy 를 준다
b = cv2.resize(img, None, fx=0.5, fy=0.5)
print(a.shape, b.shape) # 결과: (120, 160, 3) (120, 160, 3) → shape 는 (세로, 가로)
# 방법 3. 가로를 200 으로 정하고 세로는 비율로 계산한다
new_w = 200
new_h = round(h * new_w / w) # 240 × 200 ÷ 320 = 150
c = cv2.resize(img, (new_w, new_h))
print(c.shape) # 결과: (150, 200, 3)dsize 에는 (가로, 세로) 를 주는데, 결과의 shape 는 (세로, 가로) 로 찍힙니다. 순서가 서로 반대라는 것을 꼭 기억합니다.
주의할 점
cv2.resize(img, (240, 320))처럼shape순서대로 (세로, 가로) 를 넣으면 가로 240, 세로 320 인 세로로 긴 그림이 됩니다. 오류가 나지 않아 알아채기 어렵습니다.dsize와fx,fy를 함께 주면dsize가 이깁니다. 배율을 쓸 때는dsize자리에None을 줍니다.- 3장에서 본 것처럼 작은 그림을 키워도 새 정보는 생기지 않습니다. 칸이 커질 뿐입니다.