Python OpenCV视觉智能感知
第一讲——读取摄像头或视频文件并播放显示
本部分内容将深入、全面、详细地介绍如何使用Anaconda Python和OpenCV读取摄像头或视频文件,并进行播放。
1任务描述
使用Anaconda Python和OpenCV,读取摄像头或本地视频文件并播放显示。
2解题思路
要从摄像头或视频文件读取视频,首先应获取摄像头或视频文件,并判断是否获取成功。
获取摄像头或视频文件成功后,逐帧读取视频,播放显示。为了能够连续读取和播放视频的每帧图像,需要将读取和播放视频帧放在一个循环体里。由于不知道摄像头的视频帧数,可以构造一个无限循环体。对视频文件,可以构造一个无限循环体或以视频帧数为上限的有限循环体。在循环体内部应设置循环结束控制条件,以便能够控制结束读取和播放视频。
视频读取和播放结束后,应释放摄像头或视频文件,并销毁视频播放窗口。
3主要方法介绍
(1)导入OpenCV库cv2
要使用OpenCV,首先导入OpenCV库cv2.导入方法为:
import cv2
导入OpenCV库cv2的前提是确保计算机已经安装了OpenCV.Anaconda Python安装OpenCV的方法为在Anaconda Prompt窗口执行以下命令:
pip install opencv-python
(2)cv2.VideoCapture()方法
cv2.VideoCapture()方法用于创建一个VideoCapture对象,以捕获摄像头或视频文件。该方法接收摄像头的索引或视频文件名。如果只有一个摄像头,则以整数0进行索引。如果有多个摄像头,则分别以0,1,2…等整数进行索引。如果要读取视频文件,则需传入视频文件的全名称(包括路径和扩展名)字符串,形如’D:/opencv/videos/myvideo.mp4’.
(3)while方法
Python中使用while语句构造循环体,循环执行程序。即在条件满足情况下,循环执行某段程序,以重复处理相同任务。其基本形式为:
while判断条件(condition):
执行语句(statements)……
判断条件可以是任何表达式,任何非零、或非空(null)的值均为True。当判断条件为假False时,循环结束。
(4)read()方法
VideoCapture对象使用read()方法读取摄像头或视频文件的帧。该方法返回两个值,一般用ret,frame 命名接收,当然也可以命名为其他名称。其中第一个返回值ret是布尔值,如果读取帧成功返回True,如果读取失败则返回False。如果视频文件读取到结尾,它的返回值为False.第二个返回值frame是每一帧的图像数据,是个形状为(height,width,channels)的整数型三维数组。height,width,channels分别表示图像帧的高度、宽度、通道。数组中的每个元素的值是像素值,范围为0-255.3个通道0,1,2分别表示B(蓝),G(绿),R(红)。
(5)cv2.waitKey()方法
cv2.waitKey()方法用于暂停程序的执行,等待一段时间,在此期间如果有按键按下,则返回键值的ASCII 码,并响应相应的键盘事件。如果没有按键按下,则在等待设定的时间后,继续执行后续指令。waitKey()方法接收整数,表示等待的时间,单位是毫秒。如果传入的参数为小于等于0的整数,则表示无限等待,直到有按键按下。
(6)release()方法
VideoCapture对象使用release()方法释放自身。当不需要读取摄像头或视频文件时,应调用该方法释放VideoCapture对象。
(7)destroyAllWindows()方法
cv2.destroyAllWindows()方法用于释放视频播放窗口。当不需要播放视频时,应调用此方法销毁视频播放窗口。
4代码实现
任务实现代码如下。
In[]:import cv2#导入opencv
cap=cv2.VideoCapture(0)#创建VideoCapture对象
while(True):#创建无限循环,用于播放每一帧图像
ret,ad()#读取图像的每一帧
cv2.imshow('frame',frame)#显示帧
#等待1毫秒,判断此期间有无按键按下,以及按键的值是否是Esc键
if cv2.waitKey(1)&0xFF==27:
break#中断循环
cv2.destroyAllWindows()#释放视频播放窗口
Out:
5代码解析
上述代码中,使用cv2.VideoCapture(0)方法创建了一个VideoCapture对象cap.参数0是摄像头的索引。为读取和播放每一帧图像,使用while(True)创建了一个无限循环,在循环体内读取每帧图像并播放。
cv2.imshow()方法用于播放帧。它接收两个参数,如本例中cv2.imshow('frame',frame)所示。第一个参数接收字符串,表示播放视频窗口的名称,它将显示在窗口上方。第二个参数即要播放的图像帧。它可以是cap读取的图像frame,也可以是处理过的图像。
要终止播放,可以设置一个按键,当检测到该按键按下后,使用break方法中断循环。这里用到了cv2.waitKey()方法。它接收整数,表示等待的时间(毫秒)。在等待期间判断是否有按键按下,如果有则返回按键的ASCII码。如果传入的参数为小于等于0的整数,则表示无限等待,直到有按键按下。
由于不同操作系统返回的键值长度可能不一样,而ASCII码只有8位,为保险起见,将cv2.waitKey()返回的键值与0xFF进行与运算,只取其低8位,即cv2.waitKey(1)&0xFF,这样保证获得一个准确的ASCII 码。本例使用Esc(ASCII码的十进制为27)键作为终止循环按键。如果使用其他按键(例如q),则可以使用形如ord(’q’)的方法获取按键的ASCII码。
终止播放后,要使用lease()方法释放VideoCapture对象cap,使用cv2.destroyAllWindows()方法销毁播放窗口。
6拓展提高
上例中,实现了从摄像头读取视频、播放、退出的基本操作。实际上,从摄像头或视频文件成功读取视频并正确播放,还涉及许多细节。例如,如何判断捕获摄像头或视频文件成功?如果读取帧失败应该怎么处理?如何使用其他按键退出播放?等等。下面对这些问题进一步进行介绍。
(1)读取摄像头并播放,按q键退出播放
下面,使用ord()方法获取字符的ASCII码值,以实现按其他键退出视频播放。ord(‘q’)将返回字母q的
ASCII码值。
任务实现代码如下。
In[]:#读取摄像头并播放,按q键退出播放
import cv2#导入opencv
cap=cv2.VideoCapture(0)#创建VideoCapture对象
while(True):#创建无限循环,用于播放每一帧图像
ret,ad()#读取图像的每一帧
cv2.imshow('frame',frame)#显示帧
#等待1毫秒,判断此期间有无按键按下,以及按键的值是否是Esc键
if cv2.waitKey(1)&0xFF==ord('q'):
break#中断循环
cv2.destroyAllWindows()#释放视频播放窗口
Out:
类似的,如果想使用其他键退出播放,可以在ord()中传入其他按键对应的字符。
(2)观察ad()方法返回的参数值
In[]:#读取摄像头并播放,按Esc键输出ret,frame的信息,并退出播放
import cv2#导入opencv
cap=cv2.VideoCapture(0)#创建VideoCapture对象
while(True):#创建无限循环,用于播放每一帧图像
ret,ad()#读取图像的每一帧
cv2.imshow('frame',frame)#显示帧
#等待1毫秒,判断此期间有无按键按下,以及按键的值是否是Esc键
if cv2.waitKey(1)&0xFF==27:
print('退出前ret的值为:',ret)
print('frame的数据类型为:',frame.dtype)
print('frame的形状为:',frame.shape)
print('退出前frame的部分元素值为:\n',frame[100,100:200,0])
break#中断循环
cv2.destroyAllWindows()#释放视频播放窗口
Out:退出前ret的值为:True
frame的数据类型为:uint8
frame的形状为:(480,640,3)
退出前frame的部分元素值为:
[144144144144143143143143144144144144144144145146144144
145145143146139123116120122123127129130136140141142148
148150149152154156155159162162162164164165165169169169
166169170170168170170170170170170171168168170170169171
171172171171172171172172170172173173173174174173173175
174173174174172172171172170173]
可以看出,ad()方法返回的第一个参数为ret=True.frame的数据类型为uint8,即8位整数。frame 的形状为(480,640,3),表示高480像素,宽640像素,有3个颜通道。
frame是一个数组。frame[100,100:200,0]表示索引号为0的颜通道中,索引号为100的行上,列索引号为从100到200(不包括200)位置的元素。这涉及Python对数组的索引,将在后续章节专门介绍。
从输出结果可以看出,frame[100,100:200,0]输出了一系列整数值,它们表示相应位置的像素值,是0-255的整数。
(3)读取视频文件并播放,按Esc键输出ret,frame的信息,并退出播放
在使用cv2.VideoCapture()方法创建VideoCapture对象时,如果传入视频文件的全名,包括路径和视频文件扩展名,则可以播放视频文件。以下代码实现视频文件的播放。读者可自行用手机拍摄视频,保存到计算机后使用以下代码进行播放。播放时只需在cv2.VideoCapture()方法中替换文件名称即可。
In[]:#读取视频文件并播放,按Esc键输出ret,frame的信息,并退出播放
import cv2#导入opencv
#创建VideoCapture对象
cap=cv2.VideoCapture('D:/intelligent_sensing/videos/my_video.mp4')
while(True):#创建无限循环,用于播放每一帧图像
ret,ad()#读取图像的每一帧
cv2.imshow('frame',frame)#显示帧
#等待1毫秒,判断此期间有无按键按下,以及按键的值是否是Esc键
if cv2.waitKey(1)&0xFF==27:
print('退出前ret的值为:',ret)
print('frame的数据类型为:',frame.dtype)
print('frame的形状为:',frame.shape)
print('退出前frame的部分元素值为:\n',frame[500,500:600,1])
break#中断循环
cv2.destroyAllWindows()#释放视频播放窗口
Out:退出前ret的值为:True
frame的数据类型为:uint8
frame的形状为:(1920,1080,3)
退出前frame的部分元素值为:
[103124109825340434448514743403934353235
35200077141157173172154143114885341485559
455573921111151221351491501581611591471291096847
3120100000111200000003
python怎么读文件夹下的文件夹152949797478120164177178181185183177165159157158
161161158152148144142139138139]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论