使用OpenCV实现逐帧获取视频图片

  import os

  import sys

  from concurrent.futures import ThreadPoolExecutor

  import cv2

  def output_img(video_path,img_dir):

  # 由视频逐帧输出图片

  # video_path: 视频文件路径

  # img_dir: 图片保存目录路径,路径不支持中文

  os.makedirs(img_dir,exist_ok=True)

  # img_dir:表示要创建的目录路径。

  # exist_ok=True:表示如果目录已经存在时不抛出异常。如果将 exist_ok 设置为 True,那么如果目录已经存在,os.makedirs() 函数也不会报错;如果设置为 False,则会抛出一个 FileExistsError 异常。

  cv = cv2.VideoCapture(video_path)

  frame_count = 0

  # 计数器

  n = 0

  # 命名计数器

  while True:

  ret,frame = cv.read()

  if not ret:

  break

  frame_count += 1

  if frame_count % 30 ==0:

  # 每隔三十帧获取一次图片

  n += 1

  img_name = "0000000{0}.jpg".format(n)

  img_file_path = os.path.join(img_dir,img_name)

  if not os.path.exists(img_file_path):

  sys.stdout.write("创建文件:"+ img_file_path + "

  ")

  # 标准输出流,将指定文本输出到控制台或其他输出设备中

  cv2.imwrite(img_file_path,frame,[cv2.IMWRITE_JPEG_QUALITY,100])

  # 将图像帧保存为jepg格式的图像,质量最高为100

  else:

  sys.stderr.write("跳过:" + img_file_path + "

  ")

  ret,frame = cv.read()

  def run(video_dir,img_dir):

  pool = ThreadPoolExecutor()

  # 创建一个线程池对象,实例化ThreadPoolExecutor类,将任务提交给线程池,线程池会自动调度线程来执行这些任务

  for file in os.listdir(video_dir):

  if file[-4:] == ".mp4":

  video_file_path = os.path.join(video_dir,file)

  img_dir_name = os.path.join(img_dir,file[:-4])

  os.makedirs(img_dir_name,exist_ok=True)

  pool.submit(output_img,*(video_file_path,img_dir_name))

  #* 和 ** 是用于解包参数的操作符。在这种情况下,*(video_file_path, img_dir_name)

  # 的作用是将元组 (video_file_path, img_dir_name) 中的元素解包并作为单独的参数传递给函数。

  if __name__ == '__main__':

  run(r"E:video",r"E:image")