上一篇文章介绍了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后端支持这个功能)

示例如下图所示

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

欢迎大家补充学习!!!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐