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

news/2024/7/21 4:21:48 标签: python, 音视频, 开发语言, 图像处理, opencv

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

1 视频分解图片(拆帧)

1.1 主函数介绍+代码

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

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

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

python">def Frame_video(video_path, out_path, target_frame=1):
    """
    :param video_path: 需要拆帧的视频路径
    :param out_path: 拆帧后图片保存路径
    :param target_frame: 抽取帧数间隔,默认为1,即1帧保存1张图片
    :return: None
    """
    print("-------------------------视频抽帧-------------------------")
    if not os.path.exists(out_path):
        # 判断文件夹是否存在
        os.makedirs(out_path)
    video = cv2.VideoCapture()  # 初始化一个OpenCV的视频读取对象
    video.open(video_path)
    count = 0  # 记录当前帧数
    image_index = 1000001  # 用于保存图片名称
    frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取帧数
    print('视频共%s帧,抽取%s帧......' % (frames, int(frames/target_frame)))
    while True:
        _, frame = video.read()
        if frame is None:
            # print("第%s帧图片无法打开!" % count)
            break
        if count % target_frame == 0:
            if int((image_index-1000000) / int(frames/target_frame) * 100) in [20, 40, 60, 80]:
                print("已提取百分之%s,剩余%s帧......" %
                      (int((image_index-1000000) / int(frames/target_frame) * 100),
                       int(frames / target_frame) - image_index + 1000000))
            save_path = out_path + "%s.png" % image_index
            cv2.imwrite(save_path, frame)
            image_index += 1
        count += 1
    video.release()
    print("视频已全部抽帧完成......")
    print("-------------------------抽帧完成-------------------------")

1.2 完整代码

python"># -*- coding: utf-8 -*-
"""
@Time : 2023/10/25 14:26
@Auth : RS迷途小书童
@File :Video Frame Images.py
@IDE :PyCharm
@Purpose:视频拆帧成图片
"""
import os
import sys
import cv2


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


if __name__ == '__main__':
    print("\n-------------------------基础信息-------------------------")
    Video_path = r'G:\D.MP4'
    save_dir = r'B:\YOLO\18/'
    video1 = cv2.VideoCapture()  # 初始化一个OpenCV的视频读取对象
    if not video1.open(Video_path):
        print("无法打开视频,请检查数据!")
        sys.exit()
    fps = video1.get(cv2.CAP_PROP_FPS)  # 获取帧率
    frame_count = int(video1.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取视频的总帧数
    video1.release()  # 清理缓存
    duration = frame_count / fps  # 计算视频的时长(秒)
    print("视频时长为: %ss" % int(duration))
    print("视频帧率为: %sFPS" % int(fps))
    print("视频帧数为: %s" % int(frame_count))
    Frame = int(input("请输入抽取帧数间隔:"))
    Frame_video(Video_path, save_dir, Frame)

2 图片组合视频(组帧)

2.1 主函数介绍+代码

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

python">def Image_Frame(images_path, out_path, fps):
    """
    :param images_path: 输入需要组帧的图片文件夹路径
    :param out_path: 输出视频路径
    :param fps: 视频帧率
    :return: None
    """
    print("-------------------------图片组帧-------------------------")
    images_lists = os.listdir(images_path)  # images_lists.sort()
    image_size = Image.open(os.path.join(images_path, images_lists[0])).size
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    video_writer = cv2.VideoWriter(out_path, fourcc, fps, image_size)
    for image_list in images_lists:
        image_path = os.path.join(images_path, image_list)
        frame = cv2.imread(image_path)
        video_writer.write(frame)
        print("正在添加:", image_list)
    video_writer.release()
    print("-------------------------组帧完成-------------------------")

2.2 完整代码

python"># -*- coding: utf-8 -*-
"""
@Time : 2023/10/25 16:00
@Auth : RS迷途小书童
@File :Images Frame Video.py
@IDE :PyCharm
@Purpose:图片组帧成视频
"""
import os
import cv2
from PIL import Image


def Image_Frame(images_path, out_path, fps):
    """
    :param images_path: 输入需要组帧的图片文件夹路径
    :param out_path: 输出视频路径
    :param fps: 视频帧率
    :return: None
    """
    print("-------------------------图片组帧-------------------------")
    images_lists = os.listdir(images_path)  # images_lists.sort()
    image_size = Image.open(os.path.join(images_path, images_lists[0])).size
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    video_writer = cv2.VideoWriter(out_path, fourcc, fps, image_size)
    for image_list in images_lists:
        image_path = os.path.join(images_path, image_list)
        frame = cv2.imread(image_path)
        video_writer.write(frame)
        print("正在添加:", image_list)
    video_writer.release()
    print("-------------------------组帧完成-------------------------")


if __name__ == "__main__":
    Image_path = r'G:\1/'
    Out_path = r'G:\1.mp4'
    FPS = int(input("请输入帧率:"))
    Image_Frame(Image_path, Out_path, FPS)

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


http://www.niftyadmin.cn/n/5126161.html

相关文章

C++智能指针之shared_ptr原理和应用举例

shared_ptr是C中的智能指针,它提供了共享所有权的能力。以下是shared_ptr的原理和特点: 先说原理: 1. shared_ptr使用引用计数的方式来管理对象的生命周期。 2. 每个shared_ptr都有一个关联的引用计数,用于统计有多少个指针共享…

FreeRTOS 互斥量 优先级反转(翻转)和优先级继承 详解

目录 什么是互斥量? 什么是优先级反转(翻转)和优先级继承 互斥量相关 API 函数 优先级反转(翻转)示例 使用互斥量优化优先级反转(翻转)问题示例 什么是互斥量? 在多数情况下&a…

java面试--线程总结

Java中有几种方式来创建线程执行任务,分别是什么? 1、继承Thread类 public class MyThread extends Thread{public static void main(String[] args) {MyThread myThread new MyThread();myThread.start();}Overridepublic void run() {System.out.pr…

银河麒麟v10x86或者arm离线安装服务

银河麒麟v10x86或者arm离线安装服务 最近有个项目,甲方的服务器用的全是国产化服务器银河麒麟,架构是x86的然后也无法连接外网,需要离线安装服务正常思路就是找到离线安装的包,然后拷贝到现场的服务器中进行安装所以问题就在于如…

如何使用LoRA和PEFT微调 Mistral 7B 模型

一、前言 对于大模型在一些安全级别较高的领域,比如在金融服务领域实施人工智能解决方案时,面临的最大挑战之一是数据隐私、安全性和监管合规性。 因为担心数据泄露的问题,很多银行或机构都会回避利用人工智能的优势潜力,尤其是…

题目 1056: 二级C语言-温度转换(python详解)——练气四层初期

✨博主:命运之光 🦄专栏:算法修炼之练气篇(C\C版) 🍓专栏:算法修炼之筑基篇(C\C版) 🍒专栏:算法修炼之练气篇(Python版) ✨…

方舟生存进化ARK个人服务器搭建教程保姆级

方舟生存进化ARK个人服务器搭建教程保姆级 大家好我是艾西,在很久之前我有给大家分享过方舟生存进化的搭建架设教程,但时间久远且以前的教程我现在回头看去在某些地方说的并不是那么清楚。最近也是闲暇无事打算重新巩固下方舟生存进化的搭建架设教程&…

数学分析:傅里叶三角级数

贝塞尔不等式,就是勾股定理。不过要注意,因为他们的基并不是单位基,所以系数做过缩放。 三角级数的复形式。 通过复形式,可以进一步化简。 因为是等比数列,最终可以得到一个很好的地理克雷核。 这个引理的意思是&#…