C++ OpenCV #003 视频的读取,显示,保存

视频可以看成由一张张照片合成而来,opencv支持对视频直接操作


1. 确认电脑支持的编码方式

  • 若不进行确认,则保存视频时的编码方式不确定,可能导致保存的视频无法打开

  • 打开视频:outputVideo.open(filename, int fourcc, double fps, Size frameSize, bool isColor = true)

    filename:视频路径

    fourcc:保存视频的格式,设置为-1时,则输出本地机器支持视频编码格式

    fps:帧率

    frameSize:分辨率

    isColor:打开的是否是彩色视频,若把视频为灰度,还写true,则会报错

  • 程序:

    #include <opencv2/opencv.hpp>
    #include <opencv2/core/utils/logger.hpp>
    using namespace std;
    using namespace cv;
    
    // 新版的openc输出时,默认输出运行的所有日志信息,这些信息基本无用,编写函数关闭无用的日志输出
    void close_log() {
        // 保留报错日志的输出
        utils::logging::setLogLevel(utils::logging::LOG_LEVEL_ERROR);
    }
    
    void func() {
        // 实例化对象
        VideoWriter outputVideo;
        outputVideo.open("F:\\test\\1.mp4", -1, 10, Size(1920, 1080), true);
    }
    
    int main() {
        close_log();
        func();
        return 0;
    }
    
  • 输出:如图mp4支持的编码格式为 0x7634706d,后续保存或打开mp4视频可以使用该编码格式了



2. 打开视频

说明:视频播放可以看成是一张张图片在一定的速率(帧率)下显示出来。

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
#include<string>
#include<iostream>
using namespace std;
using namespace cv;


// 保留报错日志
void close_log() {
    utils::logging::setLogLevel(utils::logging::LOG_LEVEL_ERROR);
}

void video_show() {
    // 创建 VideoCapture对象, 打开视频
    VideoCapture cap("F:\\test\\beautiful.mp4");

    // 判断视频是否存在
    if (!cap.isOpened()) {
        cout << "视频打开失败" << endl;
        return;
    }

    Mat frame;
    while (1) {
        // 把视频帧储存到矩阵,每帧画面相当于一张图片
        cap >> frame;
        // 视频读完后,不会自动退出(报错),读完数据为空,退出循环
        if (frame.empty()) {
            cout << "视频播放完成....." << endl;
            break;
        }
        // 显示每一帧
        imshow("video_show", frame);
        // 视频帧率
        waitKey(10);
    }

    // 释放资源
    cap.release();
}

int main() {
    close_log();
    video_show();

    return 0;
}


3. 视频的属性

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
#include<string>
#include<iostream>
using namespace std;
using namespace cv;

// 保留报错日志
void close_log() {
    utils::logging::setLogLevel(utils::logging::LOG_LEVEL_ERROR);
}

void video_show() {
    // 创建 VideoCapture对象, 打开视频
    VideoCapture cap("F:\\test\\beautiful.mp4");
    // 判断视频是否存在
    if (!cap.isOpened()) {
        cout << "视频打开失败" << endl;
        return;
    }

    // 视频属性,右键视频可查看属性
    int width = cap.get(CAP_PROP_FRAME_WIDTH);              // 帧宽度
    int height = cap.get(CAP_PROP_FRAME_HEIGHT);            // 帧高度
    int frame_rate = cap.get(CAP_PROP_FPS);                 // 帧率
    int total_frame = cap.get(CAP_PROP_FRAME_COUNT);        // 总帧数
    cout << width << " " << height << " " << frame_rate << " " << total_frame << endl;
}

int main() {
    close_log();
    video_show();

    return 0;
}
784 434 10 212


4. 写入视频

  • 示例:读取一段视频,把视频的每一帧,保存为另一个视频

  • 示例中写入视频时利用了第一步获取的支持编码的格式 0x7634706d

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
#include<string>
#include<iostream>
using namespace std;
using namespace cv;

void close_log() {
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_ERROR);
}

void video_show() {

    // 创建 VideoCapture对象, 打开视频
    VideoCapture cap("F:\\test\\beautiful.mp4");
    // 创建 VideoWriter对象,设置保存视频时的参数
    VideoWriter writer("F:\\test\\1_out.mp4", 0x7634706d, 20, Size(1080, 754), true);
    // 判断视频是否存在
    if (!cap.isOpened()) {
        cout << "视频打开失败" << endl;
        return;
    }

    Mat frame;
    while (1) {
        // 把视频帧储存到矩阵,每帧画面相当于一张图片
        cap >> frame;
        // 视频读完后,不会自动退出(报错),读完数据为空,退出循环
        if (frame.empty()) {
            cout << "视频播放完成....." << endl;
            break;
        }
        // 存入视频
        writer.write(frame);
        // 显示每一帧
        imshow("video_show", frame);
        // 视频帧率
        waitKey(10);
    }
    
    // 释放资源
    cap.release();
}

int main() {
    close_log();
    video_show();

    return 0;
}
posted @ 2023-06-28 23:06  枫_Null  阅读(1115)  评论(0)    收藏  举报