[Python] 영상 또는 웹캠에서의 이미지를 프레임 단위로 자르기

조하운·2023년 7월 12일
0

1. 영상으로부터 프레임 단위로 자르기


먼저 영상 데이터로부터 프레임 단위로 잘라 이미지로 바꾸는 법을 알아보자.

파이썬에서는 OpenCV 라이브러리를 사용해서 이미지 처리를 다룬다. 여기서도 OpenCV를 사용하기 위해 import cv2 를 통해 영상 자료를 다룰 것이다.

전체 코드

  import cv2
import os
import base64
from time import localtime
from time import strftime

def get_image(path:str):
    print(cv2.__version__)
    print(" ======= Parsing Video data is : ", path)
    if path:
        filepath = path
    else:
        filepath = '2023032319.mov'

    video = cv2.VideoCapture(f'{filepath}')

    if not video.isOpened():
        print("Could not Open :", filepath)
        exit(0)
        
    length = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
    width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = video.get(cv2.CAP_PROP_FPS)
    
    print("length :", length)
    print("width :", width)
    print("height :", height)
    print("fps :", fps, "\n")

    currunt_time = localtime()
    timestamp = strftime('%Y_%m_%d_%H', currunt_time)
    try:
        if not os.path.exists(timestamp):
            os.makedirs("data/images/"+timestamp)
    except OSError:
        print("Directory is already exists : " + timestamp)
    
    count = 0
    
    while(video.isOpened()):
        ret, img = video.read()
        if(int(video.get(1)) % int(fps) == 0): # get an image for each seconds
            tm = localtime()
            capturedtime = strftime('%Y%m%d_%H%M%S_', tm)
            cv2.imwrite(f'images/{timestamp}/{capturedtime}{str(int(video.get(1)))}.jpg', img)
            data = {"image": img, "filename" : f"{capturedtime}{str(int(video.get(1)))}"}
            print("Saved frame number:" , str(int(video.get(1))))
            count += 1
            yield data
        if(ret == False):
            break
    video.release()

설명

나는 이 쓰레기 무단투기 프로젝트를 진행하기 위해서 좀 더 특수한 목적이 있는 코드를 구현했다. 위 코드처럼 작성했을 때 얻을 수 있는 기능이 아래와 같다.

  1. 영상을 내가 원하는 프레임 단위로 자를 수 있음(예를 들면 1초에 3장, 1초에 6장 등)
  2. 프레임을 잘라 이미지로 만드는 시점의 시각을 파일 이름으로 지정할 수 있음
  3. 1시간 단위로 이미지를 구별할 수 있는 폴더를 생성하여 그 안에 같은 시간대에 찍힌 이미지를 저장함

2. 실시간 카메라로부터 프레임 단위로 자르기

사전 준비

카메라를 데스크톱에 연결하여 실시간으로 이미지를 자르기 위해서는 먼저 카메라가 연결되어 있어야 한다. cam = cv2.VideoCapture(0) 명령을 실행하면 cam 변수에 실시간 카메라 객체가 할당된다. VideoCapture(0) 에서 0은 보통 데스크톱에 카메라가 연결될 경우 default로 0번으로 인식을 하기 때문에 다른 설정을 하지 않았다면 위의 명령으로 정상적인 작동이 될 것이다.

전체 코드

  import cv2
import time
from time import localtime
from time import strftime
import os

def get_image():
    print(cv2.__version__)

    cam = cv2.VideoCapture(0)

    if not cam.isOpened():
        print("Could not Open Camera:")
        exit(0)
    

    currunt_time = localtime()
    timestamp = strftime('%Y_%m_%d_%H', currunt_time)

    try:
        if not os.path.exists(timestamp):
            os.makedirs("data/images/"+timestamp)
    except OSError:
        print("Directory is already exists : " + timestamp)
    
    count = 0
    while True:
        ret, img = cam.read()
        if not ret:
            print("Can't read Camera")
            break
        
        cv2.imshow('CCTV', img)
        if cv2.waitKey(1000): # 1000ms
            count += 1
            tm = localtime()
            capturedtime = strftime('%Y%m%d_%H%M%S_', tm)
            #cv2.imwrite(f'data/images/{timestamp}/{capturedtime}.jpg', img)
            data = {"image": img, "filename" : f"{capturedtime}{str(count)}"}
            yield data # yield path of image
            print("Saved frame number:" , str(count))
        if cv2.waitKey(1000) == ord('q'):
            break
    cam.release()


    # count = 0
    
    # while(video.isOpened()):
    #     ret, frame = video.read()
    #     if(int(video.get(1))% int(fps) == 0):
    #         cv2.imwrite("data/images/" + filepath[-10:-4] + f"/{filepath[-10:-4]}%0d.jpg"% count, frame)
    #         print("Saved frame number:" , str(int(video.get(1))))
    #         count += 1
    #     if(ret == False):
    #         break

if __name__ == "__main__":
    print("hello")
    get_image()

설명

위 코드도 현재 진행하는 프로젝트의 목적에 맞게 특수하게 작성되었다. 실시간 캠을 작동하게 되면 그때 그때의 시간을 기록하는 것이 중요하므로, time 라이브러리를 사용해서 캠이 켜지고 시간이 변화하면서 프레임이 잘릴 때마다의 시점을 파일 이름으로 지정하여 이미지를 저장하도록 한다.

카메라가 실시간으로 켜져 있는 동안에, 위 코드에서는 1000ms 마다 프레임을 캡처하여 이미지로 저장한다. cv.waitKey(1000)이 그 기능이다.

그리고 if cv2.waitKey(1000) == ord('q') if문을 통해 q를 눌렀을 때 자동으로 카메라가 꺼지도록 작성하였다.

3. 결론

Python 에서 대표적인 이미지 처리 라이브러리는 OpenCV와 PIL 로, OpenCV는 이런 비디오, 실시간 캠에서의 이미지 처리를 쉽게 할 수 있도록 하고, PIL은 이미지 데이터 - 바이너리 데이터 변환이 쉽게 되도록 한다.

이 프로젝트를 진행하면서 컴퓨터 비전 관련해서 이미지 전처리가 필요한 Task에서는 python을 가지고 위와 같이 코드를 설계해나가면 되겠다.

profile
| 컴퓨터 비전 | 딥 러닝 | 자율주행 |

0개의 댓글