• 【Python入门教程】基于OpenCV视频分解成图片+图片组合成视频(视频抽帧组帧)


            在人工智能爆火的今天,深度学习被广泛应用于各个领域。深度学习的模型训练离不开大量的样本库。我之前分享过【Python爬虫】批量爬取网页的图片&制作数据集,今天跟大家分享一下如何使用OpenCV库对视频进行抽帧,从而增加样本图片的数量。正好也顺便分享一下如何再将图片组合成视频。当然视频的抽帧组帧还可以应用到很多邻域,我这里是用在制作样本的。

    1 视频分解图片(拆帧)

    1.1 主函数介绍+代码

            cv2.VideoCapture()是OpenCV库中的一个函数,用于读取视频文件或实时视频流。它返回一个视频捕获对象,可以通过这个对象进行视频的读取、操作和释放等操作。

            使用cv2.VideoCapture()可以读取视频文件或实时视频流中的每一帧图像。通过循环读取帧,可以获取视频中的所有帧。

            这里入参中的target_frame是指间隔多少帧保存一张图片,如果输入1,则全部保存。若视频帧率为60(每秒60张图片),你设置target_frame为120,则两秒保存一张图片。

    1. def Frame_video(video_path, out_path, target_frame=1):
    2. """
    3. :param video_path: 需要拆帧的视频路径
    4. :param out_path: 拆帧后图片保存路径
    5. :param target_frame: 抽取帧数间隔,默认为1,即1帧保存1张图片
    6. :return: None
    7. """
    8. print("-------------------------视频抽帧-------------------------")
    9. if not os.path.exists(out_path):
    10. # 判断文件夹是否存在
    11. os.makedirs(out_path)
    12. video = cv2.VideoCapture() # 初始化一个OpenCV的视频读取对象
    13. video.open(video_path)
    14. count = 0 # 记录当前帧数
    15. image_index = 1000001 # 用于保存图片名称
    16. frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) # 获取帧数
    17. print('视频共%s帧,抽取%s帧......' % (frames, int(frames/target_frame)))
    18. while True:
    19. _, frame = video.read()
    20. if frame is None:
    21. # print("第%s帧图片无法打开!" % count)
    22. break
    23. if count % target_frame == 0:
    24. if int((image_index-1000000) / int(frames/target_frame) * 100) in [20, 40, 60, 80]:
    25. print("已提取百分之%s,剩余%s帧......" %
    26. (int((image_index-1000000) / int(frames/target_frame) * 100),
    27. int(frames / target_frame) - image_index + 1000000))
    28. save_path = out_path + "%s.png" % image_index
    29. cv2.imwrite(save_path, frame)
    30. image_index += 1
    31. count += 1
    32. video.release()
    33. print("视频已全部抽帧完成......")
    34. print("-------------------------抽帧完成-------------------------")

    1.2 完整代码

    1. # -*- coding: utf-8 -*-
    2. """
    3. @Time : 2023/10/25 14:26
    4. @Auth : RS迷途小书童
    5. @File :Video Frame Images.py
    6. @IDE :PyCharm
    7. @Purpose:视频拆帧成图片
    8. """
    9. import os
    10. import sys
    11. import cv2
    12. def Frame_video(video_path, out_path, target_frame=1):
    13. """
    14. :param video_path: 需要拆帧的视频路径
    15. :param out_path: 拆帧后图片保存路径
    16. :param target_frame: 抽取帧数间隔,默认为1,即1帧保存1张图片
    17. :return: None
    18. """
    19. print("-------------------------视频抽帧-------------------------")
    20. if not os.path.exists(out_path):
    21. # 判断文件夹是否存在
    22. os.makedirs(out_path)
    23. video = cv2.VideoCapture() # 初始化一个OpenCV的视频读取对象
    24. video.open(video_path)
    25. count = 0 # 记录当前帧数
    26. image_index = 1000001 # 用于保存图片名称
    27. frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) # 获取帧数
    28. print('视频共%s帧,抽取%s帧......' % (frames, int(frames/target_frame)))
    29. while True:
    30. _, frame = video.read()
    31. if frame is None:
    32. # print("第%s帧图片无法打开!" % count)
    33. break
    34. if count % target_frame == 0:
    35. if int((image_index-1000000) / int(frames/target_frame) * 100) in [20, 40, 60, 80]:
    36. print("已提取百分之%s,剩余%s帧......" %
    37. (int((image_index-1000000) / int(frames/target_frame) * 100),
    38. int(frames / target_frame) - image_index + 1000000))
    39. save_path = out_path + "%s.png" % image_index
    40. cv2.imwrite(save_path, frame)
    41. image_index += 1
    42. count += 1
    43. video.release()
    44. print("视频已全部抽帧完成......")
    45. print("-------------------------抽帧完成-------------------------")
    46. if __name__ == '__main__':
    47. print("\n-------------------------基础信息-------------------------")
    48. Video_path = r'G:\D.MP4'
    49. save_dir = r'B:\YOLO\18/'
    50. video1 = cv2.VideoCapture() # 初始化一个OpenCV的视频读取对象
    51. if not video1.open(Video_path):
    52. print("无法打开视频,请检查数据!")
    53. sys.exit()
    54. fps = video1.get(cv2.CAP_PROP_FPS) # 获取帧率
    55. frame_count = int(video1.get(cv2.CAP_PROP_FRAME_COUNT)) # 获取视频的总帧数
    56. video1.release() # 清理缓存
    57. duration = frame_count / fps # 计算视频的时长(秒)
    58. print("视频时长为: %ss" % int(duration))
    59. print("视频帧率为: %sFPS" % int(fps))
    60. print("视频帧数为: %s" % int(frame_count))
    61. Frame = int(input("请输入抽取帧数间隔:"))
    62. Frame_video(Video_path, save_dir, Frame)

    2 图片组合视频(组帧)

    2.1 主函数介绍+代码

            cv2.VideoWriter函数用于将录制的视频保存成文件。它需要指定文件路径、编码器、帧率和视频尺寸等参数。

    1. def Image_Frame(images_path, out_path, fps):
    2. """
    3. :param images_path: 输入需要组帧的图片文件夹路径
    4. :param out_path: 输出视频路径
    5. :param fps: 视频帧率
    6. :return: None
    7. """
    8. print("-------------------------图片组帧-------------------------")
    9. images_lists = os.listdir(images_path) # images_lists.sort()
    10. image_size = Image.open(os.path.join(images_path, images_lists[0])).size
    11. fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    12. video_writer = cv2.VideoWriter(out_path, fourcc, fps, image_size)
    13. for image_list in images_lists:
    14. image_path = os.path.join(images_path, image_list)
    15. frame = cv2.imread(image_path)
    16. video_writer.write(frame)
    17. print("正在添加:", image_list)
    18. video_writer.release()
    19. print("-------------------------组帧完成-------------------------")

    2.2 完整代码

    1. # -*- coding: utf-8 -*-
    2. """
    3. @Time : 2023/10/25 16:00
    4. @Auth : RS迷途小书童
    5. @File :Images Frame Video.py
    6. @IDE :PyCharm
    7. @Purpose:图片组帧成视频
    8. """
    9. import os
    10. import cv2
    11. from PIL import Image
    12. def Image_Frame(images_path, out_path, fps):
    13. """
    14. :param images_path: 输入需要组帧的图片文件夹路径
    15. :param out_path: 输出视频路径
    16. :param fps: 视频帧率
    17. :return: None
    18. """
    19. print("-------------------------图片组帧-------------------------")
    20. images_lists = os.listdir(images_path) # images_lists.sort()
    21. image_size = Image.open(os.path.join(images_path, images_lists[0])).size
    22. fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    23. video_writer = cv2.VideoWriter(out_path, fourcc, fps, image_size)
    24. for image_list in images_lists:
    25. image_path = os.path.join(images_path, image_list)
    26. frame = cv2.imread(image_path)
    27. video_writer.write(frame)
    28. print("正在添加:", image_list)
    29. video_writer.release()
    30. print("-------------------------组帧完成-------------------------")
    31. if __name__ == "__main__":
    32. Image_path = r'G:\1/'
    33. Out_path = r'G:\1.mp4'
    34. FPS = int(input("请输入帧率:"))
    35. Image_Frame(Image_path, Out_path, FPS)

            本次博文就分享到这,如果大家有RS、GIS、Python方面的问题,欢迎大家留言交流。我们一起学习进步!

  • 相关阅读:
    2020秋招Java面试题
    .NET Core 使用 System.Threading.Channels消息队列
    Linux vim的常见基本操作
    爬虫异常处理实战:应对请求频率限制和数据格式异常
    谷歌浏览器自定义标签页 newtab
    java计算机毕业设计开放式实验室预约系统源码+mysql数据库+系统+lw文档+部署
    学习Uni-app开发小程序Day5
    前端面试题之Javascript篇
    SQL排序函数详解+案例实战
    融云 Flutter SDK,跨平台开发的真香之选
  • 原文地址:https://blog.csdn.net/m0_56729804/article/details/134048318