[Python introductory tutorial] Decompose video into pictures + combine pictures into video based on OpenCV (video frame extraction)

        Today, with the explosion of artificial intelligence, deep learning is widely used in various fields. Deep learning model training is inseparable from a large number of sample libraries. I have shared before[Python crawler] batch crawling of images from web pages & making data sets. Today I will share with you how to use the OpenCV library to process videos. Frames are extracted to increase the number of sample images. It just so happens that I would also like to share how to combine pictures into videos. Of course, video frame extraction can also be applied to many neighborhoods. I used it here to make samples.

1 Video decomposition pictures (frame splitting)

1.1 Main function introduction + code

        cv2.VideoCapture()is a function in the OpenCV library for reading video files or live video streams. It returns a video capture object through which the video can be read, manipulated and released.

        Usecv2.VideoCapture() to read every frame in a video file or live video stream. By reading the frames in a loop, you can get all the frames in the video.

        The target_frame in the input parameter here refers to the number of frames to save a picture. If you enter 1, all will be saved. If the video frame rate is 60 (60 pictures per second) and you set target_frame to 120, one picture will be saved every two seconds.

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 Complete code

# -*- 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 picture combination video (framing)

2.1 Main function introduction + code

        The cv2.VideoWriter function is used to save the recorded video into a file. It requires specifying parameters such as file path, encoder, frame rate, and video size.

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 Complete code

# -*- 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)

        This blog post is shared here. If you have any questions about RS, GIS, and Python, you are welcome to leave a message for communication. Let's learn and progress together!

Guess you like

Origin blog.csdn.net/m0_56729804/article/details/134048318