OpenCV4(C++)—— 视频和摄像头的加载、显示与保存

文章目录


一、加载与显示

视频或摄像头的加载是使用 cv::VideoCapture 类。(这个类和 ifstream 类比较相似,视频或摄像头的加载和文本文件操作是大致相同。主要步骤:(1)加载(打开)视频或视像头。(2) 判断加载是否成功。 (3)读取内容。(4)关闭。)

注意:

(1)VideoCapture类变量同时提供了可以查看视频属性的 get()函数 ,通过输入指定的标志来获取视频属性,例如视频的像素尺寸、帧数、帧率等。

(2)在读取内容(每一帧图片)时,和ifstream一样,同样有多种方式,如通过">>"运算符,或使用read成员函数等。但注意要使用 Mat类 来定义buffer。

(3)当VideoCapture类变量中所有的图像都赋值给Mat类变量后,再次赋值的时候就是赋空值,故Mat类变量会变为空矩阵,因此可以通过 empty() 判断VideoCapture类变量中是否所有图像都已经读取完毕。

(4)视频其实是每一帧图像的组成,所以显示也是连续显示每一帧图像,同样使用 imshow函数

代码如下(示例):

c 复制代码
#include <opencv2/opencv.hpp>  
#include<iostream>  
using namespace std;

int main()
{

    // 和文本文件一样,两种打开方式:成员函数open和默认构造函数
    //cv::VideoCapture capVideo;
    //capVideo.open("C:/Users/Opencv/temp/123.mp4");
    cv::VideoCapture capVideo("C:/Users/Opencv/temp/123.mp4");
	
	// 打开摄像头,第一个参数为要打开的摄像头设备的ID,ID的命名方式从0开始。
	// cv::VideoCapture capVideo(0); // 打开第一个摄像头

    if (!capVideo.isOpened())
    {
        cout << "打开视频失败" << endl;
        return -1;
    }

    cout << "视频中图像的宽度=" << capVideo.get(cv::CAP_PROP_FRAME_WIDTH) << endl;
    cout << "视频中图像的高度=" << capVideo.get(cv::CAP_PROP_FRAME_HEIGHT) << endl;
    cout << "视频帧率=" << capVideo.get(cv::CAP_PROP_FPS) << endl;
    cout << "视频的总帧数=" << capVideo.get(cv::CAP_PROP_FRAME_COUNT);

    cv::Mat buffer;
    while (1) {
        capVideo >> buffer;
        if (buffer.empty())
        {
            break;
        }
        cv::imshow("video", buffer);
        //char key = cv::waitKey(1000 / capVideo.get(cv::CAP_PROP_FPS));  // 按源视频的帧率
        char key = cv::waitKey(30);  // 每帧延迟30毫秒。(由此可设置快放或慢放)

        if (key == 'q' || key == 27)
        {
            break;
        }    
    }
    capVideo.release();  //释放对象
    cv::destroyAllWindows();

二、保存

(1)OpenCV中提供了 VideoWrite()类 用于实现多张图像保存成视频文件。该类的构造函数参数如下:

c 复制代码
cv::VideoWriter output(filename, int fourcc, double fps, Size frameSize, bool  isColor=true)

filename::保存视频的具体路径,包含视频格式
fourcc:压缩帧的4字符编解码器代码。如JPEG编码('M','J','P','G'),但这个效果一般。常用的H.264 编码格式('H', '2', '6', '4')等。注:赋值"-1"则会自动搜索合适的编解码器
fps:保存视频的帧率,即视频中每秒图像的张数。可实现原视频二倍速播放、原视频慢动作播放等
frameSize:视频帧的尺寸。通常在设置时要与图像的尺寸相同,不然无法保存视频
isColor:保存视频是否为彩色视频,缺省为彩色

(2)VideoWrite()和VideoCapture()一样,都可以通过isOpened()函数判断是否成功创建一个视频流,可以通过get()查看视频流中的各种属性。

(3)在保存视频时,我们只需要将生成视频的图像一帧一帧通过"<<"操作符(或者write()函数)赋值给视频流即可,最后使用release()关闭视频流。

代码如下(示例):

c 复制代码
#include <opencv2/opencv.hpp>  
#include<iostream>  

using namespace std;

int main()
{

    cv::VideoCapture capVideo("C:/Users/Opencv/temp/123.mp4");
    // cv::VideoCapture capVideo;
    // capVideo.open("C:/Users/Opencv/temp/123.mp4");

    if (!capVideo.isOpened())
    {
        cout << "打开视频失败" << endl;
        return -1;
    }

    cout << "视频中图像的宽度=" << capVideo.get(cv::CAP_PROP_FRAME_WIDTH) << endl;
    cout << "视频中图像的高度=" << capVideo.get(cv::CAP_PROP_FRAME_HEIGHT) << endl;
    cout << "视频帧率=" << capVideo.get(cv::CAP_PROP_FPS) << endl;
    cout << "视频的总帧数=" << capVideo.get(cv::CAP_PROP_FRAME_COUNT);

    int width = static_cast<int>(capVideo.get(cv::CAP_PROP_FRAME_WIDTH));
    int height = static_cast<int>(capVideo.get(cv::CAP_PROP_FRAME_HEIGHT));

    // cv::VideoWriter output("C:/Users/Opencv/temp/321.mp4", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25, cv::Size(width,height), true);
    cv::VideoWriter output("C:/Users/Opencv/temp/32331.mp4", cv::VideoWriter::fourcc('H', '2', '6', '4'), 25, cv::Size(width, height), true);

    if (!output.isOpened()) {
        // 处理无法创建输出视频文件的情况
        return -1;
    }

    cv::Mat buffer;
    while (capVideo.read(buffer)) {

        //  可用一些方法对每一帧图片进行处理

        output.write(buffer); // 再将当前帧写入输出视频
        //output << buffer;

        cv::imshow("show",buffer);
        char key = cv::waitKey(1000 / capVideo.get(cv::CAP_PROP_FPS));  // 按源视频的帧率
        if (key == 'q' || key == 27)
        {
            break;
        }
    }
    capVideo.release();  //释放对象
    cv::destroyAllWindows();
    return 0;
}
相关推荐
深蓝海拓1 小时前
opencv的模板匹配(Template Matching)学习笔记
人工智能·opencv·计算机视觉
滨HI03 小时前
C++ opencv简化轮廓
开发语言·c++·opencv
学习路上_write3 小时前
FREERTOS_互斥量_创建和使用
c语言·开发语言·c++·stm32·单片机·嵌入式硬件
闻缺陷则喜何志丹4 小时前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
BestOrNothing_20155 小时前
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)
c++·函数重载·运算符重载·operator·前置后置++·重载与重写
2501_941144425 小时前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码5 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
charlie1145141916 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
Cx330❀6 小时前
C++ STL set 完全指南:从基础用法到实战技巧
开发语言·数据结构·c++·算法·leetcode·面试
zmzb01036 小时前
C++课后习题训练记录Day33
开发语言·c++