昊虹君 发表于 2022-11-15 14:13

使用OpenCV的类VideoWriter进行视频写操作(保存视频)

使用OpenCV的类VideoWriter进行视频写操作(保存视频)

在OpenCV中可以用类VideoWriter实现视频写的相关操作。

如需详细了解类VideoWriter的使用,最好的资料是官方文档,
类VideoWriter的官方文档页面链接如下:
https://docs.opencv.org/4.4.0/dd/d9e/classcv_1_1VideoWriter.html

这个类最常用的两个成员函数为open()和write(),
成员函数write()的使用很简单,参数那里填入写入视频的每一帧图像即可。

这里重点介绍下成员函数open()。

成员函数open()的原型在OpenCV4中一共有四种,如下:
bool open (const String &filename, int fourcc, double fps, Size frameSize, bool isColor=true)

bool open (const String &filename, int apiPreference, int fourcc, double fps, Size frameSize, bool isColor=true)

bool open (const String &filename, int fourcc, double fps, const Size &frameSize, const std::vector< int > &params)

bool open (const String &filename, int apiPreference, int fourcc, double fps, const Size &frameSize, const std::vector< int > &params)
比较常用的是第一种,所以这里介绍下第一种,其参数意义如下:
filename---待写入的视频文件路径;

fourcc---设置视频的编码方式,通过四个字符来设置,可以用函数 cv::VideoWriter::fourcc()获得,这个函数详细的说明可参阅官方文档
https://docs.opencv.org/4.4.0/dd/d9e/classcv_1_1VideoWriter.html#afec93f94dc6c0b3e28f4dd153bc5a7f0
常见的编码格有哪些?大家可参阅下面这篇博文:
https://www.cnblogs.com/20183544-wangzhengshuai/p/14851403.html
值得注意的是:当fourcc的值为-1时,程序运行时会出现如下的选项框让用户手动选择编码格式。
http://pic1.hhai.cc/pic1/2022/2022-11/004/12.png
上面各选项的详细说明大家可参考下面这篇博文:
https://www.cnblogs.com/small-lazybee/p/15801978.html

fps---视频的帧率;

frameSize---视频的分辨率;

isColor---是否为彩色视频,默认是彩色视频;

明白以上参数的意义后,就基本掌握类VideoWriter的使用了

接下来给一个示例,该示例的作用是读取一个视频文件获得其每一帧,并将其每一帧编码为一个新的视频文件。

以下示例代码中用到的视频“tea_small.avi”的百度网盘下载链接如下:
https://pan.baidu.com/s/1VEI_ruNl1_34oZ4umEjkZg?pwd=fgdb

C++示例代码如下:

//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
        // 视频读入与输出路径设置
        string sourceVideoPath = "F:/material/videos/tea_small.avi";
        string outputVideoPath = "F:/material/results/tea_small_write_test.avi";
       
        // 视频读入
        VideoCapture inputVideo(sourceVideoPath);
        // 检测视频输入的有效性      
        if (!inputVideo.isOpened())
        {
                cout << "fail to open!" << endl;
                return -1;
        }

        // 获取视频分辨率
        int videoWidth = (int)inputVideo.get(CV_CAP_PROP_FRAME_WIDTH);
        int videoHeight = (int)inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT);
        cv::Size videoResolution = cv::Size(videoWidth, videoHeight);

        cout << "视频分辨率:" << videoResolution.width <<" " << videoResolution.height << endl;


        // 获取视频总帧数   
        int videoCount = inputVideo.get(CV_CAP_PROP_FRAME_COUNT);
        cout << "总帧数:" << videoCount << endl;

        //获取视频帧率
        double fps = inputVideo.get(CV_CAP_PROP_FPS);

        //初始化一个VideoWriter对象
        VideoWriter outputVideo;


        //open方法相关设置
        int fourcc_1 = VideoWriter::fourcc('X', 'V', 'I', 'D'); //设置视频的编码方式
        outputVideo.open(outputVideoPath, fourcc_1, fps, videoResolution, true);

        if (!outputVideo.isOpened())
        {
                cout << "fail to open!" << endl;
                return -1;
        }

        cv::Mat frameImg, resultImg;

        int count = 0;

        while (true)
        {

                inputVideo >> frameImg;//获取当前帧图像


                // 显示当前帧
                if (!frameImg.empty())
                {
                        outputVideo << frameImg;//将当前帧进行编码写入视频文件

                        count++;
                        cout<< "一共"<< videoCount<< "帧,";
                        cout << "第" << count << "帧处理完毕" << endl;
                }
                else
                {
                        break;
                }
        }

        // 释放相关对象及资源
        inputVideo.release();
        outputVideo.release();

        return 0;

}
代码很简单,不需要再作补充说明,运行结果如下图所示:
http://pic1.hhai.cc/pic1/2022/2022-11/004/06.png
                                          
http://pic1.hhai.cc/pic1/2022/2022-11/004/07.png
                                          
http://pic1.hhai.cc/pic1/2022/2022-11/004/08.png

Python代码如下:
注意:与C++代码不同的是,在Python代码中,我保存的视频文件类型为mp4,而不是C++代码中的avi。

# -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术

# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询

# OpenCV的版本为4.4.0

import cv2 as cv
import sys

if __name__ == '__main__':
    sourceVideoPath = 'F:/material/videos/tea_small.avi'
    outputVideoPath = 'F:/material/results/tea_small_write_test2.mp4'

    # 视频读入
    inputVideo = cv.VideoCapture(sourceVideoPath)
    if inputVideo.isOpened():
      print('视频读取成功\n')

    else:
      print('视频读取失败\n')
      sys.exit()

    # 获取视频分辨率
    videoWidth = int(inputVideo.get(cv.CAP_PROP_FRAME_WIDTH))
    videoHeight = int(inputVideo.get(cv.CAP_PROP_FRAME_HEIGHT))
    videoResolution = (videoWidth, videoHeight)
    print('视频分辨率:{} {}'.format(videoWidth, videoHeight))

    # 获取视频总帧数
    videoCount = inputVideo.get(cv.CAP_PROP_FRAME_COUNT)
    print('视频总帧数:{}'.format(videoCount))

    # 获取视频帧率
    fps = inputVideo.get(cv.CAP_PROP_FPS)

    # 初始化一个VideoWriter对象
    outputVideo = cv.VideoWriter()

    # open方法相关设置
    # 设置视频的编码方式
    fourcc = cv.VideoWriter_fourcc('M', 'P', '4', 'V')
    outputVideo.open(outputVideoPath, fourcc, fps, videoResolution, True)

    count = 0
    while inputVideo.isOpened():
      ret, frame = inputVideo.read()
      if ret is True:
            outputVideo.write(frame)
            count = count + 1
            print('一共{}帧,第{}帧处理完毕'.format(videoCount, count))
      else:
            break

    # 释放并关闭相关对象
    inputVideo.release()
    outputVideo.release()

代码很简单,不需要再作补充说明,运行结果如下图所示:
http://pic1.hhai.cc/pic1/2022/2022-11/004/09.png
                                          
http://pic1.hhai.cc/pic1/2022/2022-11/004/10.png
                                          
http://pic1.hhai.cc/pic1/2022/2022-11/004/11.png
页: [1]
查看完整版本: 使用OpenCV的类VideoWriter进行视频写操作(保存视频)