본문 바로가기

Fields Applied with AI/컴퓨터 비전 Computer Vision

Ⅰ. 컴퓨터 비전 기초 (6. 동영상이란?)

  • 동영상(Video) = 영상을 연속적으로 재생하여 마치 움직이는 것처럼 보이는 영상들.
  • 프레임(Frame) = 동영상 속 하나의 영상.
  • 프레임율(Frame Rate)[fps] = 1초 동안 재생되는 프레임수.

# FPS(Frame Per Second) = 프레임율 단위.

# 일반적으로 15~60 fps를 사용하고, 보통 사람 눈에는 25~30 fps정도면 부드럽게 느껴집니다. 프레임율이 높아지면 높은 수준의 동영상을 볼 수 있지만 용량이 커집니다. 이 때문에 코덱이라는 프로그램을 이용해서 압축을 하게 됩니다.

 

 

 

 

 

6-(1) 카메라 처리 예제

Create VideoCapture Object

import sys
import cv2
cap = cv2.VideoCapture()

 

  • cap : 카메라 및 동영상을 처리하는 각종 함수가 들어있는 VideoCapture 클래스의 객체. 

 

 

Open Camera 

cap.open(0)
if not cap.isOpened():
    print("Camera open failed!")
    sys.exit()

 

  • cap객체의 카메라 열기 함수인 open()을 사용하여 컴퓨터의 웹카메라를 오픈합니다.
  • 카메라를 열때 컴퓨터의 기본 카메라부터 설정된 순서대로 0,1,2...으로 인덱스가 부여됩니다. (만약 카메라가 2대라면 0,1 인덱스가 존재합니다.) 위 상황에서 0은 컴퓨터의 기본 카메라를 오픈한다는 뜻입니다. 
  • cap객체의 카메라가 제대로 열렸는지 확인하는 함수인 isopend() 사용하여 제대로 열리지 않았을 때 프로그램을 중단하는 if문을 작성합니다.

 

 

Print Camera Frame Size

print('Frame width:', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))
print('Frame height:', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

Frame width: 640

Frame height: 480

 

  • cap객체의 여러 가지 속성을 불러오는 함수인 get()을 사용하여 카메라 프레임의 가로 길이와 세로 길이를 출력합니다.

 

 

Process Camera Frame

while True:
    ret, frame = cap.read()
    if not ret:
        break
    inversed = ~frame  
    cv2.imshow('frame', frame)
    cv2.imshow('inversed', inversed)
    if cv2.waitKey(10) == 27:
        break
cap.release()
cv2.destroyAllWindows()

 

  • 동영상을 원하는 조건이 만족할 때까지 재생할 수 있도록 무한 루프를 이용합니다.
  • 동영상은 영상은 연속이므로 하나의 영상 프레임을 읽어오며 연속적으로 빠르게 처리하는 과정으로 진행됩니다.
  • while True는 break문이 나올때까지 실행한다는 뜻입니다.
  • cap객체의 동영상의 프레임을 읽어오고 성공 실패 유무까지 반환하는 함수인 read()를 이용하여 정보를 할당합니다.
  • ret : 동영상 프레임을 읽어오는데 성공 유무(True or False)
  • Frame : 현재의 동영상 프레임 1개 array.
  • 만약 ret에 False값으로 할당되어 프레임을 불러오는데 실패한다면 break를 합니다.
  • inversed : 읽어온 프레임 1장 frame의 반전된 영상.
  • cv2의 imshow()함수를 통해 정상적인 frame과 반전된 frame을 불러옵니다. 이때 프레임은 정지된 영상입니다.
  • cv2의 waitKey() 함수를 사용하여 10ms(0.01s) 대기 후 다음 명령문으로 넘어가거가 ESC키(27)을 입력하면 break 되도록 구성합니다. 즉, ESC 키를 누르기 전까지는 하나의 프레임은 0.01s 마다 넘어가게 됩니다. 이 경우에 FPS는 100이 됩니다. (1초에 100장 프레임 재생)
  • 카메라를 통한 프레임을 읽어오는 경우는 끝이 없으므로 ESC 키를 누르기 전까지는 무한루프에서 계속 동작하게 됩니다.

 

 

 

 

6-(2) 동영상 처리 예제

Upload Video File

from google.colab import files
upload = files.upload()

Saving video1.mp4 to video1.mp4

 

 

Create VideoCapture Object

import sys
import cv2
cap = cv2.VideoCapture('video1.mp4')
 
if not cap.isOpened():
    print("Video open failed!")
    sys.exit()

 

  • cap : 카메라 및 동영상을 처리하는 각종 함수가 들어있는 VideoCapture 클래스의 객체.
  • VideoCapture 객체를 만들때 열고 싶은 카메라 인덱스 또는 비디오 파일을 인자로 주면 따로 open() 함수 없이 객체를 만들고 바로 비디오 파일을 열수 있습니다.

 

 

Print Video Frame Size, Frame Count, FPS

print('Frame width:', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))
print('Frame height:', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('Frame count:', int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))
 
fps = cap.get(cv2.CAP_PROP_FPS)
print('FPS:', fps)

Frame width: 1280

Frame height: 720

Frame count: 85

FPS: 24.0

 

  • cap객체의 여러 가지 속성을 불러오는 함수인 get()을 사용하여 카메라 프레임의 가로 길이와 세로 길이, 프레임수, FPS를 불러옵니다.
  • fps는 뒤에도 사용할 변수이므로 따로 할당하고 출력했습니다.

 

 

Process Video Frame

delay = round(1000 / fps)
 
while True:
    ret, frame = cap.read()
    if not ret:
        break
    edge = cv2.Canny(frame, 5, 150)
    cv2.imshow('frame', frame)
    cv2.imshow('edge', edge)
    if cv2.waitKey(delay) == 27:
        break
cap.release()
cv2.destroyAllWindows()

 

 

  • 카메라 처리 예제와 동일하게 무한 루프를 동해서 처리합니다.
  • delay : 1000ms(1s)를 원래 동영상의 fps로 나눈 값. (동영상 프레임 1장이 지속되는 시간)
  • dege : cv2의 Canny() 함수를 사용하여 현재 frame의 가장자리 부분인 edge만 추출하여 저장합니다.
  • cv2의 waitKey() 함수를 사용할 때 프레임 지속 시간은 미리 계산한 delay로 설정합니다. 동영상의 경우에는 FPS가 이미 정해져 있으므로 카메라 처리 예제와 다릅니다.
  • 동영상은 카메라와 다르게 끝이 있으므로 모든 프레임을 다 읽으면 ret에 False가 할당되고 break를 통해 빠져나오게 됩니다.

 

 

 

 

6-(3) 카메라 동영상 저장

Create VideoCapture Object

import sys
import cv2
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Camera open failed!")
    sys.exit()

 

  • 이전 예제들과 동일하게 VideoCapture 객체를 생성하면서 기본 카메라 0을 오픈합니다.

 

 

Assign Camera Frame Size, FPS

w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)

 

  • cap객체의 여러 가지 속성을 불러오는 함수인 get()을 사용하여 카메라 프레임의 가로 길이와 세로 길이, FPS를 불러옵니다.

 

 

Create VideoWriter Object 

fourcc = cv2.VideoWriter_fourcc(*'DIVX') # *'DIVX' == 'D', 'I', 'V', 'X'
delay = round(1000 / fps)
out = cv2.VideoWriter('output.avi', fourcc, fps, (w, h))
if not out.isOpened():
    print('File open failed!')
    cap.release()
    sys.exit()

 

  • fourcc : 촬영하는 동영상을 DIVX 방식으로 인코딩하는 VideoWriter_fourcc 객체.
  • delay : 동영상의 프레임 1장이 지속되는 시간.
  • out : 촬영하는 동영상을 제목 확장자 'output.avi', 인코딩 방식 'fourcc', fps와 동영상 크기 (w,h)로 저장하는 VideoWriter 객체. 

 

 

Process Camera Video

while True:
    ret, frame = cap.read()
    if not ret:
        break
    edge = cv2.Canny(frame, 50, 150)
    edge_color = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
    out.write(edge_color)
    cv2.imshow('frame', frame)
    cv2.imshow('edge', edge_color)
    if cv2.waitKey(delay) == 27:
        break
cap.release()
out.release()
cv2.destroyAllWindows()

 

  • 카메라 처리 예제와 동일하게 무한 루프를 동해서 처리합니다.
  • edge에는 흑백 영상으로 반환되어 저장되어 있고, VideoWriter 객체는 컬러 영상을 저장하도록 만들었으므로 흑백의 edge 영상을 컬러로 변환시켜 줘야 합니다.
  • out객체의 write() 함수를 이용하여 edge_color 프레임을 저장하게 됩니다.
  • 카메라 동영상을 저장할 때에는 소리없이 영상만 저장됨에 유의합니다.

 

 

 

 

 

*참고 : OpenCV를 활용한 컴퓨터 비전과 딥러닝