• 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函数

    代码如下(示例):

    #include   
    #include  
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    二、保存

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

    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:保存视频是否为彩色视频,缺省为彩色
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      (2)VideoWrite()和VideoCapture()一样,都可以通过isOpened()函数判断是否成功创建一个视频流,可以通过get()查看视频流中的各种属性。
      (3)在保存视频时,我们只需要将生成视频的图像一帧一帧通过“<<”操作符(或者write()函数)赋值给视频流即可,最后使用release()关闭视频流。

    代码如下(示例):

    #include   
    #include  
    
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
  • 相关阅读:
    M4Singer CUDA error: no kernel image is available for execution on the device
    【2023云栖】郭瑞杰:阿里云搜索产品智能化升级
    Linux学习第44天:Linux 多点电容触摸屏实验(二):难忘记第一次牵你手的温存
    burpsuite安装方法(抓包工具)
    FFmpeg工具使用总结
    ubuntu莫名的 系统出现文件系统只读
    年薪30万+的HR这样做数据分析!(附关键指标&免费模版)
    安装myql
    C#,入门教程——程序运行时的调试技巧与逻辑错误探针技术与源代码
    Docker 启动容器
  • 原文地址:https://blog.csdn.net/qq_43199575/article/details/133356918