OpenCV 개요
- Computer Vision : 사람의 시각적인 부분을 기계로 구현하는것을 목적으로 하는 딥러닝 분야
- 이미지, 동영상 등의 처리를 지원하는 라이브러리
- C++로 제작되어 있고 Java, Android, Python 등 다양한 언어에서 구현 가능
- 특히 Python에서 OpenCV를 사용할 경우 Numpy, Matplotlib 등의 라이브러리들과 바로 연동 가능
import numpy as np
import matplotlib.pyplot as plt
# OpenCV 임포트
import cv2
# 이미지 불러오기
cat = cv2.imread('image/image_cat.jpg')
# OpenCV와 matplotlib간 연동됨
plt.imshow(cat);
OpenCV의 색상 체계
- 일반적인 이미지는 RGB 색상을 사용
- OpenCV는 BGR 색상 체계를 사용함(그래서 RGB를 그대로 사용하면 Red계열 색상이 Blue계열로 변경되어 출력됨)
- 초기에는 알파벳 순서대로 BGR로 쓰다가 이후에 색상 주파수가 낮은 순으로 RGB로 바뀌어 현재는 RGB가 대중적으로 사용됨
- OpenCV에서는 RGB를 BGR로 변환하여 불러와야 함
cat = cv2.imread('image/image_cat.jpg')
# cvtColor : 색상 변환 함수
cat2 = cv2.cvtColor(cat, cv2.COLOR_RGB2BGR)
# x축, y축 좌표 눈금을 없애고 싶을때
plt.xticks([])
plt.yticks([])
plt.imshow(cat2);
이미지 색상 변환
- 컬러 이미지(RGB)
- 흑백 이미지(Gray) → 0 ~ 255 사이의 흑백 픽셀값으로 구성된 이미지
- 컬러 이미지는 용량이 크고 연산량이 많기 때문에 실시간 처리가 힘들고, 이를 간소화시켜 계산과 연산을 용이하게 하기 위해 흑백이미지나 이진이미지를 사용
- 컬러 이미지는 채도와 명도에 영향을 받기 때문에 이를 최소화 하기 위함
- 명도(밝은 정도) - 밤에 색상을 볼 때 정확한 색상을 보여주지 못하는 경우 존재
- 채도(탁한 정도) - 색상에 빛을 강하게 비추는 경우 정확한 색상을 보지 못하는 경우가 존재
- 이진 이미지(binary) → 0(검정)과 255(흰) 두가지 색상으로만 구성된 이미지
- 배경과 객체를 구분
- 관심 영역과 비관심 영역을 분리
- 필터를 만들거나 단순한 이미지 처리를 할 경우 사용
흑백(Gray) 이미지 만드는 방법
1. 기존 컬러 이미지를 Gray로 불러서 출력하기
# 이미지를 불러올때 gray로 받아주고 출력시에도 gray 색상으로 변환하여 출력
cat_gray = cv2.imread("image/image_cat.jpg", cv2.IMREAD_GRAYSCALE)
plt.imshow(cat_gray, cmap='gray');
2. 컬러 이미지를 그대로 불러온 다음 cvtColor를 통해 gray로 변환 후 출력하기
cat2 = cv2.imread("image/image_cat.jpg")
cat2_gray = cv2.cvtColor(cat2, cv2.COLOR_BGR2GRAY)
plt.imshow(cat2_gray, cmap='gray');
이진(binary) 이미지 만들기
- 기존 이미지가 컬러 이미지라면 gray로 변환 후에 이진 이미지로 만들어줘야 함!
# threshold : 특정 기준을 통해서 데이터를 변환시켜주는 함수(문턱(경계)이라는 뜻)
# (이미지, 경계 기준값, 경계값보다 클 경우 적용되는 값, 경계값 적용 방식)
# 경계 기준값 : 0 ~ 255 값 중에서 선택
# 적용값 : 기준값보다 큰 경우에 할당되는 값(150보다 크면 255, 작으면 0)
_, bi_cat = cv2.threshold(cat2_gray, 150, 255, cv2.THRESH_BINARY)
# _ : 첫번째 리턴값은 받지 않음(경계값)
# bi_cat : 두번째 리턴값은 threshold가 적용된 이미지 데이터
plt.imshow(bi_cat, cmap='gray');
경계값 적용 방식 종류
- cv2.THRESH_BINARY : 픽셀값이 경계값보다 크면 value(적용값), 아니면 0을 할당(흰색, 검은색으로만 표시)
- cv2.THRESH_BINARY_INV : THRESH_BINARY의 반대(픽셀값이 경계값보다 크면 0, 아니면 value를 할당)
- cv2.THRESH_TRUNC : 픽셀값이 경계값보다 크면 경계값, 아니면 픽셀값을 그대로 할당
- cv2.THRESH_TOZERO : 픽셀값이 경계값보다 크면 픽셀값, 아니면 0을 할당(검은색을 좀 더 부각)
- cv2.THRESH_TOZERO_INV : THRESH_TOZERO의 반대(픽셀값이 경계값보다 크면 0, 아니면 픽셀값 할당)
동영상 혹은 카메라(웹 캠) 불러오기
- 카메라로부터 프레임 캡쳐 후 연결하여 영상으로 보여주기
- 동영상 파일로부터 프레임 캡쳐 후 연결하여 영상으로 보여주기
# 영상 파일을 다룰 때는 예외처리(제대로 동작하지 않았을 경우에 대한 처리)를
# 해주는 것이 오류방지에 좋음
# 1. 영상 파일에서 프렝미단위로 사진을 캡쳐해 받아오기
try :
# VideoCapture : 동영상을 프레임 단위로 캡쳐
# 1) 웹 캠으로 부터 캡쳐
# 카메라번호 - USB포트 번호, 일반적으로 0
cap = cv2.VideoCapture(0)
# 2) 동영상으로 부터 캡쳐
# cap = cv2.VideoCapture("image/video.mp4")
print("비디오 캡쳐 시작")
except :
print("비디오 캡쳐 실패")
# 2. 캡쳐해 온 프레임을 계속해서 한 장씩 읽어와 연결하여 출력(영상으로 보여주겠음!)
while True:
# read : 캡쳐한 이미지 프레임을 한 장씩 읽어오는 함수
# ret : 읽기 성공여부(True, False)
# frame : 읽어온 이미지 데이터(numpy 배열 타입)
ret, frame = cap.read()
# 프레임을 읽지 못했거나 영상의 모든 프레임을 다 읽었을 경우 종료
if ret == False :
print("프레임 읽기 실패 or 프레임 모두 읽음!")
# 비디오 캡쳐 종료
cap.release()
# 생성한 창을 모두 닫아주기
cv2.destroyAllWindows()
break
# 윈도우 창 크기 변경
# frame = cv2.resize(frame, (1000, 700))
# 흑백 영상 출력
# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# imshow : 새 윈도우 창을 띄워서 이미지를 계속 출력(윈도우 창 이름, 전달받을 프레임)
cv2.imshow("Video", frame)
# waitKey : 키보드의 특정 키 값을 입력할 때까지 기다리는 명령
# (숫자) : 한 장의 프레임을 읽어들이고 40ms 기다렸다 다음 사진을 읽어들일 수
# 있도록 딜레이를 주는 역할
key = cv2.waitKey(40)
# ex) 영상이 초당 60 프레임이라면 16 ms로 설정
# 영상 초당 프레임수와 waitKey값의 차이가 나면 플레이 자체는 문제 없지만
# 마지막 프레임이 잘리는 현상이 발생할 수 있음
# 재생중에 영상을 끄고 싶을 경우
# 윈도우 창의 X를 누르지 말고 키보드로 멈춰야함(X누르면 에러뜨거나 커널 재시작)
# 27 : 아스키코드로 ESC
# 49 : 아스키코드로 1
if key == 27:
print("동영상 읽기 종료")
cap.release()
cv2.destroyAllWindows()
break
영상 녹화하기
try:
cap = cv2.VideoCapture("image/video.mp4")
print("비디오 캡쳐 시작!!")
except:
print("비디오 캡쳐 실패ㅠㅠ")
# 녹화될 파일 설정
fps = 30.0 # 초당 프레임 수
w = int(cap.get(3)) # 캡쳐한 비디오의 가로(3)크기
h = int(cap.get(4)) # 캡쳐한 비디오의 세로(4)크기
# 영상의 코덱 설정(CODEC : COder and DECoder)
# COder : 음성 또는 영상의 신호를 디지털 신호로 변환
# DECoder : coder의 반대
# DIVX : 일반적으로 avi 파일에 많이 사용되는 코덱
codec = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter("image/record_file.avi", codec, fps, (w,h))
# 녹화 상태 여부
record = False
while True :
ret, frame = cap.read()
if ret == False :
print("비디오 읽기 실패 또는 비디오 모두 읽음")
cap.release()
out.release()
cv2.destroyAllWindows()
break
cv2.imshow("record", frame)
# 영상 녹화 시작 여부
if record : # record가 True가 되면 녹화시작!
out.write(frame)
k = cv2.waitKey(40)
if k == 27 :
print("영상 및 녹화를 종료합니다")
cap.release()
out.release()
cv2.destroyAllWindows()
break
# 숫자 2 키보드
if k == 50 :
print("녹화를 시작합니다")
record=True
'딥러닝' 카테고리의 다른 글
[딥러닝] 로이터뉴스 카테고리분류(RNN+LSTM) (0) | 2022.07.28 |
---|---|
[딥러닝] Simple RNN (0) | 2022.07.26 |
[딥러닝] 데이터 증강(ImageDataGenerator) (0) | 2022.07.26 |
[딥러닝] VGG16 모델 (0) | 2022.07.26 |
[딥러닝] CNN 모델 (0) | 2022.07.26 |