Shortcuts

Source code for caer.video.extract_frames

#    _____           ______  _____ 
#  / ____/    /\    |  ____ |  __ \
# | |        /  \   | |__   | |__) | Caer - Modern Computer Vision
# | |       / /\ \  |  __|  |  _  /  Languages: Python, C, C++, Cuda
# | |___   / ____ \ | |____ | | \ \  http://github.com/jasmcaus/caer
#  \_____\/_/    \_ \______ |_|  \_\

# Licensed under the MIT License <http://opensource.org/licenses/MIT>
# SPDX-License-Identifier: MIT
# Copyright (c) 2020-2021 The Caer Authors <http://github.com/jasmcaus>


import math
import time
import cv2 as cv

from .._internal import _check_target_size
from ..path import list_videos, exists, mkdir
from .constants import FRAME_COUNT, FPS
from ..io import imsave, resize

__all__ = [
    'extract_frames'
]

[docs]def extract_frames(input_folder, output_folder, target_size=None, recursive=False, label_counter = None, max_video_count=None, frames_per_sec=None, frame_interval=None, dest_filetype='jpg') -> int: r""" Extract frames from videos within a directory and save them as separate frames in an output directory. Args: input_folder (str): Input video directory. output_folder (str): Output directory to save the frames. target_size (tuple): Destination Image Size (tuple of size 2) label_counter (int): Starting label counter (optional) max_video_count (int): Number of videos to process. frames_per_sec (int, float): Number of frames to process per second. frame_interval (int, float): Interval between the frames to be processed. dest_filetype (str): Processed image filetype (png, jpg). Default: png Returns: label_counter (after processing) """ dest_filetype.replace('.', '') processed_videos = 0 vid_count = 0 # to check if < max_video_count if not exists(input_folder): raise ValueError('Input folder does not exist', input_folder) if target_size is not None: _ = _check_target_size(target_size) video_list = list_videos(input_folder, recursive=recursive, use_fullpath=True, verbose=0) if len(video_list) == 0: raise ValueError(f'No videos found at {input_folder}') if label_counter is None: label_counter = 0 if max_video_count is None: max_video_count = len(video_list) if not exists(output_folder): mkdir(output_folder) # Begin Timer start = time.time() for vid_filepath in video_list: if vid_count < max_video_count: capture = cv.VideoCapture(vid_filepath) video_frame_counter = 0 vid_count += 1 # Find the number of frames and FPS video_frame_count = int(capture.get(FRAME_COUNT)) - 1 video_fps = math.ceil(capture.get(FPS)) file = vid_filepath[vid_filepath.rindex('/')+1:] if frames_per_sec is not None: if frame_interval is None: interval = _determine_interval(video_fps/frames_per_sec) # eg: 30//15 else: interval = frame_interval # if frames_per_sec and frame_interval are both None, we assume that each frame should be processed else: interval = 1 # processed_frames = (video_frame_count//video_fps) * frames_per_sec print(f'{vid_count}. Reading \'{file}\'. Frame Count: {video_frame_count}. FPS: {video_fps}. Processed frames: {video_frame_count//interval}') # Start converting the video while capture.isOpened(): _, frame = capture.read() if target_size is not None: frame = resize(frame, target_size=target_size) # Write the results back to output location as per specified frames per second if video_frame_counter % interval == 0: imsave(f'{output_folder}/{file}_{label_counter}.{dest_filetype}', frame) video_frame_counter += 1 label_counter += 1 # print('Frame counter: ', video_frame_counter) video_frame_counter += 1 # If there are no more frames left if video_frame_counter > (video_frame_count-1): capture.release() processed_videos += 1 break # End timer end = time.time() # Printing stats taken = end-start minu = taken // 60 sec = taken % 60 if processed_videos > 1: print(f'[INFO] {processed_videos} videos extracted in {minu:.0f}m {sec:.0f}s') else: print(f'[INFO] {processed_videos} video extracted in {minu:.0f}m {sec:.0f}s') return label_counter
def _determine_interval(x) -> int: y = '{x:.1f}' inde = y.find('.') + 1 if inde == -1: # if no '.' (if an integer) return x if int(y[inde]) < 5: return math.floor(x) else: return math.ceil(x)
Read the Docs v: stable
Versions
latest
stable
Downloads
pdf
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.