初学OpenCV学习记录(十)

以下内容摘自《OpenCV2计算机视觉编程手册》

引言

本章内容主要是如何读取视频、处理和写入视频。

读取视频序列

视频其实就是一帧一帧的图像组成,这里的读取视频可以是视频文件或USB摄像头。
使用到的类为cv::VideoCapture,创建一个对象,构造参数为视频文件的名称,则会自动打开视频,例如:cv::VedeoCapture capture("../bike.avi"),如果要读取USB摄像头,那么需要指定的是整数的ID号,而不是文件名。
类中与读取视频序列相关的函数:

  • isOpend():检查视频是否成功打开
  • get(CV_CAP_PROP_FPS):获取视频的帧率
  • read():读取一帧图像,输入参数为Mat对象
  • release():关闭视频文件
  • set():指定视频读取的起始位置

注意:获取的帧率是double变量,使用式将其强制转化为long类型即可,得到帧率以后,我们就知道循环读取并处理每一帧图片的时间间隔设置为多少,可以比帧率快,也可以慢。另外,打开视频时,计算机中必须安装有对应的解码器,通常,如果你能用windows自带的播放器(Windows Media Player)打开视频,那么你就能用OpenCV读取它。

处理视频帧

在每一次的循环中,读取新的一帧图像并进行处理,处理方法主要靠之前学到的图像处理知识。
处理视频帧的设计方法可以有以下几种:

  • 直接编程,这种方法不便于代码移植,每个项目都需要单独编程。
  • 定义一个视频处理类,在类中做读取视频和写入视频的操作,这个类中定义一个用于处理数据的回调函数,那么如果要在项目中处理,直接使用这个视频处理类,并将写好的回调函数与其绑定,就可以使用了。
  • 定义一个帧处理类和视频处理类,视频处理类里的内容与上面一样,帧处理类中仅包含一个处理函数,是一个虚函数,这个帧处理函数就是一个接口,我们在实际用的时候要自己写一个类,继承于帧处理类,重写虚函数,然后使用视频处理类,视频处理类内部要设计函数设置帧处理类的实例,这个方法是最推荐的。

相关的代码可以参考书中的做法

写入视频

将处理完的图像保存为视频的形式,使用到的类为cv::VideoWriter
相关函数有:

  • open():打开一个输出视频
  • write():将图片作为一帧输出到视频文件

跟踪视频中的特征点

书中给出了一个例子是跟踪视频中的特征点,我们前面已经学了很多方法,可以获得一张图像中的特征点,实际上跟踪视频中的特征点,就是要对每一帧视频都提取特征点,但我们这里使用的函数是cv::calcOpticalFlowPyrLK(),为什么用这个函数呢?这个函数输入两个连续的图像中和第一幅图像中检测到的特征点,他会返回新的图像中的特征点,因为两帧之间特征点的移动不会太多,这个算法会在原先特征点的位置进行搜索,已找到新的特征点位置,算法的基本原理就是特征点在相邻帧之间强度保持不变,推导出基础光流约束,根据光流约束方程求解特征点的偏移量。
值得注意的是,我们需要在每次调用完上面的函数以后,判断并且去除那些跟踪错误的点,并且每次循环中检查特征点的数量,如果数量太少,就要重新初始化特征点,增加特征点数目。

提取视频中的前景物体

使用条件:相机固定,观察背景几乎保持不变,感兴趣的元素是场景中运动的物体,为了提取出这些前景物体,我们要对背景建模,然后用当前帧的图像与背景对比,检测前景物体,这是智能监控应用的基础步骤,这里不再多讲。
两种方法:

  • cv::absdiff()该算法通过简单的图像与背景图做差,得到前景图像,然后通过二值化得到前景物体图像,难点在于阈值的选取,因为场景中的模型不是一成不变的,所以要动态的创建背景模型,使用cv::accumulateWeighted()滑动平均更新背景模型,具体代码看书。
  • 第二种方法避免了阈值的选取,使用混合高斯算法,算法更为复杂,效果也更好,基本原理是该方法对每一个像素利用滑动平均值和滑动方差构建了一个高斯背景模型,对一新获取的一副图片,如果像素不在高斯模型上,那么就是一个前景物体,也会为其构建一个高斯模型,如果这个像素值反复的出现在这个新构建高斯模型上,那么这个高斯模型就会成为背景的一部分。具体代码看书。

猜你喜欢

转载自blog.csdn.net/weixin_42411702/article/details/123957862