본문 바로가기
데이터 과학 관련 스터디/OpenCV

[Open CV] 파이썬 동영상 파일 & 웹캠 읽기, 저장하기

by inhovation97 2022. 3. 3.
본 글은 파이썬으로 만드는 OpenCV프로젝트 서적의 내용을 포스팅하는 내용입니다. 
2장 기본 입출력
해당 실습은 cv2 라이브러리를 이용하여 진행합니다.

1. 동영상 읽기
2. 웹캠 켜기
3. 웹캠 크기 조절하기
4. 웹캠 이미지 저장하기
5. 웹캠 동영상 저장하기

 

1. 동영상 읽기

 

동영상은 이미지 프레임 하나하나를 연속적으로 읽어오는 원리입니다.

그 속도가 영상의 속도를 좌우하는데, 보통의 동영상은 40fps(frames per second)인 경우가 가장 많다고 합니다.

fps에 맞는 지연속도를 구하여 프레임이 들어가는 속도를 조절하는데, 그 계산은 아래와 같습니다.

 

지연시간 = 1000/fps

 

1초를 밀리초 단위로 환산해서 제공해야하기에 1000으로 계산합니다. 

지연시간이 길다는 건 fps값이 작아 프레임을 넣는 시간이 길어지는 것입니다. 

 

# play video
import cv2

video_file = '../CV2/video/sarang1.mp4'

cap = cv2.VideoCapture(video_file)      # 동영상 캡처 객체 생성
if cap.isOpened():                      # 캡처 객체 초기화 확인
    while True: 
        ret, img = cap.read()           # 다음 프레임 읽기
        if ret:                         # 프레임 읽기 정상
            cv2.imshow(video_file, img) # 화면에 표시
            cv2.waitKey(25)             # 25ms 지연(40fps로 가정)
        else:                           # 다음 프레임을 읽을 수 없음.
            break
    
else:
    print("Can't open video.")          # 캡처 객체 초기화 실패
cap.release()                           # 캡쳐 자원 반납
cv2.destroyAllWindows()

 

cv2.VideoCapture - 비디오 캡처 객체 생성자

입력 : 동영상 파일 경로 or 카메라 장치 번호(그냥 0부터 인덱스 넣어주면 됨)

출력 : 동영상 캡처 객체

 

xxx.isOpened() - 객체 초기화 확인 ( 파일이나 카메라 장치에 제대로 연결돼 있는지 확인)

출력 : 초기화 여부 (True/False)

 

xxx.read() - 영상 프레임 읽기

출력 : ret (프레임 읽기 성공 또는 실패 여부 T/F), img (프레임 이미지 numpy배열 or None)

 

xxx.release() - 캡처 자원 반납

 

 

결과

 

 

 

2. 웹캠 읽기

 

# turn on web camera
import cv2

video_file = '../CV2/video/sarang1.mp4'

cap = cv2.VideoCapture(0)               # 웹캠 객체 생성
if cap.isOpened():                      # 캡처 객체 초기화 확인
    while True: 
        ret, img = cap.read()           # 다음 프레임 읽기
        if ret:                         # 프레임 읽기 정상
            cv2.imshow('camera', img)
            if cv2.waitKey(1) != -1:    # 화면에 표시
                break
        else: 
            print('no frame')           # 다음 프레임을 읽을 수 없음.
            break
    
else:
    print("Can't open video.")          # 캡처 객체 초기화 실패
cap.release()                           # 캡쳐 자원 반납
cv2.destroyAllWindows()

 

거의 비슷합니다.

cv2.VideoCapture()함수에 웹캠 장치 번호만 입력하면 됩니다.   

이 경우는 프레임의 끝이 없기 때문에 cv2.waitKey(1) 함수를 이용하여 버튼을 누르면 break가 걸리도록 if문을 걸어줌.

 

 

 

3. 카메라 비디오 속성 제어 ( 영상 크기 조절 )

 

아쉽게도 카메라가 아닌 동영상 파일에 프레임 크기를 재지어하는 것은 적용되지 않습니다.

 

import cv2

cap = cv2.VideoCapture(0)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print("Oringinal width: %d, height: %d" %(width, height))

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print('Resized width: %d, height: %d' % (width, height))

if cap.isOpened():
    while True:
        ret,img = cap.read()
        if ret:
            cv2.imshow('camera', img)
            if cv2.waitKey(1) != -1: # 지정된 시간동안 키입력이 없으면 -1을 계속 반환
                break
        else:
            print('no frame!')
            break
else:
    print('can`t open camera!')
cap.release()
cv2.destroyAllWindows()

 

cv2.CAP_PROP_FRAME_WIDTH() - 프레임 폭

cv2.CAP_PROP_FRAME_HEIGHT() - 프레임 높이

cv2.CAP_PROP_FRAME_FPS() - 초당 프레임 수

cv2.CAP_PROP_FRAME_MSEC() - 동영상 파일의 프레임 위치(ms)

cv2.CAP_PROP_FRAME_AVI_RATIO() - 동영상 파일의 상대 위치(0:시작, 1:끝)

cv2.CAP_PROP_FRAME_FOURCC() - 동영상 파일 코덱 문자

cv2.CAP_PROP_FRAME_AUTOFOCUS() - 카메라 자동 초점 조절

cv2.CAP_PROP_FRAME_ZOOM() - 카메라 줌

 

-> 위의 각 속성 ID를 get()에 전달하면 해당 속성 값을 구할 수 있고, set() 함수에 아이디와 함께 전달하면 값을 지정할 수 있습니다.

 

4. 웹캠으로 사진찍기

 

import cv2

cap= cv2.VideoCapture(0)
if cap.isOpened():
    
    while True:
        ret,frame = cap.read()
        
        if ret:
            cv2.imshow('camera', frame)

            if cv2.waitKey(1) != -1:
                cv2.imwrite('photo.jpg', frame)
                break
            
        else:
            print('no frame')
            break
else:
    print('no camera!')
cap.release()
cv2.destroyAllWindows()

 

cv2.waitKey() 함수를 이용하여 아무키나 누르면 해당 프레임을 저장함.

 

5. 웹캠으로 녹화하기

 

import cv2
cap = cv2.VideoCapture(0)
if cap.isOpened:
    file_path = '../CV2/video/record.mp4'
    fps = 25.40
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')            # 인코딩 포맷 문자
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    size = (int(width), int (height))                   # 프레임 크기
    
    out = cv2.VideoWriter(file_path, fourcc, fps, size) # VideoWriter 객체 생성
    while True:
        ret, frame = cap.read()
        if ret:
            cv2.imshow('camera-recording', frame)
            out.write(frame)                            # 파일 저장
            if cv2.waitKey(int(1000/fps)) != -1:
                break
        else:
            print('no file!')
            break
    out.release()                                       # 파일 닫기
else:
    print("Can`t open camera!")
cap.release()
cv2.destroyAllWindows()

 

여러 프레임을 동영상으로 저장하기 위해서는 cv2.VideoWriter()라는 새로운 API가 필요합니다.

cv2.VideoWriter(file_path, fourcc, fps, size) - 비디오 저장 클래스 생성자

입력 : 차례대로 비디오 파일 저장 경로, 비디오 인코딩 형식 4글자, 초당 프레임 수, 프레임 폭과 높이

출력 : 비디오 저장 객체

 

비디오 저장 객체.write() - 프레임 저장

입력 : 저장할 프레임(numpy 배열)

 

cv2.VideoWriter_fourcc( c1, c2, c3, c4) - fourcc 코드생성

4개의 인코딩 포맷 문자를 입력하면 코드 값을 생성해 내는 함수로 4개의 문자를 한 문자당 8비트씩 사용하여 각 자릿수에 맞게 표현해줌.

인코딩 포맷 문자는 사용할 운영체제에서 지원하는 코덱 중에서 원하는 이름을 지정하면 됨.

댓글