OpenCV2学习笔记(九):视频流读取与处理

时间:2015-03-05 00:24:30   收藏:1   阅读:10980

由于项目需要,计划实现九路视频拼接,因此必须熟悉OpenCV对视频序列的处理。视频信号处理是图像处理的一个延伸,所谓的视频序列是由按一定顺序进行排放的图像组成,即帧(Frame)。在这里,主要记录下如何使用Qt+OpenCV读取视频中的每一帧,之后,在这基础上将一些图像处理的算法运用到每一帧上(如使用Canny算子检测视频中的边缘)。

一. 读取视频序列

OpenCV提供了一个简便易用的框架以提取视频文件和USB摄像头中的图像帧,如果只是单单想读取某个视频,你只需要创建一个cv::VideoCapture实例,然后在循环中提取每一帧。新建一个Qt控制台项目,直接在main函数添加:

#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 读取视频流
    cv::VideoCapture capture("e:/BrokeGirls.mkv");
    // 检测视频是否读取成功
    if (!capture.isOpened())
    {
        qDebug() << "No Input Image";
        return 1;
    }

    // 获取图像帧率
    double rate= capture.get(CV_CAP_PROP_FPS);
    bool stop(false);
    cv::Mat frame; // 当前视频帧
    cv::namedWindow("Extracted Frame");

    // 每一帧之间的延迟
    int delay= 1000/rate;

    // 遍历每一帧
    while (!stop)
    {
        // 尝试读取下一帧
        if (!capture.read(frame))
            break;
        cv::imshow("Extracted Frame",frame);
        // 引入延迟
        if (cv::waitKey(delay)>=0)
                stop= true;
    }
        return a.exec();
}

(注意:要正确打开视频文件,计算机中必须安装有对应的解码器,否则cv::VideoCapture无法理解视频格式!)运行后,将出现一个窗口,播放选定的视频(需要在创建cv::VideoCapture对象时指定视频的文件名)。

二. 处理视频帧

为了对视频的每一帧进行处理,这里创建自己的类VideoProcessor,其中封装了OpenCV的视频获取框架,该类允许我们指定每帧调用的处理函数。

首先,我们希望指定一个回调处理函数,每一帧中都将调用它。该函数接受一个cv::Mat对象,并输出处理后的cv::Mat对象,其函数签名如下:

void processFrame(cv::Mat& img, cv::Mat& out);

作为这样一个处理函数的例子,以下的Canny函数计算图像的边缘:

    // 对视频的每帧做Canny算子边缘检测
void canny(cv::Mat& img, cv::Mat& out) 
{
    // 先要把每帧图像转化为灰度图
    cv::cvtColor(img,out,CV_BGR2GRAY);
    // 调用Canny函数
    cv::Canny(out,out,100,200);
    // 对像素进行翻转
    cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
}

定义好一个视频处理类,它将与一个回调函数相关联。使用该类,可以创建一个实例,指定输入的视频文件,绑定回调函数,然后开始对每一帧进行处理,要调用这个视频处理类,只需在main函数中添加:

    // 定义一个视频处理类处理视频帧
    // 首先创建实例
    VideoProcessor processor;
    // 打开视频文件
    processor.setInput("e:/BrokeGirls.mkv");
    // 声明显示窗口
    // 分别为输入和输出视频
    processor.displayInput("Input Video");
    processor.displayOutput("Output Video");
    // 以原始帧率播放视频
    processor.setDelay(1000./processor.getFrameRate());
    // 设置处理回调函数
    processor.setFrameProcessor(canny);
    // 开始帧处理过程
    processor.run();
    cv::waitKey();

未完待续…

评论(1
ss-aifeizhibu 2017-02-09 15:37:38
请问一下,后边的更新在哪里
1
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!