opencv3计算机视觉+Python(一)
基本I/O脚本
读/写图像文件
OpenCV的imread函数和imwrite函数能支持各种静态图像文件格式。不同系统支持的文件格式不一样,但都支持BMP格式,通常还应该支持PNG、JPEG和TIFF格式。
大多数常用的opencv函数都在cv2模块中。可能也会遇到其他基于cv或cv2.cv模块的opencv帮助,这些都是传统版本。Python模块被称为cv2并不表示该模块是针对OpenCv2.x.x版本的
imread()函数的参数:
1.IMREAD_ANYCOLOR=4
2.IMREAD_ANYDEPTH=2
3.IMREAD_COLOR=1
4.IMREAD_GRAYSCALE=0
5IMREAD_LOAD_GDAL=8
6.IMREAD_UNCHANGED=-1
cv.imshow(‘窗口名’,img)#必须要加上窗口名
且必须加
cv2.waitKey(0)
cv2.destroyAllWindows()否则会一闪跳过
图像与原始字节之间的转换
一个opencv图像是.array类型的二维或三维数组。
8位的灰度图像是一个含有字节值得二维数组。一个24维得RGB图像是一个三维数组,它也包含了字节值。可使用表达式访问这些值,例如image[0,0]或image[0,0,0]。第一个值代表像素y坐标或行,0表示顶部;第二个值是像素得x坐标或列,0表示最左;第三个值(如果可用得话)表示颜色通道。
若一副图像得每个通道为8位,则可将其显示转换为标准得一维Python bytearray格式:
byteArray=bytearray(image)
反之,bytearray含有恰当顺序的字节,可以通过显式转换和重构,得到numpy.array形式得图像:
grayImage=numpy.array(grayByteArray).reshape(height,width)
bgrImage=numpy.array(bgrByteArray).reshape(height,width,3)
视频文件得读/写
opencv提供VideoCapture类和videoWriter类来支持各种格式得视频文件。支持的格式类型会因系统的不同而变化,但应该都支持AVI格式。在到达视频文件末尾之前,VideoCapture类可通过read()函数来获取新的帧,每帧是一副基于BGR格式的图像
可将一幅图像传递给VideoWriter类的write()函数,该函数会将这幅图像加到VideoWriter类所指向的文件中。
特别注意:必须要为VideoWriter类的构造函数指定视频文件名,这个文件名对应的文件若存在,会被覆盖。也必须指定视频编解码器。编解码器的可用性根据系统不同而不同。下面是常用选项:
cv2.VideoWriter_fourcc(‘I’,’4’,’2’,’0’):该选项是一个未压缩的 YUV颜色编码,是4:2:0色度子采样。这种编码有很好的兼容性,但会产生较大文件,文件扩展名为.avi
cv2.VideoWriter_fourcc(‘P’,’I’,’M’,’1’):该选项是MPEG-1编码类型,文件扩展名为.avi
cv2.VideoWriter_fourcc(‘X’,’V’,’I’,’D’):该选项是MPEG-4编码类型,如果希望得到的视频大小为 平均值,推荐使用此选项,文件扩展名为.avi
cv2.VideoWriter_fourcc(‘F’,’L’,’V’,’1’):该选项是一个Flash视频,文件扩展名为.flv。
捕获摄像头的帧
VideoCapture类可以获得摄像头的帧流。但对摄像头而言,通常不是用视频的文件名来构造VideoCapture类,而是需要传递摄像头的设备索引(device index)
然而与前面不一样,VideoCapture类的get()方法不能返回摄像头帧速率(fps)的准确值,它总是返回0
import numpy as np
cameraCapture=cv2.VideoCapture()#调用摄像头
fps=
size=(int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))
videoWriter=cv2.VideoWriter('4.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)
success,frame=cameraCapture.read()
numFramesRemaining=*fps-#倒计时
while success and numFramesRemaining>:
videoWriter.write(frame)
success,frame=cameraCapture.read()
numFramesRemaining-=
cameraCapture.release()
摄像头的数量和顺序由系统决定。但opencv没有提供任何查询摄像头数量和属性的方法。如果使用无效索引构造了VideoCapture类,就不会得到帧,VideoCapture的read()函数会返回(false,None)。为了不让read()函数从没有正确打开的VideoCapture类中获取数据,可在执行该函数之后使用VideoCapture.isOpened方法做一个判断,该方法返回一个boolean值。
当需要同布一组摄像头或一个多头摄像头时,read()方法就不再适合,可用grab()和retrive()方法代替它。对于一组摄像头,可以使用以下代码
success0=cameraCapture0.grab()
success1=cameraCapture1.grab()
if success0 and success1:
frame0=cameraCapture0.retrieve()
frame1=cameraCapture1.retrieve()
在窗口显示图像
cv.imshow(‘窗口名’,img)#必须要加上窗口名
且必须加
cv2.waitKey(0)
cv2.destroyAllWindows()否则会一闪跳过
在窗口显示摄像头帧
OpenCV的namedWindow()、imshow()和DestroyWindow()函数允许指定窗口来创建,显示和销毁(destroy)窗口。此外,任意窗口下都可以通过waitKey()函数来获取键盘输入,通过setMouseCallback()函数来获取鼠标输入。
clicked=False
def onMouse(event,x,y,flags,param):
global clicked
if event==cv2.EVENT_LBUTTONUP:
clicked=True
CameraCapture=cv2.VideoCapture()
cv2.namedWindow('MyWindow')
cv2.setMouseCallback('MyWindow',onMouse)
print('Showing camera feed. Click window or press any key to stop')
success,frame=CameraCapture.read()
while success and cv2.waitKey()==- and not clicked:#要么键盘输入要么鼠标输入,要么摄像头获取帧不成功,否则会继续
cv2.imshow('Mywindow',frame)
success,frame=CameraCapture.read()
cv2.destroyWindow('MyWindow')
CameraCapture.release()
OpenCV的窗口函数和waitKey()函数相互依赖。OpenCV的窗口只有在调用waitKey()函数时才会更新,waitKey()函数只有在OpenCV窗口成为活动窗口时,才能捕获输入信息。
鼠标回调函数setMouseCallback()有5个参数,如前面的示例代码所示。param为可选参数,它是setMouseCallback()函数的第三个参数,默认情况下,该参数为0.回调事件参数可以取如下的值,他们分别对应不同的鼠标事件。
cv2.EVENT_MOUSEMOVE:该事件对应鼠标移动
cv2.EVENT_LBUTTONDOWN:该事件对应鼠标左键按下
cv2.EVENT_RBUTTONDOWN:该事件对应鼠标右键按下
cv2.EVENT_MBUTTONDOWN:该事件对应鼠标中间键按下
cv2.EVENT_LBUTTONUP:该事件对应鼠标左键松开
cv2.EVENT_RBUTTONUP:该事件对应鼠标右键松开
cv2.EVENT_MBUTTONUP:该事件对应鼠标中间键松开
cv2.EVENT_LBUTTONDBLCLK:该事件对应双击鼠标左键
cv2.EVENT_RBUTTONDBLCLK:该事件对应双击鼠标右键
cv2.EVENT_MBUTTONDBLCLK:该事件对应双击鼠标中键
鼠标回调的标志参数可能以下事件的按位组合:
cv2.EVENT_FLAG_LBUTTON:该事件对应按下鼠标左键
cv2.EVENT_FLAG_RBUTTON:该事件对应按下鼠标右键
cv2.EVENT_FLAG_MBUTTON:该事件对应按下鼠标中键
cv2.EVENT_FLAG_CTRLKEY:该事件对应按下Ctrl键
cv2.EVENT_FLAG_SHIFTKEY:该事件对应按下Shift键
cv2.EVENT_FLAG_ALTKEY:该事件对应按下Alt键
然而OpenCV不提供任何处理窗口事件的方法。例如当单击窗口的关闭按钮时不能关闭应用程序。由于Opencv有限的事件处理能力和GUI处理能力。
Cameo——面向对象的设计
Python的应用程序可用纯粹的面向过程语言来实现,像前面讨论的小应用程序(如基本I/O的脚本)通常会这样做。不过为了提高模块化水平和扩展性,下面将采用面向对象的方式实现。
通过前面介绍的OpenCV I/O功能可以知道,所有图像其实都是相似的,尽管图像的来源或去向不同。无论是从哪里获得的图像流,或者要将其输出到哪里,都可以将相同逻辑应用到图像流中的每个帧中。在应用中,将I/O代码与应用程序代码分离会变得特别方便,例如Cameo会使用多个I/O流
可创建CaptureManager类和WindowManager类作为高级的I/O流接口。在应用程序的代码中可以使用CaptureManager来读取新的帧,并能将帧分派到一个或多个输出中,这些输出包括静止的图像文件、视频文件以及窗口(可以通过WindowManager类来实现)。WindowManager类使应用程序代码能以面向对象的形式处理窗口和事件。
CaptureManager和WindowManager都具有可扩展性,因此,实现时可以不依赖OpenCV的I/O.
使用managers.CaptureManager提取视频流
无论该图像流来自视频文件还是摄像头,openCV都可以获取、显示和记录图像流,但是每种情况都有一些需要特殊考虑的地方。CaptureManager类对一些差异进行了抽象,并提供了更高级的接口从获取流中分配图像,再将图像分到一个或多个输出中(如图像文件、视频文件或窗口)。
在VideoCapture类中初始化CaptureManager类,在应用程序主循环的每一次迭代通常应调用CaptureManager类的enterFrame()和exitFrame()函数。在调用enterFrame()和exitFrame()函数之间,应用程序可能会设定通道属性并获取帧属性。通道属性的初始值是0,只有在多头摄像头的情况下,通道属性的初始值非0.帧属性是当调用enterFrame()函数时与当前通道状态对应的图像。
可能会经常调用CaptureManager类的writeImage()、startWritingVideo()和stopWritingVideo()函数。在调用existFrame()函数之前,会延迟写入文件。并且,在调用existFrame()函数的过程中,帧属性可能会在窗口中显示,这取决于应用程序代码是将WindowManager类作为CaptureManager的构造函数参数,还是设置previewWindowManager属性。
如果应用程序代码处理了帧属性,那么在记录文件和窗口中会有所体现。CaptureManager类中有一个称为shouldMirrorPreview的构造函数参数和属性,如果想要帧在窗口中镜像(水平翻转),但不记录在文件中,可将shouldMirrorPreview设置为True.通常,当面对摄像头的时候,用户喜欢摄像头返回镜像图像。
前面介绍过VideoWriter类需要帧速率,但OpenCV不能为摄像头提供准确的帧速率,解决这个问题的方法是通过帧计数器和Python标准的time.time()函数估计帧速率,但这些方法都有问题。由于帧速率不稳定以及time.time()函数需要依赖系统实现,有些时候,估计精度可能会很差。但是,如果在未知的硬件平台上运行应用程序,这样估计得帧速率会比随意假定一个摄像头的帧速率效果要好。
cameo.Cameo的强大实现
Cameo类提供两种方法启动应用程序:run()和onkeypress()。在初始化时,Cameo类会把onKeypress()作为回调函数创建WindowManager类,而CaptureManager类会使用摄像头和WindowManager类。当调用run()函数时,应用程序会执行主循环处理帧和事件,应用程序会调用onkeypress()函数处理事件。按空格键可获取截图信息,按tab键可启动/停止截屏(一个视频记录),按Esc键可以推出应用程序。
opencv3计算机视觉+Python(一)的更多相关文章
- 《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
1.源代码下载地址 <OpenCV3 计算机视觉--Python语言实现 第二版>由我们翻译,英文书名<Learning OpenCV3 Computer Vision with P ...
- OpenCV3计算机视觉+python(三)
使用OpenCV3处理图像 下面要介绍的内容都与图像处理有关,这时需要修改图像,比如要使用具有艺术性的滤镜.外插(extrapolate)某些部分.分割.粘贴或其他需要的操作. 不同色彩空间的转换 O ...
- OpenCV3计算机视觉Python语言实现笔记(四)
1. Canny边缘检测 OpenCV提供了Canny函数来识别边缘.Canny边缘检测算法有5个步骤:使用高斯滤波器对图像进行去噪.计算梯度.在边缘上使用非最大抑制(NMS).在检测到的边缘上使用双 ...
- OpenCV3计算机视觉Python语言实现笔记(三)
一.使用OpenCV处理图像 1.不同颜色空间的转换 OpenCV中有数百种关于在不同色彩空间之间转换的方法.当前,在计算机视觉中有三种常用的色彩空间:灰度.BGR以及HSV(Hue, Saturat ...
- OpenCV3计算机视觉Python语言实现笔记(二)
1. 图像与原始字节之间的转换 从概念上讲,一个字节能表示0到255的整数.目前,对于多有的实时图像应用而言,虽然有其他的表示形式,但一个像素通常由每个通道的一个字节表示. 一个OpenCV图像是.a ...
- OpenCV3计算机视觉+Python(五)
人脸检测和识别 本章将介绍Haar级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配.本章将考虑如何将多个Haar级联分类器构成一个层次结构,即一个分类器能识别整体区域(如人 ...
- OpenCV3计算机视觉+python(二)
不同色彩空间的转换 当前,在计算机视觉中有三种常用的色彩空间:灰度.BGR以及HSV 1.灰度色彩空间是通过去除彩色信息来将其转换为灰阶,灰度色彩空间对中间处理特别有效,比如人脸检测 2.BGR,即蓝 ...
- OpenCV3计算机视觉Python语言实现笔记(五)
图像的几何变换主要包括:平移.扩大与缩小.旋转.仿射.透视等等.图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到对应关系. 1. 图像的平移 图像的平移,沿着x方向tx距离,y方向ty距离 ...
- OpenCV3计算机视觉Python语言实现笔记(一)
Python3下OpenCV的安装 :http://blog.csdn.net/lwplwf/article/details/61616493 1. 读/写图像文件 OpenCV的imread()函数 ...
随机推荐
- atitit.跨语言执行cmd cli api的原理及兼容性设计草案
atitit.跨语言执行cmd cli api的原理及兼容性设计草案 1. 标准输入,标准输出,标准错误与重新定向1 2. 常见问题2 2.1. 执行bat文件2 2.2. 执行bat文件 /c ...
- 分享我们必须知道的高速GTX技术
eSATA接口只有几根线为什么那么快?连上网线显示的1Gbps是不是很令人兴奋!没错他们都用了高速GTX技术,GTX全称为Gigabit Transceiver,是为了满足现代数字处理技术和计算技术庞 ...
- __attribute__系列之介绍篇
1.什么是__attribute__? __attribute__机制是GNU C的一大特色,它可以设置函数属性.变量属性和类型属性等.可以通过它们向编译器提供更多数据,帮助编译器执行优化等. 2._ ...
- URL浅谈
URL中的锚 URL中的锚就是#,语法: #foo 其中定位锚的方式有2种,id和name属性都可以定位锚. 例子: <div name='top'>top</div>或者&l ...
- shell实现洗牌随机
洗牌问题: 洗一副扑克,有什么好办法?既能洗得均匀,又能洗得快?即相对于一个文件来说怎样 高效率的实现乱序排列? 关于洗牌问题,其实已经有了一个很好的shell解法,这里另外给三个基于AWK的方法, ...
- nginx的luajit安装luarocks并安装luafilesystem
nginx的luajit安装luarocks并安装luafilesystem by admin on -- :: in , 69次 标题有点绕口.我尽量把关键词都贴进去.之前因为自己的nginx安装了 ...
- ssh加密访问
ssh 加密访问 telnet 开放访问需安装软件openssh-server $ssh akaedu@192.168.103.114 $ssh 192.168.103.114 附: ...
- diamond源码阅读-diamond-client
读取数据 DiamondManager manager = new DefaultDiamondManager("DEFAULT_GROUP", "zml", ...
- Java手记
由于腾讯的MTA只有JAVA的demo,为了测试用php实现的加密算法是否正确,所有只能运行一下Java 配置环境:http://www.runoob.com/java/java-environmen ...
- 解决erlang R17无法识别中文问题
erlang更新到R17已有一段时间了.公司项目打算从旧版的erlang迁移到R17,却不料有不少的困扰,当中一个问题是中文问题. 这个问题非常easy重现:新建一个文件t.erl.保存为utf-8无 ...