上一篇文章介绍了OpenCV对于图像的处理方法,然而目前对视频的处理分析越来越成为计算机视觉的主流,视频中包含的信息量要远远大于图片,而本质上视频是由一帧帧的图像组成,所以视频处理最终还是要归结于图像处理,但在视频处理中,有更多的时间维的信息可以利用。本文主要介绍OpenCV在处理视频时的一些基本函数


1、视频的读取(cv::VIdeoCpature)

视频读取,主要利用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后端支持这个功能)

示例如下图所示

iOS openCV 播放yuv opencv读取视频_OpenCV

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方法还可以设置视频的帧率、亮度

2、视频的写入(cv::VIdeoWriter)

视频的写入与读取类似,使用VideoWriter类来实现,这个类有几个方法,除了构造函数外,提供了open、IsOpen、write、和重载操作符<<

cv::VideoWriter(const string& path,int fourcc,double fps, Size framesize, bool isColor=true)

  • 第一个参数表示保存的文件路径和文件名
  • 第二个参数表示编码格式
  • 第三个参数表示帧率
  • 第四个参数表示视频尺寸大小
  • 第五个参数表示视频图像类型(true彩色,false灰度)

需要注意的是fourcc的常用格式有

  • CV_FOURCC('P','I','M','1') = MPEG-1 codec
  • CV_FOURCC('M','J','P','G') = motion-jpeg codec
  • CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
  • CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
  • CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
  • CV_FOURCC('U', '2', '6', '3') = H263 codec
  • CV_FOURCC('I', '2', '6', '3') = H263I codec
  • CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

3、视频读写程序示例

视频读取

#include <opencv2/opencv.hpp>
#include <iostream>

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 <opencv2/opencv.hpp>
#include <iostream>

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;
}

欢迎大家补充学习!!!