OpenCV 활용한 Computer Vision

CROSSORBIT·2022년 7월 2일
0

Image-Processing

목록 보기
2/7
post-thumbnail

개요

  • OpenCV(Open Source Computer Vision) : 컴퓨터 비전을 위해 실시간 이미지 프로세싱에 중점을 둔 라이브러리
  • TensorFlow, Torch / PyTorch 및 Caffe의 딥러닝 프레임워크를 지원하여 사물 인식, OCR 등에 활용할 수 있음

주요 기능

1. 설치하기

pip install opencv-python

2. 이미지 열기

imread 로 파일 읽어오면, Numpy 배열(numpy.ndarray)로 리턴 됩니다. imshow 함수의 경우 윈도우 창을 새로 띄우기 거기에 이미지를 보여주는데요. 여러개 이미지를 띄우려면, 창 이름을 각기 다르게 지정해줘야 합니다. imshow 함수는 BGR로 색상을 불러오기 때문에 cv2.cvtColor 이용하여 RGB로 변경해야 원래 색상으로 볼 수 있습니다.

image = cv2.imread('./images/klimt.jpg', cv2.IMREAD_COLOR)
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

cv2.imshow('image', image)
cv2.imshow('rgb_image', rgb_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

# ESC로 창 닫을 수 있도록 waitkey 설정
for i in range (1,5):
    cv2.waitKey(1)

윈도우 창으로 이미지 띄우면, 매번 닫아줘야 하는 번거로움이 있는데요. matplotlib.pyplot 을 이용하여 jupyter notebook에서 쉽게 확인하는데 더 편합니다.

import matplotlib.pyplot as plt

plt.figure(figsize=(8, 5))

plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title('image')
plt.xticks([]), plt.yticks([])

plt.subplot(1, 2, 2)
plt.imshow(rgb_image)
plt.title('rgb_image')
plt.xticks([]), plt.yticks([])

plt.show()

[출력]

3. 이미지 속성

print(f'이미지 사이즈 : {format(image.shape)}')
print(f'이미지 dtype : {format(image.dtype)}')
print(f'이미지 Width : {format(image.shape[1])}')
print(f'이미지 Height : {format(image.shape[0])}')

[출력]
이미지 사이즈 : (778, 500, 3)
이미지 dtype : uint8
이미지 Width : 500
이미지 Height : 778

4. 이미지 크기 변경

  • 보간법
    - cv2.INTER_NEAREST (최근방 이웃 보간법)
    - cv2.INTER_LINEAR (양선형 보간법 - 2x2 이웃 픽셀 참조)
    - cv2.INTER_CUBIC (3차회선 보간법 - 4x4 이웃 픽셀 참조)
    - cv2.INTER_LANCZOS4 (Lanczos 보간법 - 8x8 이웃 픽셀 참조)
    - cv2.INTER_AREA (영역 보간법)
  • 크기 확대
    - INTER_LINEAR < INTER_CUBIC < INTER_LANCZOS4 순서로 시간 오래 걸리는 대신 퀄리티 높아짐.
    - 가장 적당하고 많이 사용하는 것은 INTER_LINEAR. 그래서 미지정시 기본값으로 적용됨
    - cv2.INTER_NEAREST 가 퀄리티 가장 안 좋음
  • 크기 축소
    - 축소 시 디테일이 사라질 수 있음. 입력 영상을 부드럽게 필터링 후 축소 진행
    - cv2.resize() 함수에서는 cv2.INTER_AREA 플래그 사용 권장. (디테일 사라짐 최소화)
import cv2, sys
import numpy as np

src = cv2.imread('./images/klimt.jpg')

if src is None:
    print("Image load failed")
    sys.exit()

img1 = cv2.resize(rgb_image, (1280, 1920)) 
img2 = cv2.resize(rgb_image, (1280, 1920), interpolation=cv2.INTER_LANCZOS4)
# x,y 비율로 설정하기
img3 = cv2.resize(rgb_image, dsize=(0,0), fx=0.5, fy=0.3, interpolation=cv2.INTER_AREA)

images = [img1, img2, img3]
title = ['INTER_LINEAR' ,'INTER_LANCZOS4' ,'INTER_AREA']

for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(images[i])
    plt.title(title[i])
    plt.xticks([]), plt.yticks([])

plt.show()

[출력]

5. 이미지 자르기

image = rgb_image[460:600, 20:480]

plt.imshow(image)
plt.title('crop')
plt.xticks([]), plt.yticks([])
plt.show()

[출력]

6. 이미지 회전

  • 회전 변환 행렬 구하기

    cv2.getRoatateMatrix2D(center, angel, sacle)
    - center : 회전 중심 좌표, (x, y) 튜플
    - angle : (반시계 방향) 회전 각도. (음수 설정 시 시계방향)
    - scale : 추가적 확대 비율
    * return value : 2x3 어파인 변환 행렬, 실수형

  • 어파인 변환 행렬을 cv2.warpAffine 함수에 입력해주면 이동 변환

    cv2.warpAffine(src, M, dsize, flags)
    - src : 입력 이미지
    - M : 앞서 구한 2x3 어파인 변환 행렬
    - dsize : 결과 영상 크기, (w, h) 튜플, (0, 0)이면 src와 같은 크기로 설정
    - flags : 보간법. 기본값은 cv2.INTER_LINEAR

copy = (rgb_image.shape[1] / 2, rgb_image.shape[0] / 2)

# 이미지 중심점 기준으로 45도 회전하면서 1.5배 확대
rotate = cv2.getRotationMatrix2D(copy, 45, 1.5)
image = cv2.warpAffine(rgb_image, rotate, (0,0))

[출력]

7. 이미지 좌우, 상하 대칭

img1 = cv2.flip(rgb_image, 1)  # FLIP_LEFT_RIGHT
img2 = cv2.flip(rgb_image, 0)  # FLIP_TOP_BOTTOM
img3 = cv2.flip(rgb_image, -1) # FLIP_LEFT_RIGHT_TOP_BOTTOM

[출력]

8. 박스 그리기 & 텍스트 넣기

openCV의 경우 한글을 지원하지 않아 텍스트에 한글 입력시 '???' 형태로 깨져서 출력됩니다. 한글 출력시 Pillow 등 사용하여 별도 설정이 필요합니다.

bbox_image = rgb_image.copy()

bounding_box = (30, 610, 140, 60)

x1, y1, w, h = bounding_box
pt1 = (int(x1), int(y1))
pt2 = (int(x1+w), int(y1+h))

cv2.rectangle(bbox_image, pt1, pt2, (0, 255, 0), 1)
cv2.putText(bbox_image, 'Title', (x1, y1 - 15), cv2.FONT_HERSHEY_DUPLEX, 1, (0,255,0))

plt.figure(figsize=(8, 5)) # 전체 Figure 사이즈 설정
plt.imshow(bbox_image)
plt.title('bbox_image')
plt.xticks([]), plt.yticks([])

[출력]

profile
기억과 기록 그 사이 어딘가에서

0개의 댓글