前边文章介绍了在WIN10系统上,分别用C++和Python调用OpenCV接口,播放本地和网络摄像头视频。本篇我们来看一下,用C++如何调用OpenCV接口,打开网络摄像头的视频,对其进行录像,并抓拍图片。
视频来源 | 视频格式/协议 | 参数 |
网络摄像头 | RTSP | rtsp://admin:123456@192.168.1.104:554/Streaming/Channels/101 |
下边我们用海康IP摄像机做测试,表格中的rtsp地址,是海康摄像机的URL格式,其它品牌(大华、宇视)与之类似。
rtsp://admin:123456@192.168.1.104:554/Streaming/Channels/101
rtsp:表示采用RTSP协议从摄像机取流
admin:摄像机网页登录用户名
123456:摄像机网页登录密码
192.168.1.104:摄像机IP地址
554:RTSP默认端口
输出文件 | 格式 | 文件名称 |
录像文件 | mp4 | output.mp4 |
抓拍图片文件 | bmp | picture_x.bmp |
在测试程序中,主要用到了OpenCV以下接口:
录制视频
VideoWriter:写视频文件类,录制视频文件时使用。
测试程序中,用到该类的重载构造函数,原型如下:
- CV_WRAP VideoWriter(const String& filename, int fourcc, double fps,
- Size frameSize, bool isColor = true);
参数说明:
filename:保存的录像文件路径及名字
fourcc:指定视频编码器,特别注意,在OpenCV3种,该参数调用方式如CV_FOURCC('M','P','4','2')。在OpenCV4中,该参数调用方式做了改变,具体见后边代码。要不然编译不过
fps:保存的录像视频帧率
frameSize:录像文件视频分辨率大小,即视频画面的宽和高
isColor:表示录像用彩色画面还是黑白画面,默认ture,彩色画面
抓拍图片
函数原型:
- CV_EXPORTS_W bool imwrite( const String& filename, InputArray img,
- const std::vector<int>& params = std::vector<int>());
参数说明:
filename:保存的抓拍图片文件路径及名字
img:抓拍的视频帧,其类型为Mat
params:用来设置对应图片格式的参数,一般情况下这些图片格式都是经过压缩,这里就是设置这些压缩参数来控制图片的质量。该参数是一个vector
创建测试项目、配置开发环境,具体可参考之前文章,这里就不多说了
Win10+OpenCV4.6.0之开发环境(VS2022)配置入门_来灵的博客-CSDN博客
这次测试项目名称video_record,VS2022种创建好的项目截图
将下列代码编辑到video_record.cpp文件里
- #include <opencv2\opencv.hpp>
- #include <iostream>
- #include <string>
- using namespace cv;
- using namespace std;
-
- //打开网络摄像头录像
- bool OpenCameraAndRecord(const std::string& url)
- {
- cout << "将要播放视频文件,按下空格键结束播放" << endl;
-
- VideoCapture capture;
- bool result = capture.open(url);
-
- //检查是否成功打开
- if (!capture.isOpened())
- {
- cout << "打开文摄像头失败,url:" << url << endl;
- return result;
- }
-
- //打印视频参数:宽、高、每秒传输帧数
- int videoWidth = capture.get(CAP_PROP_FRAME_WIDTH);
- int videoHeight = capture.get(CAP_PROP_FRAME_HEIGHT);
- int videoFps = capture.get(CAP_PROP_FPS);
-
- cout << "视频分辨率为:" << videoWidth << "x" << videoHeight << ",fps:" << videoFps << endl;
-
- //下边是OpenCV3中的调用方式,OpenCV4对第二个参数接口做了调整
- //VideoWriter vedio("./record/output.mp4", CV_FOURCC('M', 'J', 'P', 'G'), videoFps, Size(videoWidth, videoHeight));
-
- VideoWriter recorder("./record/output.mp4", CAP_OPENCV_MJPEG, videoFps, Size(videoWidth, videoHeight), true);
-
- try
- {
- Mat frame;
- char pictureName[256] = { 0 };
- int pictureIndex = 1;
- while (true)
- {
- capture >> frame; //读取视频帧
- if (true == frame.empty())
- {
- cout << "获取视频帧为空,退出播放" << endl;
- break;
- }
-
- //如果仅在后台录制视频,不实施播放,把imshow注释掉
- imshow("摄像机实时视频", frame); //在名称为“视频文件”的窗口中显示视频
-
- recorder << frame; //给录像文件写入视频帧
-
- int key = waitKey(1);
- if (32 == key) //按下空格键退出视频每帧的显示
- {
- snprintf(pictureName, sizeof(pictureName), "./picture/picture_%d.bmp", pictureIndex++);
- cv::imwrite(pictureName, frame);
- }
- else if (27 == key) //按下ESC键退出视频播放和录制
- {
- cout << "按下空格键,退出播放和录制" << endl;
- break;
- }
- else {}
- }
- }
- catch (const std::exception& e)
- {
- cout << "exception:" << e.what() << endl;
- }
-
- capture.release();
- recorder.release();
- //如果仅在后台录制视频,不实施播放,把destroyWindow注释掉
- destroyWindow("摄像机实时视频");
- cout << "视频录制完成" << endl << endl;
- return result;
- }
-
- int main()
- {
- cout << "使用OpenCV录制视频测试" << endl;
-
- //打开网络摄像头播放
- //如果要打开电脑本地视频文件进行录制,下边参数传入视频文件路径和名字即可
- OpenCameraAndRecord("rtsp://admin:123456@192.168.1.104:554/Streaming/Channels/101");
-
- cout << "完成测试" << endl;
- system("pause");
- }
测试项目工程当前目录,新创建2个文件夹:record和picture,分别用于保存录像文件和抓拍图片文件
VS中代码截图
录像文件
使用VLC打开播放
抓拍图片
打开图片