视频快速抽帧处理/间隔帧推理或负样本获取方法

一、问题描述

在深度学习场景中,面对相对开放的场景,我们经常会需要处理长时间的视频,而花费叫长的时间,就让人头疼。比如为了获取一个厂/小区的所有摄像头下一周的画面背景,当然其极高的同质性也不可能每一帧画面都获取,就需要一种快速的间隔帧抽帧方案。
为了优化读取图片的速度,经过调研研究后,可将图片的获取分为两个阶段:读取 ,解码,分别对应opencv的VideoCapture函数的grab()和retrieve()两个子函数。实验证明可以有效的加快视频画面的抽取效率。具体的实验代码如下。

二、视频抽帧处理代码

import cv2
import os
import time
import threading
import random

def readAll_by_grab(video_file_path):
    videRead = cv2.VideoCapture(video_file_path)
    while True:
        tag = videRead.grab()
        if not tag:
            break
        ret, frame = videRead.retrieve()
        time.sleep(0.01)
    videRead.release()

def readAll_by_cvread(video_file_path):
    videRead = cv2.VideoCapture(video_file_path)
    while True:
        tag, frame = videRead.read()
        if not tag:
            break
        time.sleep(0.01)
    videRead.release()


def read_by_grab(video_file_path):
    videRead = cv2.VideoCapture(video_file_path)
    fps = videRead.get(cv2.CAP_PROP_FPS)
    idx = 0
    choose_idx = random.randint(0, fps)
    while True:
        idx += 1
        tag = videRead.grab()
        if not tag:
            break
        if idx % fps == choose_idx:
            ret, frame = videRead.retrieve()
            time.sleep(0.01)
    videRead.release()

def read_by_cvread(video_file_path):
    videRead = cv2.VideoCapture(video_file_path)
    fps = videRead.get(cv2.CAP_PROP_FPS)
    idx = 0
    choose_idx = random.randint(0, fps)
    while True:
        tag, frame = videRead.read()
        if not tag:
            break
        if idx % fps == choose_idx:
            time.sleep(0.01)
    videRead.release()
    
if __name__ == '__main__':
    '''
    readAll_by_grab:        耗时: 45.87809038162231
    readAll_by_cvread:      耗时: 45.898966550827026
    read_by_grab:           耗时: 11.92901349067688
    read_by_cvread:         耗时: 17.04421854019165
    '''
    video_file_path = r'd:\Data\trash\test_louyou_06112\16-26-29.avi'
    for way in [readAll_by_grab, readAll_by_cvread, read_by_grab, read_by_cvread]:
        start_time = time.time()
        way(video_file_path)
        print(time.time() - start_time)

三、进阶采用多线程进行加速推理

import cv2
import os
import time
import threading
import random

def threading_operate(threads_nums, index, video_file_path):
    videRead = cv2.VideoCapture(video_file_path)
    fps = videRead.get(cv2.CAP_PROP_FPS)
    idx = 0
    choose_idx = random.randint(0, 25)
    while True:
        tag = videRead.grab()
        if not tag:
            break
        if idx % (threads_nums * fps) == (choose_idx + fps * index):
            ret, frame = videRead.retrieve()
            time.sleep(0.01)
    videRead.release()

def video_by_grad_threads(video_file_path):
    threads_nums = 2
    threads = []
    for index in range(threads_nums):
        t = threading.Thread(target=threading_operate, args=[threads_nums, index, video_file_path])  # 传个任务,和参数进来
        t.start()  # 线程开始
        threads.append(t)

    for t in threads:
        t.join()
            
if __name__ == '__main__':
    '''
    video_by_grad_threads:          耗时: 10.581750392913818
    '''
    video_file_path = r'd:\Data\trash\test_louyou_06112\16-26-29.avi'
    start_time = time.time()
    way(video_file_path)
    print(time.time() - start_time)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值