- OpenCV 4机器学习算法原理与编程实战
- 朱斌编著
- 1684字
- 2021-04-30 21:23:50
2.2 基本视频操作
如果说单张图像是二维数据,则视频是三维数据,它增加了时间维度z,单张图像与视频序列如图2-18所示。在机器视觉和机器学习结合的许多应用中都需要处理视频,本节将介绍OpenCV的基本视频操作。
图2-18 单张图像与视频序列
2.2.1 读取和播放视频文件
1. 实现方法
使用OpenCV读取和播放视频文件几乎与显示图像一样简单,只需设置一个循环结构,每次循环读取视频文件中的一帧图像用于显示即可,当然还需要设置退出循环的条件。读取和播放视频文件如示例代码2-6所示。
示例代码2-6 读取和播放视频文件
2. 代码分析
首先,实例化一个视频控制类函数cv::VideoCapture的对象cap,用于读取和操作视频文件:
其次,使用cap.open方法从源文件所在目录读取视频文件bike.avi:
然后,创建一个用于从视频文件中读取单帧图像的cv::Mat变量frame:
接下来是关键部分,创建for循环从视频文件中依次读取单帧图像并存储在frame中:
最后,当读取的frame是空图像时,即已读取到视频文件的最后一帧,退出循环:
如果读取的frame有数据,则显示frame:
另外,增加一个退出机制,即在播放过程中当有按键被按下时,cv::waitKey函数将返回按键的ASCII码(>0),并退出循环,停止播放,否则等待33ms后继续读取下一帧图像:
当然,也可以使用while循环控制视频文件的播放。
3. 运行结果
示例代码2-6的运行结果如图2-19所示,视频中的小女孩骑车从左至右经过画面。
图2-19 示例代码2-6的运行结果
2.2.2 处理视频文件
1. 实现方法
下面通过例子展示如何使用OpenCV调用摄像头并处理视频文件。如果计算机自带摄像头或已将USB摄像头连接至计算机,则只需将示例代码2-7中的cap.open("bike.avi")改为cap.open(0)即可打开摄像头。
示例代码2-7 调用摄像头并处理视频
2. 代码分析
首先,使用cap.open(0)方法打开默认摄像头,新建两个cv::Mat变量——frame和edge_img,分别用于存放摄像头捕获的图像与边缘检测后的图像:
然后,与示例代码2-6一样,在循环中获取一帧图像:
接下来,使用cv::Canny函数检测图像的边缘图像,并将其存储于edge_img变量中:
在两个窗口中分别显示源图与边缘图像:
设置循环退出条件,当按下“ESC”、“q”或者“Q”键时退出循环:
前面从整体上分析了示例代码2-7,下面简单介绍Canny边缘检测算法。Canny边缘检测算法结合了高低阈值计算出的两个边缘分布图,可生成最优边缘分布图。具体做法是在低阈值的边缘分布图中只保留有连续路径的边缘点,同时把这些边缘点连接到属于高阈值边缘分布图的边缘上。这样一来,高阈值分布图上的所有边缘点就都保留了下来,而低阈值分布图上的边缘点的孤立链被全部移除。这是一种很好的折中方案,只要指定适当的阈值,就能获得高质量的轮廓。这种基于两个阈值获得二值分布图的策略,称为滞后化阈值,适用于任何需要用阈值获得二值分布图的场景。
cv::Canny函数是OpenCV提供的边缘检测函数。
cv::Canny函数:
函数参数:
◎ image:8bit输入图像。
◎ edges:输出边缘图像,单通道8bit图像,尺寸与输入图像一致。
◎ threshold1:滞后阈值化的第1阈值。
◎ threshold2:滞后阈值化的第2阈值。
◎ apertureSize:Sobel操作员的孔径大小。
◎ L2gradient:标志,指示是使用更精确的L2范数计算图像梯度的大小(L2gradient =true),还是使用默认的L1范数(L2gradient = false)计算图像梯度的大小。
3. 运行结果
读取摄像头并处理示例代码2-7的运行显示结果如图2-20所示。
图2-20 读取摄像头并处理示例代码2-7的运行显示结果
2.2.3 存储视频文件
1. 实现方法
使用cv::VideoWrite类可以方便地在硬盘中写入不同编码方式的视频文件。在示例代码2-7的基础上,修改代码如下。
示例代码2-8 写视频文件
2. 代码分析
与示例代码2-7相比,在增加的代码中首先使用了cv::VideoCapture类的get方法来获取摄像头图像的宽和高:
然后根据这些参数,实例化一个cv::VideoWriter类的对象out,并调用open方法完成对out的初始化:
最后,在while循环中计算图像边缘后,使用cv::VideoWriter类的write方法将边缘图像edge_img一帧接一帧地写入视频文件my_video.avi中:
另一种写入视频的操作如下:
cv::VideoWriter::VideoWriter函数:
函数参数:
◎ filename:输出视频文件名。
◎ fourcc:由4个字母组成,表示帧压缩的编码方式。例如:
VideoWriter::fourcc('P', 'I', 'M', '1') 表示MPEG-1编码。
VideoWriter::fourcc('D', 'I', 'V', 'X') 表示MPEG-4编码。
VideoWriter::fourcc('M', 'J', 'P', 'G') 表示主运动jpeg编码。
◎ fps:每秒传输视频帧数,简称帧率。
◎ frameSize:视频帧的宽和高。
◎ isColor:如果不为零,则编码器如预期一样编码彩色帧,否则编码灰度帧(该标记当前仅在Windows上受支持)。
3. 运行结果
在源文件的目录下生成一个my_video.avi的视频文件,它存储了边缘检测结果视频,存储的视频文件缩略图如图2-21所示。
图2-21 存储的视频文件缩略图