1 前言
前边文章介绍了在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 |
2 关键接口说明
在测试程序中,主要用到了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<int>类型,里面分别存入paramId_1, paramValue_1, paramId_2, paramValue_2, ... 也就是说存入一对属性值。如果不设置该参数的话,则程序会自动根据所保存的图像格式采用一个默认的参数。
3 创建测试项目
创建测试项目、配置开发环境,具体可参考之前文章,这里就不多说了
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中代码截图
4 效果截图
录像文件
使用VLC打开播放
抓拍图片
打开图片
5 参考资料
OpenCV图片拍照及视频录制方法_top_geek_001的博客-CSDN博客_opencv 拍照