上一篇文章介绍了OpenCV对于图像的处理方法,然而目前对视频的处理分析越来越成为计算机视觉的主流,视频中包含的信息量要远远大于图片,而本质上视频是由一帧帧的图像组成,所以视频处理最终还是要归结于图像处理,但在视频处理中,有更多的时间维的信息可以利用。本文主要介绍OpenCV在处理视频时的一些基本函数
视频读取,主要利用VideoCapture类下的方法打开视频并获取视频中的帧,其操作有很多,这里只提及最普遍的用法
具体可见:https://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html
1.1使用构造函数获取视频文件
//在该构造函数中,输入正确的视频文件的文件路径即可,OpenCV会打开对应的视频文件
cv::VideoCapture::VideoCapture(const string& filename);
打开视频文件有两种方法
//方法一
VideoCapture cap("E:/myFile/video/ty.mp4");//获取E:/myFile/video路径下的ty.mp4视频文件
//方法二
VideoCapture cap;
cap.open("E:/myFile/video/ty.mp4");//使用open方法
//在该构造函数中,输入摄像头ID,则可打开对应的摄像头,默认摄像头为0
cv::VideoCapture::VideoCapture(int device);
VideoCapture cap(0);//读取默认摄像头
1.2验证视频是否读入成功
若成功读取视频文件则放回True,否则返回False
if (!cap.isOpened())
{
cout << "无法打开视频文件!" << endl;
return -1;
}
1.3获取视频帧
获取视频帧有以下多种方法
Mat frame;
//方法一
capture.read(frame);
//方法二
capture.grab();
capture.retrieve(frame);
//方法三
capture>>frame;
1.4获取视频的参数
一个视频有很多参数,如:帧率、总帧数、尺寸、格式等,VideoCapture的get方法可以获取大量的这些参数
参数表如下表所示
参数 |
对应宏 | 说明 |
VideoCapture.get(0) | CV_CAP_PROP_POS_MSEC | 视频文件的当前位置(播放)以毫秒为单位 |
VideoCapture.get(1) | CV_CAP_PROP_POS_FRAMES | 基于以0开始的被捕获或解码的帧索引 |
VideoCapture.get(2) | CV_CAP_PROP_POS_AVI_RATIO | 视频文件的相对位置(播放):0=电影开始,1=影片的结尾 |
VideoCapture.get(3) | CV_CAP_PROP_FRAME_WIDTH | 在视频流的帧的宽度 |
VideoCapture.get(4) | CV_CAP_PROP_FRAME_HEIGHT | 在视频流的帧的高度 |
VideoCapture.get(5) | CV_CAP_PROP_FPS | 帧速率/帧数/fps |
VideoCapture.get(6) | CV_CAP_PROP_FOURCC | 编解码的4字-字符代码 |
VideoCapture.get(7) | CV_CAP_PROP_FRAME_COUNT | 视频文件中的帧数 |
VideoCapture.get(8) | CV_CAP_PROP_FORMAT | 返回对象的格式 |
VideoCapture.get(9) | CV_CAP_PROP_MODE | 返回后端特定的值,该值指示当前捕获模式 |
VideoCapture.get(10) | CV_CAP_PROP_BRIGHTNESS | 图像的亮度(仅适用于照相机) |
VideoCapture.get(11) | CV_CAP_PROP_CONTRAST | 图像的对比度(仅适用于照相机) |
VideoCapture.get(12) | CV_CAP_PROP_SATURATION | 图像的饱和度(仅适用于照相机) |
VideoCapture.get(13) | CV_CAP_PROP_HUE | 色调图像(仅适用于照相机) |
VideoCapture.get(14) | CV_CAP_PROP_GAIN | 图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升) |
VideoCapture.get(15) | CV_CAP_PROP_EXPOSURE | 曝光(仅适用于照相机) |
VideoCapture.get(16) | CV_CAP_PROP_CONVERT_RGB | 指示是否应将图像转换为RGB布尔标志 |
VideoCapture.get(17) | CV_CAP_PROP_WHITE_BALANCE | × 暂时不支持 |
VideoCapture.get(18) | CV_CAP_PROP_RECTIFICATION | 立体摄像机的矫正标注(目前只有DC1394 v.2.x后端支持这个功能) |
示例如下图所示
1.5设置视频帧的读取位置
VideoCapture类的set方法可以允许我们取出视频中某个位置的帧
它有一些参数,可以按时间,也可以按帧号,还可以按视频长短的比例
//第100帧
double position=100.0;
capture.set(CV_CAP_PROP_POS_FRAMES,position);
//第1e6毫秒
double position=1e6;
capture.set(CV_CAP_PROP_POS_MSEC,position);
//视频1/2位置
double position=0.5;
capture.set(CV_CAP_PROP_POS_AVI_RATIO,position);
同时set方法还可以设置视频的帧率、亮度
视频的写入与读取类似,使用VideoWriter类来实现,这个类有几个方法,除了构造函数外,提供了open、IsOpen、write、和重载操作符<<
cv::VideoWriter(const string& path,int fourcc,double fps, Size framesize, bool isColor=true)
- 第一个参数表示保存的文件路径和文件名
- 第二个参数表示编码格式
- 第三个参数表示帧率
- 第四个参数表示视频尺寸大小
- 第五个参数表示视频图像类型(true彩色,false灰度)
需要注意的是fourcc的常用格式有
视频读取
#include
#include
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap("E:/myFile/video/ty.mp4");
Mat frame;
if (!cap.isOpened())
{
cout << "无法打开视频文件!" << endl;
return -1;
}
namedWindow("video", CV_WINDOW_AUTOSIZE);
while (cap.read(frame))
{
imshow("video", frame);
waitKey(10);
}
cap.release();
waitKey(0);
return 0;
}
视频写入
#include
#include
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap("E:/myFile/video/ty.mp4");
Mat frame, gray;
if (!cap.isOpened())
{
cout << "无法打开视频文件!" << endl;
return -1;
}
//获取视频帧的长和宽
Size size = Size(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
VideoWriter writer("E:/myFile/video/ty_g.mp4", CV_FOURCC('M', 'J', 'P', 'G'), 24, size, true);
namedWindow("video", CV_WINDOW_AUTOSIZE);
while (cap.read(frame))
{
//imshow("video", frame);
//转换为黑白图像
cvtColor(frame, gray, COLOR_BGR2GRAY);
//二值化处理
threshold(gray, gray, 0, 255, THRESH_BINARY | THRESH_OTSU);
cvtColor(gray, gray, COLOR_GRAY2BGR);
imshow("video", gray);
writer.write(gray);
waitKey(10);
}
waitKey(0);
cap.release();
return 0;
}
欢迎大家补充学习!!!