Skip to content

Latest commit

 

History

History
335 lines (261 loc) · 9.56 KB

220124.md

File metadata and controls

335 lines (261 loc) · 9.56 KB

Day 105

OpenCV(Computer Vision)

3. 도형 그리기

사각형

import cv2
import numpy as np

img = np.zeros((480, 640, 3), dtype = np.uint8)

COLOR = (0, 255, 0)
THICKNESS = 3

cv2.rectangle(img, (100, 100), (200, 200), COLOR, THICKNESS) # 속이 빈 사각형
# (그릴 위치, 왼쪽 위 좌표, 오른쪽 아래 좌표, 색깔, 두께)
cv2.rectangle(img, (300, 100), (400, 300), COLOR, cv2.FILLED) # 속이 찬 사각형

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

draw_rectangle

다각형

import cv2
import numpy as np

img = np.zeros((480, 640, 3), dtype = np.uint8)

COLOR = (0, 0, 255)
THICKNESS = 3

pts1 = np.array([[100, 100], [200, 100], [100, 200]])
pts2 = np.array([[200, 100], [300, 100], [300, 200]])

# cv2.polylines(img, [pts1], True, COLOR, THICKNESS, cv2.LINE_AA)
# cv2.polylines(img, [pts2], True, COLOR, THICKNESS, cv2.LINE_AA)
cv2.polylines(img, [pts1, pts2], True, COLOR, THICKNESS, cv2.LINE_AA) # 속이 빈 다각형
# (그릴 위치, 그릴 좌표들, 닫힘 여부, 색깔, 두께, 선종류)

pts3 = np.array([[[100, 300], [200, 300], [100, 400]], [[200, 300], [300, 300], [300, 400]]])
cv2.fillPoly(img, pts3, COLOR, cv2.LINE_AA) # 속이 찬 다각형
# (그릴 위치, 그릴 좌표들, 색깔, 선 종류)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

그릴 좌표들을 지정하는 방법에 여러가지 방법이 있다. [pts1]과 [pts2]로 각각 나눠서 두번에 걸쳐서 그리는 방법, [pts1, pts2]로 하나로 묶어서 표현하는 방법, pts3처럼 표현하는 방법이 있다.

draw_polyline

import cv2
import numpy as np

img = np.zeros((480, 640, 3), dtype = np.uint8)

COLOR = (0, 0, 255)
THICKNESS = 3

pts1 = np.array([[100, 100], [200, 100], [100, 200]])
pts2 = np.array([[300, 100], [400, 100], [300, 200]])
cv2.polylines(img, [pts1], True, COLOR, THICKNESS, cv2.LINE_AA)
cv2.polylines(img, [pts2], False, COLOR, THICKNESS, cv2.LINE_AA)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

닫힘 여부를 True로 하면 끝점과 시작점을 이어주고, False면 잇지 않는다. 아래 그림에서 좌측이 True, 우측이 False이다.

Poly_compare

4. 텍스트

OpenCV에서 사용하는 글꼴 종류

  1. cv2.FONT_HERSHEY_SIMPLEX : 보통 크기의 sans-serif 글꼴
  2. cv2.FONT_HERSHEY_PLAIN : 작은 크기의 sans-serif 글꼴
  3. cv2.FONT_HERSHEY_SCRIPT_SIMPLEX : 필기체 스타일 글꼴
  4. cv2.FONT_HERSHEY_TRIPLEX: 보통 크기의 serif 글꼴
  5. cv2.FONT_ITALIC : 기울임
import numpy as np
import cv2

img = np.zeros((480, 640, 3), dtype=np.uint8)

SCALE = 1 # 글씨 크기
COLOR = (255, 255, 255)
THICKNESS = 1

cv2.putText(img, "Simplex", (20, 50), cv2.FONT_HERSHEY_SIMPLEX, SCALE, COLOR, THICKNESS)
# (그릴 위치, 텍스트 내용, 시작 위치, 폰트 종류, 크기, 색깔, 두께)
cv2.putText(img, "Plain", (20, 150), cv2.FONT_HERSHEY_PLAIN, SCALE, COLOR, THICKNESS)
cv2.putText(img, "Script", (20, 250), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, SCALE, COLOR, THICKNESS)
cv2.putText(img, "Triplex", (20, 350), cv2.FONT_HERSHEY_TRIPLEX, SCALE, COLOR, THICKNESS)
cv2.putText(img, "Italic", (20, 450), cv2.FONT_HERSHEY_TRIPLEX | cv2.FONT_ITALIC, SCALE, COLOR, THICKNESS)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Italic을 사용할 때는 "|"를 사용해서 폰트도 지정해줘야 한다.

put_text

한글 우회

OpenCV에서 한글을 지원하지 않아 글자가 깨진다.

import numpy as np
import cv2

img = np.zeros((480, 640, 3), dtype=np.uint8)

SCALE = 1 # 글씨 크기
COLOR = (255, 255, 255)
THICKNESS = 1

cv2.putText(img, "한글", (20, 50), cv2.FONT_HERSHEY_SIMPLEX, SCALE, COLOR, THICKNESS)


cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Korean_text

그래서 한글을 표시하기 위해서 PIL(Python Image Library)이라는 라이브러리의 도움을 받는다.

import numpy as np
import cv2
from PIL import ImageFont, ImageDraw, Image

# 한글을 그리기 위한 함수
def myPutText(src, text, pos, font_size, font_color):
    img_pil = Image.fromarray(src)
    draw = ImageDraw.Draw(img_pil)
    font = ImageFont.truetype('fonts/gulim.ttc', font_size)
    draw.text(pos, text, font=font, fill=font_color)
    return np.array(img_pil)

img = np.zeros((480, 640, 3), dtype=np.uint8)

FONT_SIZE = 30
COLOR = (255, 255, 255)

img = myPutText(img, "한글", (20, 50), FONT_SIZE, COLOR)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

PIL

5. 파일 저장

이미지 저장

import cv2
img = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)

cv2.imwrite('img_gray.jpg', img) # 성공하면 True, 아니면 False
# cv2.imwrite('img_gray.png', img) # png 형태로 저장

img_save_result

동영상 저장

import cv2
cap = cv2.VideoCapture('video.mp4')

# 코덱 정의
fourcc = cv2.VideoWriter_fourcc(*'DIVX') # 어떤 형태로 저장

# 프레임 크기, FPS
width = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)

out = cv2.VideoWriter('output.avi', fourcc, fps, (width, height))
# (저장 파일명, 코덱, FPS, 크기, (width, height))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
        
    out.write(frame) # 영상 데이터만 저장 (소리 X)
    cv2.imshow('video', frame)
    if cv2.waitKey(25) == ord('q'):
        break

out.release()
cap.release()
cv2.destroyAllWindows()

*'DIVX'는 'D', 'I', 'V', 'X'를 따로따로 적는 것과 같다.

c = 'DIVX'
print([c])  # ['DIVX']
print([*c]) # ['D', 'I', 'V', 'X']

width, height는 정수 값을 가져야 해서 round를 사용한다.
cv2.CAP_PROP_FRAME_WIDTH를 사용하면 영상 원본의 width값을 가져온다.

6. 크기 조정

이미지

고정 크기로 설정

import cv2
img = cv2.imread('img.jpg')
dst = cv2.resize(img, (400, 500)) # width, height 고정 크기

cv2.imshow('img', img)
cv2.imshow('resize', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

resize

비율로 설정

import cv2
img = cv2.imread('img.jpg')
dst = cv2.resize(img, None, fx=0.5, fy=0.5) # x, y 비율 정의 (0.5 배로 축소)

cv2.imshow('img', img)
cv2.imshow('resize', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

resize_1

보간법

  1. cv2.INTER_AREA : 크기 줄일 때 사용
  2. cv2.INTER_CUBIC : 크기 늘릴 때 사용 (속도 느림, 퀄리티 좋음)
  3. cv2.INTER_LINEAR : 크기 늘릴 때 사용 (기본값)

보간법 적용하여 축소

import cv2
img = cv2.imread('img.jpg')
dst = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA) # x, y 비율 정의 (0.5 배로 축소)

cv2.imshow('img', img)
cv2.imshow('resize', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

보간법 적용하여 확대

import cv2
img = cv2.imread('img.jpg')
dst = cv2.resize(img, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC) # x, y 비율 정의 (1.5 배로 확대)

cv2.imshow('img', img)
cv2.imshow('resize', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

동영상

고정 크기로 설정

import cv2
cap = cv2.VideoCapture('video.mp4')

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_resized = cv2.resize(frame, (400, 500)) # 크기 조정
    
    cv2.imshow('video', frame_resized) # 크기 조정된 것을 출력
    if cv2.waitKey(1) == ord('q'):
        break
        
cap.release()
cv2.destroyAllWindows()

비율로 설정

import cv2
cap = cv2.VideoCapture('video.mp4')

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_resized = cv2.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)
    
    cv2.imshow('video', frame_resized)
    if cv2.waitKey(1) == ord('q'):
        break
        
cap.release()
cv2.destroyAllWindows()

7. 이미지 자르기

영역을 잘라서 새로운 윈도우에 표시

import cv2
img = cv2.imread('img.jpg')

crop = img[100:200, 200:400] # [세로범위, 가로범위]

cv2.imshow('img', img)   # 원본 이미지
cv2.imshow('crop', crop) # 잘린 이미지
cv2.waitKey(0)
cv2.destroyAllWindows()

crop

영역을 잘라서 기존 윈도우에 표시

import cv2
img = cv2.imread('img.jpg')

crop = img[100:200, 200:400] # [세로범위, 가로범위]
img[100:200, 400:600] = crop

cv2.imshow('img', img)   # 원본 이미지
cv2.waitKey(0)
cv2.destroyAllWindows()

crop1