视频间隔帧抽取工具(多进程)

工程:https://smuwm007.feishu.cn/docs/doccnZco1aRkBCvnqU3etmKfase

介绍

  • 视频放在videos目录下,输出结果会放在out目录下,视频名称不能相同

目录结构

  • Root
    • images
    • 本脚本.py
import cv2
import argparse
import os
import shutil
import os
from multiprocessing import Pool,cpu_count
import time

class MainProgress:
    def __init__(self,root,savePath,interval):
        self.savePath=savePath
        self.interval = interval

        '''初始化多进程池'''
        self.p = Pool()
        self.root=root
        rootDirs = os.listdir(root)
        for dir in rootDirs:
            if(dir=="out"):
                shutil.rmtree(os.path.join(root,dir))
            if(dir=="videos"):
                self.videosPath = os.path.join(root,dir)
                self.videoList=os.listdir(self.videosPath)
                self.fileCount = len(self.videoList)
        self.MakeSaveDir()



    def MakeSaveDir(self):
        os.makedirs(self.savePath,exist_ok=True)



    def Run(self,multiProcessFlag=True,num_workers=cpu_count()):

        print("=========================================")
        print(" MultiProcess ")
        print("=========================================")

        '''自动batch:通过给多进程分割总任务每个进程处理一个batch'''
        if (self.fileCount < num_workers):
            num_workers=self.fileCount
        batch = int(self.fileCount / num_workers)



        start=0
        end =batch
        sub=SubProcess(self.videosPath,self.videoList,self.savePath,self.interval)
        stopFlag=False
        while True:
            '''为每个子list启动多进程'''
            if multiProcessFlag==True:
                self.p.apply_async(sub.Run, args = (start,end,))
            else:
                # 单进程模式测试功能函数是否报错(因为多进程报错不会有提示)
                sub.Run(start,end)

            start += batch
            end += batch
            if stopFlag==True:
                break
            if end>=self.fileCount and stopFlag != True:
                end=self.fileCount
                '''保证这个if只会在batch不足的时候运行一次然后跳出循环'''
                stopFlag=True

        #等待多进程执行完毕后释放
        self.p.close()
        self.p.join()

class SubProcess:
    # 子进程初始化,可以初始化类似于目录之类的
    def __init__(self,subPath,subList,savePath,interval):
        self.savePath = savePath
        self.subPath = subPath
        self.subList = subList
        self.interval = interval
    #子进程要做的任务
    def Run(self,start,end):

        subCount = start
        while subCount!=end:
            video = self.subList[subCount]
            vPath = os.path.join(self.subPath,video)
            self.VideoShot(vPath,self.savePath,video,subCount,self.interval)
            subCount += 1
    def ProcessBar(self,cnt,max,fileName):
        i = (cnt / max) * 100
        i = int(i)
        # print("\r", end="")
        print("\n Pid = " + str(os.getpid())+" {}...ing: {}%: ".format(fileName,i), "▋" * (i // 2), end="")

    def VideoShot(self,i_video, o_video, videoName,videoNum,interval):
        cap = cv2.VideoCapture(i_video)
        num_frame = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        expand_name = '.jpg'
        if not cap.isOpened():
            print("Please check the path.")
        cnt = 0
        count = 0
        while True:
            # ret, frame = cap.read()
            #当需要抽取帧图片的时候才读取frame比直接读取更节省时间
            ret = cap.grab()

            cnt += 1
            self.ProcessBar(cnt,num_frame,videoName)
            if cnt % interval == 0:

                ret,frame = cap.retrieve()
                count += 1
                cv2.imwrite(os.path.join(o_video,videoName+str(videoNum)+"_"+ str(count) + expand_name), frame)

            if not ret:
                break

if __name__ =="__main__":
    t1=time.time()
    print("start-------------------------------------")
    # splitRatio = sys.argv[1]
    #mode = sys.argv[1]  # 第二个参数输入修改的文件目录
    #root: 工作根目录 savePath: 保存的文件夹路径(不存在则创建) interval: 间隔多少帧抽取一张
    mProgress = MainProgress(root="./",savePath="./out",interval=15)
    mProgress.Run(multiProcessFlag=True)

    print("end--------------------------------------")
    t2=time.time()
    print("Used time: ",t2-t1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值