介绍
- 视频放在videos目录下,输出结果会放在out目录下,视频名称不能相同
目录结构
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("\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 = 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-------------------------------------")
mProgress = MainProgress(root="./",savePath="./out",interval=15)
mProgress.Run(multiProcessFlag=True)
print("end--------------------------------------")
t2=time.time()
print("Used time: ",t2-t1)