欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > python >内容正文

python

Python计算机视觉:第十章 OpenCV

发布时间:2025/3/21 python 70 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Python计算机视觉:第十章 OpenCV 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

第十章 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 version gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

    10.2.3 显示图像和结果

    下面我们看一些用OpenCV进行图像处理并用OpenCV绘图及窗口管理功能显示图像后的结果的示例。

    第一个例子是从文件中读取一幅图像,并创建积分图像表示:

    # -*- coding: utf-8 -*- import cv2 from pylab import *# 添加中文字体支持 from matplotlib.font_manager import FontProperties font = 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 cv2 import numpy from pylab import *# 添加中文字体支持 from matplotlib.font_manager import FontProperties font = 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 cv2 import numpy from 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 capture cap = cv2.VideoCapture(0) while True:ret,im = cap.read()cv2.imshow('video test',im)key = cv2.waitKey(10)if key == 27:breakif key == ord(' '):cv2.imwrite('vid_result.jpg',im)

    上面VideoCapture从摄像头或文件中捕获视频。这里我们给它传递了一个整数作为初始化参数,它实际是视频设备的ID号,对于单个连着的摄像头,其ID号为0。read()方法解码并返回下一视频帧。waitKey()函数等待用户按下“Esc”(对应的ASCII码为27)终止应用,或按“space”将当前帧保存起来。

    我们将上面例子进行拓展,使其能够在OpenCV窗口中对输出的视频进行模糊。对上面的例子进行稍微的修改便可实现该功能:

    import cv2 # setup video capture cap = cv2.VideoCapture(0) # get frame, apply Gaussian smoothing, show result while 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 cv2 from pylab import * # setup video capture cap = cv2.VideoCapture(0) frames = [] # get frame, store in array while True:ret,im = cap.read()cv2.imshow('video',im)frames.append(im)if cv2.waitKey(10) == 27:break frames = array(frames) # check the sizes print im.shape print 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 object lkt = lktrack.LKTracker(imnames) # detect in first frame, track in the remaining lkt.detect_points() lkt.draw() for i in range(len(imnames)-1):lkt.track_points()lkt.draw()

    import lktrack from 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 generator lkt = lktrack.LKTracker(imnames) for im,ft in lkt.track():print 'tracking %d features' % len(ft)# plot the tracks figure() 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的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。