import cv2 as cv
import numpy as np
img = cv.imread("./.data/seulgi4.jpg")
img = cv.resize(img, dsize=(0, 0), fx=0.5, fy=0.5)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.putText(gray, 'seulgi', (10, 20), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
cv.imshow('Original', gray)
# 다양한 크기의 가우시안 블러 적용 후 결과를 수평으로 연결
# 왼쪽부터 5x5, 9x9, 15x15 커널 크기 순서
smooth = np.hstack((cv.GaussianBlur(gray, (5, 5), 0.0),
cv.GaussianBlur(gray, (9, 9), 0.0),
cv.GaussianBlur(gray, (15, 15), 0.0)))
# 블러 처리된 이미지들을 가로로 연결하여 표시
cv.imshow('smooth', smooth)
# 엠보싱 필터 정의 (좌상단에서 우하단 방향으로 양각 효과)
femboss = np.array([[-1.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 1.0]])
# 그레이스케일 이미지를 16비트 정수형으로 변환 (음수 값 처리를 위해)
gray16 = np.int16(gray)
# 엠보싱 필터 적용 (올바른 방법)
# filter2D 결과에 128을 더해 음수 값을 양수 범위로 이동시키고, 0-255 범위로 클리핑
emboss = np.uint8(np.clip(cv.filter2D(gray16, -1, femboss) + 128, 0, 255))
# 엠보싱 필터 적용 (문제 있는 방법 1)
# 클리핑 없이 128 더하기 - 오버플로우 발생 가능
emboss_bad = np.uint8(cv.filter2D(gray16, -1, femboss) + 128)
# 엠보싱 필터 적용 (문제 있는 방법 2)
# 8비트 이미지에 직접 적용 - 음수 값이 래핑되어 의도하지 않은 결과 생성
emboss_worse = cv.filter2D(gray, -1, femboss)
# 세 가지 방법으로 처리된 엠보싱 결과 이미지 표시
cv.imshow('Emboss', emboss) # 올바른 방법
cv.imshow('Emboss_bad', emboss_bad) # 문제 있는 방법 1
cv.imshow('Emboss_worse', emboss_worse) # 문제 있는 방법 2
# 키 입력 대기 (아무 키나 누를 때까지 창 유지)
cv.waitKey()
# 모든 OpenCV 창 닫기
cv.destroyAllWindows()
이동 변환(Translation)
회전 변환(Rotation)
크기 변환(Scaling)
영상 기하 변환은 컴퓨터 비전에서 이미지 정렬, 왜곡 보정, 특징점 추적 등 다양한 응용에 활용된다.
import cv2 as cv
img = cv.imread("./.data/frieren.png")
# 올바른 슬라이싱 문법: img[y1:y2, x1:x2]
patch = img[250:350, 170:270] # y좌표(250~350), x좌표(170~270) 영역 추출
# 원본 이미지에 사각형 그리기
img = cv.rectangle(img, (170, 250), (270, 350), (255, 0, 0), 3)
# 다양한 보간법으로 패치 크기 5배 확대
patch1 = cv.resize(patch, dsize=(0, 0), fx=5, fy=5, interpolation=cv.INTER_NEAREST)
patch2 = cv.resize(patch, dsize=(0, 0), fx=5, fy=5, interpolation=cv.INTER_LINEAR)
patch3 = cv.resize(patch, dsize=(0, 0), fx=5, fy=5, interpolation=cv.INTER_CUBIC)
# 결과 표시
cv.imshow('Original', img)
cv.imshow('Resize nearest', patch1) # 최근접 이웃 보간법
cv.imshow('Resize bilinear', patch2) # 쌍선형 보간법
cv.imshow('Resize bicubic', patch3) # 쌍입방 보간법
cv.waitKey()
cv.destroyAllWindows()
각 보간법의 차이점: