Python计算机视觉:第十章 OpenCV
来源:互联网 发布:windows桌面消失 编辑:程序博客网 时间:2024/05/13 13:05
第十章 OpenCV
- 10.1 OpenCV Python接口
- 10.2 OpenCV基础
- 10.2.1 读取、写入图像
- 10.2.2 颜色空间
- 10.2.3 显示图像和结果
- 10.3 视频处理
- 10.3.1 视频输入
- 10.3.2 读取视频到NumPy数组
- 10.4 跟踪
- 10.4.1 光流法
- 10.4.2 Lucas-Kanade算法
这一章主要讲述通过Python接口使用目前流行的计算机视觉编程库OpenCV。OpenCV是一个C++库,用于实时处理计算机视觉方面的问题。
10.1 OpenCV Python接口
OpenCV是一个C++库,它涵盖了很多计算机视觉领域的模块。可以通过访问[http://opencv.willowgarage.com/ documentation/python/index.html]。
OpenCV目前最新的版本是2.4.8。实际上,OpenCV有两个Python接口,老版本的cv模块使用OpenCV内置的数据类型,新版本的cv2模块使用NumPy数组。对于新版本的模块,可以通过下面方式导入:
import cv2
而老版本的模块则通过下面方式导入:
import cv2.cv
在本章中,我们使用cv2模块,译者使用的OpenCV版本是2.4.6。
10.2 OpenCV基础
OpenCV提供了读取图像和写入图像,矩阵操作以及数学库函数。我们先来看看这些基本组件并学习怎样使用它们。
10.2.1 读取、写入图像
下面是一个简短的载入图像、打印尺寸、转换格式及保存图像为.png格斯的例子:
# -*- coding: utf-8 -*-import cv2# 读入图像im = cv2.imread('../data/empire.jpg')# 打印图像尺寸h, w = im.shape[:2]print h, w# 保存原jpg格式的图像为png格式图像cv2.imwrite('../images/ch10/ch10_P210_Reading-and-Writing-Images.png',im)
运行上面代码后,在ch10文件下保存有empire.jpg转换成.png格式的图片,即ch10P210Reading-and-Writing-Images.png,下面是转换格式后保存的.png的图像:函数imread()将图像返回为一个标准的NumPy数组,如果你喜欢的话,你可以将该函数用于PIL图像读取的备选函数。函数imwrite()能够根据文件后缀自动的进行格式转换。
10.2.2 颜色空间
在OpenCV中,图像不是用常规的RGB颜色通道来存储的,它们用的是BGR顺序。当读取一幅图像后,默认的是BGR,不过有很多转换方式是可以利用的。颜色空间转换可以用函数cvtColor()函数。比如,下面是一个转换为灰度图像的例子:
import cv2im = cv2.imread('../data/empire.jpg')# create a grayscale versiongray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
10.2.3 显示图像和结果
下面我们看一些用OpenCV进行图像处理并用OpenCV绘图及窗口管理功能显示图像后的结果的示例。
第一个例子是从文件中读取一幅图像,并创建积分图像表示:
# -*- coding: utf-8 -*-import cv2from pylab import *# 添加中文字体支持from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)# 读入图像im = cv2.imread('../data/fisherman.jpg')# 转换颜色空间gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)# 显示积分图像fig = plt.figure()subplot(121)plt.gray()imshow(gray)title(u'灰度图', fontproperties=font)axis('off')# 计算积分图像intim = cv2.integral(gray)# 归一化intim = (255.0*intim) / intim.max()#显示积分图像subplot(122)plt.gray()imshow(intim)title(u'积分图', fontproperties=font)axis('off')show()# 用OpenCV显示图像#cv2.imshow("Image", intim)#cv2.waitKey()# 用OpenCV保存积分图像#cv2.imwrite('../images/ch10/ch10_P211_Displaying-Images-and-Results-cv2.jpg',intim)# 保存figure中的灰度图像和积分图像fig.savefig("../images/ch10/ch10_P211_Displaying-Images-and-Results.png")
运行上面代码,显示如下结果,并在/images/ch10/目录下生成一幅保存有灰度图像和积分图像的图片:第二个例子从种子像素开始应用泛洪(漫水)填充:
# -*- coding: utf-8 -*-import cv2import numpyfrom pylab import *# 添加中文字体支持from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)# 读入图像filename = '../data/fisherman.jpg'im = cv2.imread(filename)# 转换颜色空间rgbIm = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)# 显示原图fig = plt.figure()subplot(121)plt.gray()imshow(rgbIm)title(u'原图', fontproperties=font)axis('off')# 获取图像尺寸h, w = im.shape[:2]# 泛洪填充diff = (6, 6, 6)mask = zeros((h+2, w+2), numpy.uint8)cv2.floodFill(im, mask, (10, 10), (255, 255, 0), diff, diff)# 显示泛洪填充后的结果subplot(122)imshow(im)title(u'泛洪填充', fontproperties=font)axis('off')show()#fig.savefig("../images/ch10/floodFill.png")# 在OpenCV窗口中显示泛洪填充后的结果# cv2.imshow('flood fill', im)# cv2.waitKey()# 保存结果# cv2.imwrite('../images/ch10/floodFill.jpg',im)
译者使用的是matplotlib显示泛洪填充后的结果,上面代码底下的注释部分是用OpenCV显示泛洪填充的结果。如果你用OpenCV窗口显示上面运行的结果,可以反注释。下面是上面泛洪填充后的结果:作为最后一个例子,我们看一下提取图像的SURF(加速稳健特征)特征。SURF是SIFT特征的一个快速版本。这里我们也会展示一些OpenCV绘制命令。
# -*- coding: utf-8 -*-import cv2import numpyfrom pylab import *# 读入图像im = cv2.imread('../data/empire.jpg')# 下采样im_lowres = cv2.pyrDown(im)# 转化为灰度图像gray = cv2.cvtColor(im_lowres, cv2.COLOR_RGB2GRAY)# 检测特征点s = cv2.SURF()mask = numpy.uint8(ones(gray.shape))keypoints = s.detect(gray, mask)# 显示图像及特征点vis = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)for k in keypoints[::10]: cv2.circle(vis, (int(k.pt[0]), int(k.pt[1])), 2, (0, 255, 0), -1) cv2.circle(vis, (int(k.pt[0]), int(k.pt[1])), int(k.size), (0, 255, 0), 2)cv2.imshow('local descriptors', vis)cv2.waitKey()cv2.imwrite('../images/ch10/ch10_P261_Fig10-3.jpg',vis)
上面代码先读入一幅图像,用pyrDown
下采样,得到的一幅尺寸是原图像尺寸一半的降采样图像,即im_lowres,然后将图像转换为灰度图像,并将它传递给SURF关键点检测对象。运行上面代码,可得下面SURF特征点检测结果:
10.3 视频处理
单纯利用Python处理视频是比较困难的,因为要考虑到速度、编解码器、摄像机、操作系统已经文件格式等问题。目前Python还没有视频处理库。Python处理视频的接口仅有的较好的就是OpenCV。在这一节,我们会展示一些对视频进行处理的基本例子。
10.3.1 视频输入
OpenCV能够很好地支持视频的读入。下面的例子展示了捕获视频帧,并在OpenCV窗口中显示它们:
import cv2# setup video capturecap = cv2.VideoCapture(0)while True: ret,im = cap.read() cv2.imshow('video test',im) key = cv2.waitKey(10) if key == 27: break if key == ord(' '): cv2.imwrite('vid_result.jpg',im)
上面VideoCapture从摄像头或文件中捕获视频。这里我们给它传递了一个整数作为初始化参数,它实际是视频设备的ID号,对于单个连着的摄像头,其ID号为0。read()方法解码并返回下一视频帧。waitKey()函数等待用户按下“Esc”(对应的ASCII码为27)终止应用,或按“space”将当前帧保存起来。
我们将上面例子进行拓展,使其能够在OpenCV窗口中对输出的视频进行模糊。对上面的例子进行稍微的修改便可实现该功能:
import cv2# setup video capturecap = cv2.VideoCapture(0)# get frame, apply Gaussian smoothing, show resultwhile True: ret,im = cap.read() blur = cv2.GaussianBlur(im,(0,0),10) cv2.imshow('camera blur',blur) if cv2.waitKey(10) == 27: break
上面对每一帧图像,将其传给GaussianBlur()函数,该函数实现对图像进行高斯滤波。在这个实例中,我们传递的是彩色图像,每一个颜色通道可以分别对其进行模糊。该函数以一个滤波器大小元组及高斯函数的标准差作为输入,如果滤波器大小设置为0,则它自动赋为标准差。运行上面的结果如下:
10.3.2 读取视频到NumPy数组
OpenCV可以从一个文件中读取视频帧序列,并将它们转换成NumPy数组。下面给出了一个从摄像头捕获视频,并将它们存储在NumPy数组中的例子。
import cv2from pylab import *# setup video capturecap = cv2.VideoCapture(0)frames = []# get frame, store in arraywhile True: ret,im = cap.read() cv2.imshow('video',im) frames.append(im) if cv2.waitKey(10) == 27: breakframes = array(frames)# check the sizesprint im.shapeprint frames.shape
上面每一帧数组会被添加到列表的末尾直到捕获终止。打印出的数组大小表示的帧数、高度、宽度、3。运行上面代码打印出的结果为:
(480, 640, 3)(40, 480, 640, 3)
这里,记录了40帧。类似如这样的视频数据数组非常适合视频处理,比兔计算视频帧差异以及跟踪。
10.4 跟踪
跟踪是对视频帧序列中的物体进行跟踪。
10.4.1 光流法
10.4.2 Lucas-Kanade算法
Lucas-Kanade算法原理这里略,具体可以参阅中译本。
import lktrackimnames = ['../data/bt/bt.003.pgm', '../data/bt/bt.002.pgm', '../data/bt/bt.001.pgm', '../data/bt/bt.000.pgm']# create tracker objectlkt = lktrack.LKTracker(imnames)# detect in first frame, track in the remaininglkt.detect_points()lkt.draw()for i in range(len(imnames)-1): lkt.track_points() lkt.draw()
import lktrackfrom pylab import *imnames = ['../data/viff/viff.000.ppm', '../data/viff/viff.001.ppm', '../data/viff/viff.002.ppm', '../data/viff/viff.003.ppm', '../data/viff/viff.004.ppm']# track using the LKTracker generatorlkt = lktrack.LKTracker(imnames)for im,ft in lkt.track(): print 'tracking %d features' % len(ft)# plot the tracksfigure()imshow(im)for p in ft: plot(p[0],p[1],'bo')for t in lkt.tracks: plot([p[0] for p in t],[p[1] for p in t])axis('off')show()
from: http://yongyuan.name/pcvwithpython/chapter10.html
- Python计算机视觉:第十章 OpenCV
- OpenCV计算机视觉编程Python版
- 《用Python构建机器学习》——第十章:计算机视觉-模式识别 读后小结
- 【python下使用OpenCV实现计算机视觉读书笔记1】输入输出
- opencv+python计算机视觉(一)之边缘检测canny
- Python计算机视觉:第七章 图像搜索
- Python计算机视觉:第九章 图像分割
- 《Python计算机视觉编程》
- python计算机视觉
- Python计算机视觉:安装
- OpenCV—计算机视觉库
- OpenCV计算机视觉入门案例
- 【计算机视觉】 opencv双目视觉 立体视觉 三维重建
- python计算机视觉项目实践
- Python计算机视觉编程 笔记
- python计算机视觉编程-01
- Python计算机视觉工具安装
- 【python下使用OpenCV实现计算机视觉读书笔记2】图像与字节的变换
- Python计算机视觉:第九章 图像分割
- [iOS]Objective-C Method Swizzling
- C++中的RVO和NRVO
- 写 5个不同的自己的函数来获取一个全路径的文件的扩展名, 允许封装php 库中已有 的函数(新浪)
- NumPy 简单应用
- Python计算机视觉:第十章 OpenCV
- 解决maven传递依赖中的版本冲突
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序 http://my.oschina.net/chihz/blog/58035
- OpenMP基础----以图像处理中的问题为例
- List,Set,Map的联系和区别
- system文件丢失或损坏问题的解决办法
- Android DPAD按键无法使用
- 优先级队列priority_queue
- Android Kotlin入门-控制流