OpenCV - 이미지/비디오 읽기


OpenCV Python으로 이미지/비디오 읽기! OpenCV를 이용해 이미지 파일을 읽고 보고 저장하는 방법에 대해 알아보겠습니다
키워드 : cv2.imread(), cv2.imshow(), cv2.imwrite(), cv2.VideoCapture(), cv2.VideoWriter()

이미지 읽기 (Image Read)

import cv2
import numpy as np

img = cv2.imread('test.jpg', cv2.IMREAD_COLOR)

cv2.imread(fileName, flag) : fileName은 이미지 파일의 경로를 의미하고 flag는 이미지 파일을 읽을 때 옵션입니다

flag는 총 3가지가 있습니다. 명시적으로 써줘도 되고 숫자를 사용해도 됩니다
cv2.IMREAD_COLOR(1) : 이미지 파일을 Color로 읽음. 투명한 부분은 무시하며 Default 설정입니다
cv2.IMREAD_GRAYSCALE(0) : 이미지 파일을 Grayscale로 읽음. 실제 이미지 처리시 중간 단계로 많이 사용합니다
cv2.IMREAD_UNCHAGED(-1) : 이미지 파일을 alpha channel 까지 포함해 읽음

>>> image.shape
(206, 207, 3)

image.shape 함수는 이미지 파일의 모양을 return합니다 순서대로 Y축, X축, 채널의 수를 의미합니다
** OpenCV에선 색을 표현할 경우 BGR 순으로 표현합니다! **

이미지 보기 (Image Show)

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

cv2.imshow(tital, image) : title은 윈도우 창의 제목을 의미하며 image는 cv2.imread() 의 return값입니다
cv2.waitKey()는 키보드 입력을 대기하는 함수로 0이면 key 입력이 있을때까지 무한대기합니다. 특정 시간동안 대기를 하려면 ms값을 넣어주면 됩니다. 또한 ESC를 누를 경우 27을 리턴합니다. 이런 리턴 값을 알면 버튼에 따라 다른 동작을 실시하도록 로직을 설계할 수 있습니다
cv2.destroyAllWindows() : 화면에 나타난 윈도우를 종료합니다. 일반적으로 위 3개는 같이 사용됩니다

예제코드

import cv2

fname = './data/test.jpg'

original = cv2.imread(fname, cv2.IMREAD_COLOR)
gray = cv2.imread(fname, cv2.IMREAD_GRAYSCALE)
unchange = cv2.imread(fname, cv2.IMREAD_UNCHANGED)

cv2.imshow('Original', original)
cv2.imshow('Gray', gray)
cv2.imshow('Unchange', unchange)

cv2.waitKey(0)
cv2.destroyAllWindows()

이미지 저장하기

cv2.imwrite('result.png', original)

예시를 통해 어떻게 사용하는지 알려드리겠습니다!

import cv2

img = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27: # esc key
    cv2.destroyAllWindow()
elif k == ord('s'): # 's' key
    cv2.imwrite('testgray.png',img)
    cv2.destroyAllWindow()

ESC키를 누를 경우 창을 닫고 s키를 누를 경우 저장하는 코드입니다

Window 창 조절하기

import cv2

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

cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27: # esc key
    cv2.destroyAllWindow()
elif k == ord('s'): # 's' key
    cv2.imwrite('testgray.png',img)
    cv2.destroyAllWindow()

cv2.namedWindow()가 추가되었습니다. 이 함수는 윈도우를 고정으로 할 것인지, 사용자가 크기를 조절할 수 있는지를 나타냅니다
cv2.WIDNOW_AUTOSIZE : 원본 이미지 크기로 고정해 윈도우를 생성
cv2.WINDOW_NORMAL : 원본 이미지 크기로 윈도우를 생성하되 사용자가 크기를 조절할 수 있음

Matplotlib을 사용해 시각화하기

일반적으로 *.py 파일로 실행하면 윈도우가 잘 나옵니다. 그러나 쥬피터 노트북에서 작업하는 경우(특히 Mac 환경) 무한 로딩이 걸리는 경우가 있습니다. 이 경우 matplotlib 라이브러리로 시각화를 하곤 합니다

import cv2
from matplotlib import pyplot as plt 

img = cv2.imread('test.jpg', cv2.IMREAD_COLOR)

b, g, r = cv2.split(image)
image2 =cv2.merge([r,g,b])

plt.imshow(im2)
plt.xticks([]) # x축 눈금
plt.yticks([]) # y축 눈금
plt.show()

OpenCV는 BGR로 사용하지만 Matplotlib는 RGB로 이미지를 보여주기 때문에 cv2.split(image)를 사용해 이미지 파일을 분리한 후, cv2.merge()를 이용해 이미지 b,r을 변경했습니다

카메라로부터 비디오 읽기

import cv2

cap = cv2.VideoCapture(0)
if cap.isOpen():
	print('width: {}, height : {}'.format(cap.get(3), cap.get(4))
	
while True:
	ret, fram = cap.read()
	
	if ret:
		gray = cv2.cvtColor(fram, cv2.COLOR_BGR2GRAY)
		cv2.imshow('video', gray)
		k == cv2.waitKey(1) & 0xFF
		if k == 27:
			break
	else:
		print('error')

cap.release()
cv2.destroyAllWindows()	

cv2.VideoCapture()를 사용해 비디오 캡쳐 객체를 생성할 수 있습니다. 안의 숫자는 장치 인덱스(어떤 카메라를 사용할 것인가)입니다. 1개만 부착되어 있으면 0, 2개 이상이면 첫 웹캠은 0, 두번째 웹캠은 1으로 지정합니다
cap.isOpen() : 비디오 캡쳐 객체가 정상적으로 Open되었는지 확인합니다
while True: 특정 키를 누를때까지 무한 반복을 위해 사용했습니다. 이 스타일로 많이 코딩합니다!
ret, fram = cap.read() : 비디오의 한 프레임씩 읽습니다. 제대로 프레임을 읽으면 ret값이 True, 실패하면 False가 나타납니다. fram에 읽은 프레임이 나옵니다
cv2.cvtColor() : frame을 흑백으로 변환합니다
cap.release() : 오픈한 캡쳐 객체를 해제합니다

파일로 비디오 읽기 (Video Read)

파일을 직접 읽기도 정말 간단합니다

import cv2

cap = cv2.VideoCapture('vtest.avi')

while(cap.isOpened()):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('frame',gray)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

비디오 저장

import cv2

cap = cv2.VideoCapture(0)

fourcc = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter('output.avi', fourcc, 25.0, (640,480))

while (cap.isOpend()):
    ret, frame = cap.read()

    if ret:
        # 이미지 반전,  0:상하, 1 : 좌우
        frame = cv2.flip(frame, 0)

        out.write(frame)

        cv2.imshow('frame', frame)

        if cv2.waitKey(0) & 0xFF == ord('q'):
            break
    else:
        break

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

cv2.VideoWriter(outputFile, fourcc, frame, size) : fourcc는 코덱 정보, frame은 초당 저장될 프레임, size는 저장될 사이즈를 뜻합니다 cv2.VideoWriter_fourcc('D','I','V','X') 이런식으로소 사용하곤 합니다 적용 가능한 코덱은 DIVX, XVID, MJPG, X264, WMV1, WMV2 등이 있습니다

Reference


카일스쿨 유튜브 채널을 만들었습니다. 데이터 사이언스, 성장, 리더십, BigQuery 등을 이야기할 예정이니, 관심 있으시면 구독 부탁드립니다 :)

PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다

이 글이 도움이 되셨거나 다양한 의견이 있다면 댓글 부탁드립니다 :)

Buy me a coffeeBuy me a coffee





© 2017. by Seongyun Byeon

Powered by zzsza