OpenCV图像处理入门与实践

978-7-115-57056-7
作者: 荣嘉祺
译者:
编辑: 赵祥妮

图书目录:

详情

OpenCV 是一个开源的计算机视觉库,可以实现计算机视觉算法。本书从 OpenCV 用 Python 实现的基础语法讲起,逐步深入计算机视觉的进阶实战,并在最后配合项目实战案例,重点介绍使用 OpenCV 进行人工智能项目以及日常生活中小应用程序开发的方法。通过本书读者不但可以系统地学习有关计算机视觉的知识,而且还能对图像处理的算法有更为深入的理解。 本书基于 Python,由浅入深、循序渐进地介绍了 OpenCV 从入门到实践的内容。本书共 13 章,内容涵盖OpenCV 基础知识、常见的图像操作、图像去噪、图像轮廓的提取与分析,以及人脸识别、目标追踪等计算机视觉的项目实战。


图书摘要

版权信息

书名:OpenCV图像处理入门与实践

ISBN:978-7-115-57056-7

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


著    荣嘉祺

责任编辑 赵祥妮

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


OpenCV是一个开源的计算机视觉库,可以高效地实现计算机视觉算法。本书从OpenCV用Python实现的基础语法讲起,逐步深入计算机视觉的进阶实战,并在最后配合项目实战案例重点介绍使用OpenCV进行人工智能项目以及日常生活中小应用程序开发的方法。通过本书读者不仅可以系统地学习计算机视觉的相关知识,而且还能对图像处理的算法有更深入的理解。

本书基于Python,由浅入深、循序渐进地介绍了OpenCV从入门到实践的内容。本书共13章,内容涵盖OpenCV基础知识、常见的图像操作、图像去噪、图像轮廓的提取与分析,以及人脸识别、目标追踪等计算机视觉的项目实战。

本书内容通俗易懂,案例丰富,实用性强,可供图像处理领域的从业人员、OpenCV初学者学习参考,适合有一定Python基础的读者进阶学习,也可作为相关培训机构的教材。


OpenCV是人工智能领域的一大分支——计算机视觉的常用库,其覆盖面十分广泛,上至气象图像分析,下至相机美颜,甚至可以说只要与图像有关的内容都可以作为它应用的对象。

计算机视觉作为人工智能大数据的提供端之一,为后续的机器学习提供了大量的图像数据。可以说学习这方面的内容是学习图像处理和机器学习的过程中必不可少的一个重要步骤。

随着社会科技的发展,人工智能逐渐成为科技人士口中常见的话题。在AlphaGo击败围棋世界冠军以后,就连最普通的老百姓也能体会到人工智能的强大之处:强大的计算能力、多可能性的分析、多情景的适应能力。为此,各个高校也开始逐步重视学生在人工智能领域的发展,大学生A类竞赛中与人工智能领域相关的学科比赛的数目逐年增加,机器人格斗、机甲大师等众多比赛给人们提供了一场场酣畅淋漓的视觉盛宴。

对于人工智能,我想大多数人听到这个词会觉得这与自己可能不会有太多的瓜葛,但其实它本身并没有想象的那么神秘难解,甚至可以说随时都能开始学习,只是我们缺少一个合适的起点。而学习OpenCV提供的图像处理技术,恰巧就是一个好的起点。

对于笔者而言,初次学习OpenCV的原因可能与部分读者相似:参加比赛。笔者为了能参加2019年中国智能机器人格斗大赛而专门学习了OpenCV,虽然只是跟着OpenCV官方英文文档学习了短短几个星期,但还是完全沉迷其中、无法自拔了。

OpenCV是一个高效的图像处理库,提供了诸多简捷方法来帮助我们实现想法。因为笔者一开始就是在树莓派上进行相关内容的学习,所以使用Python来进行图像处理。被称为“最简单的语言”的Python与图像处理中常用的库OpenCV相结合,再加上矩阵操作库NumPy的辅助,使用户处理任何图像问题都能变得游刃有余,复杂问题也能被细化成各个小问题而逐一解决。

本书的特色在于笔者对每一个涉及的函数都进行了十分细致的讲解,即对应函数共有哪些参数可以填写,分别是什么意思,能填什么内容,作用是什么等,并配有专门示例进行函数演示,帮助读者深度理解函数。相关内容都配有案例和示例代码,以帮助读者更加熟练地掌握函数的语法以及各类操作。

经过前面9章的基础学习后,在最后几章我们会跳出书本,在生活中进行计算机视觉的学习。我们可以通过开启计算机的摄像头来与计算机进行人机交互,甚至可以与计算机进行手势交流、眼神交流、表情交流,让计算机识别出我们的行为并做出反应,使我们的学习更加有趣。

本书先从最基础的图片读取与写出、图片在计算机中的存储讲起,让读者对图像操作有一个基本的概念;接着介绍在OpenCV中如何对图像进行绘图、添加文字等操作,这样在后续章节中读者能够对识别出的物体进行框取操作;然后介绍如何对图像进行一些简单的操作,包括图像扩边、逻辑运算等。

在上述的学习过程中我们采用的是静态图片,结束前4章的学习后我们会开始使用计算机(或其他设备)的摄像头来进行静态+动态的双重学习。在第5章中,我们会学习一些简单的颜色空间转换、HSV(Hue, Saturation, Value)物体追踪以及视频存储等知识,让读者更加有兴趣和信心进行后续章节的学习。

第6章通过生活中的例子介绍了图像变换的知识,加强读者对图像变换的理解和掌握。第7章介绍图像中的噪点,逐个分析各种噪点的性质,并提供多种去噪方式,帮助读者在不同场合下完成噪点的去除。

在第8章中,我们会介绍图像边缘提取以及图像金字塔等知识,让读者对图像有更加深刻的认识,并且熟悉如何通过图像来提取对应边缘等相关内容。第9章起着承上启下的作用:覆盖了前面8章的知识点并做出相应的扩充,引出实践性的几章,为读者最后的学习实践扫除部分知识盲点。

在第10~13章中,我们会通过多形式、多方面、多途径的方式来了解并实现生活中图像处理的应用实例,例如人脸识别、背景提取、文字识别、手势识别等,帮助读者进一步提升所学的知识和技能。

本书的配套教学资源可在异步社区上获取,包括课件、视频、源代码。

本书主要适合以下读者阅读。

由于笔者自身水平有限,书中难免出现一些疏漏之处,诚恳希望各位读者指正,笔者联系方式为3405752849@qq.com。

最后,感谢本书编辑团队对我的肯定和帮助。


本章首先简单介绍了OpenCV,接着介绍在不同的编译环境中安装OpenCV的方法,然后介绍OpenCV中常用的Python内置函数、OpenCV中的常见错误,最后带领读者初步体验OpenCV的代码。

本章的主要内容如下。

 

注意:

对于Python内置函数的知识务必做到实时复习,以便后面编写实例代码。

 

OpenCV支持多种编程语言,包括C++、Python、Java等,使用范围十分广泛。它也可以在不同的操作系统上使用,包括Windows、Linux、macOS、Android和iOS等。

OpenCV-Python库可以说是OpenCV在Python中的一种尝试,使用方法类似于Python API(Application Programming Interface,应用程序接口)。它结合了OpenCV中C++实现的API的优点和Python的最佳特性,使用起来十分方便,因而受到了用户的喜爱。

之所以选择Python来实现OpenCV,是因为Python是一种面向对象的编程语言,它的简单性和代码可读性使程序员能够用更少的代码表达思想。虽然与C、C++等语言相比,Python运行速度比较慢,但是Python可以使用C或C++轻松扩展,从而提升其自身的运行速度。这也意味着我们可以在C或C++中编写计算密集型代码,并创建可用作Python模块的Python packet包器件。这么做有两个好处:首先,代码的运行速度与原始C或C++代码一样快(因为后台运行的实际上是C或C++代码);其次,使用Python编写代码比使用C或 C++更易上手。OpenCV-Python库就是原始OpenCV C++实现的OpenCV在Python语言中的移值。

除了OpenCV-Python模块以外,用户还可以使用NumPy模块,这是一个高度优化的数据库操作模块,使用类似于MATLAB的语法。所有OpenCV数组都可以转换为NumPy数组,这也使得OpenCV与使用NumPy的其他库的集成变得更加容易。

OpenCV支持与计算机视觉和机器学习相关的众多算法,并且应用领域正在日益扩展,大致有以下领域。

在了解OpenCV的背景知识后,相信很多读者已经迫不及待想要去尝试了。现在就让我们正式开始OpenCV的学习,首先完成OpenCV的安装。

如果要在Visual Studio 2017上使用OpenCV,可以通过以下步骤来完成Python-OpenCV库的安装(在更高版本的Visual Studio上的安装步骤基本相同)。

(1)创建一个Python的空项目,如图1.1所示。

图1.1 创建一个Python的空项目

(2)空项目创建完成以后,右击右侧的Python环境,在弹出的快捷菜单中选择“查看所有Python环境”,如图1.2所示。

图1.2 查看所有Python环境

(3)单击“概述”,选择“包”,如图1.3所示。

图1.3 选择“包”

(4)在文本框内输入“opencv-python”,单击下方的“运行命令:pip install opencv-python”安装OpenCV,如图1.4所示。

图1.4 单击“运行命令:pip install opencv-python”

(5)此时就已经完成了在Visual Studio 2017上安装OpenCV的过程。

 

注意:

这里安装OpenCV时不是搜索“opencv”,而是搜索“opencv-python”。

 

如果要在PyCharm上使用OpenCV,可以通过以下步骤来安装OpenCV-Python库(此处PyCharm的版本是2019.2.1,在更高版本的PyCharm上的安装步骤基本相同)。

(1)进入PyCharm界面,单击左上角的“File”,然后选择“Settings”,如图1.5所示。

图1.5 选择“Settings”

(2)进入Settings界面,在左侧的“Project: auto”中选择“Project Interpreter”,单击右上方的“+”号,完成库加载,如图1.6所示。

图1.6 库加载

(3)在上方的文本框中输入“opencv-python”后双击选中,单击左下角的“Install Package”下载安装包。

(4)下载完成后,OpenCV在PyCharm上的安装过程结束。

对于其他编译器[例如IDLE(Integrated Development and Learning Environment,集成开发和学习环境)],可以通过在Windows操作系统的计算机里执行命令“pip install opencv-python”来进行安装。

 

注意:

不建议使用IDLE一类的普通编译器,因为需要花费很多的时间去记忆每个函数的每个参数是什么。如果有自动提示会好很多,对于本书的学习而言,我比较推荐Visual Studio和PyCharm这两款编译器,因为它们不但有自动提示功能,而且使用起来更加顺手。

 

在计算机视觉中,使用者时常需要与计算机本身进行交互。举个简单的例子,打开摄像头进行自拍时,机器本身可能很难知道使用者想要它在什么时刻进行拍照这个动作,但是我们可以通过手动操作来实现。而我们与系统的交互一般传递的是ASCII(American Standard Code for Information Interchange,美国信息交换标准码),为此我们需要将键盘输入的字符转为ASCII来让计算机明白我们想要它去做些什么操作。

但在大多数的时候使用者都希望计算机能够自己独立工作而非需要其本人在旁边监督,为了增强计算机的独立工作能力,程序员在写程序的时候会考虑多种情况来提高程序的鲁棒性。

首先要学习的是实现使用者与计算机之间交互的基础——将键盘输入的字符转换为 ASCII,这里需要使用ord函数。

ord函数以一个字符(长度为1的字符串)作为参数,返回对应的ASCII数值或Unicode(统一码)数值。

ord函数的语法如下。

ord(char)

其中char为一个字符类型的参数,它的返回值是char所对应的十进制整数ASCII数值,如ord('a')返回97,ord('A')返回65。

 

注意:

如果所给的Unicode字符超出了Python的定义范围,则会引发一个名为“TypeError”的异常。

 

如果将图片[1]看成一种输入信号,那么其中难免会有噪声干扰计算机本身进行兴趣数据(即使用者想要的数据)的提取。为了尽可能减少干扰,我们常常会使用max函数和min函数来对含有噪声的图像进行去噪操作。

max函数和min函数分别返回给定参数的最大值与最小值,在本书中这两个函数使用的参数多为列表。

max函数的语法如下,[符号后表示的是参数可选项,可以不使用。

max(iterable, *[, key, default])

max函数的参数解释如下。

示例代码如下。

b=['a','B']
print(max(b))
print(max(b,key=str.upper))

第二行代码的运行结果为a,因为此时max函数会按照全体ASCII的顺序去比较数值大小,a对应的ASCII数值为97,B对应的ASCII数值为66,所以最大值为a。但是如果我们加入kdy的参数,如上面第三行:

key=str.upper

max函数的排列顺序就将按照字符的大写的ASCII数值去比较,此时a的大写字符A的ASCII数值为65,而B的ASCII数值为66,所以第三行代码的运行结果为B。

min函数的语法和max函数一致,只是返回值为给定参数的最小值。

 

注意:

key后面可以跟对象参数的方法。

 

与max函数和min函数相同,sorted函数也可以用来提高程序抗图片噪声干扰的能力。

sorted函数的作用是对所有可迭代的对象进行排序。

该函数的语法如下。

sorted(iterable, cmp=None, key=None, reverse=False)

sorted函数的参数解释如下。

返回值为经过排序的列表。

示例代码如下。

a=[1,2,3,4,5]
b=sorted(a,reverse=True)
print(b)

其运行结果如下。

[5,4,3,2,1]

本节介绍在后续的编程中可能会遇到的错误,读者在第一次阅读时,可以略读。倘若在后续编写程序时遇到了此类报错,可以再返回来翻阅查看,从而修正错误。

在计算机视觉中,使用频繁的库除了OpenCV以外,还有与其配合使用的NumPy库。这个库也可以仿照1.2节介绍的安装过程来进行安装,只需要把其中输入的“opencv-python”改成“numpy”即可。在CSDN等网站中查找计算机视觉的相关代码资料,并复制别人的代码后,用户可能会发现程序运行不起来,并且提示np这个模块没有找到,这个时候就要注意去看最前面的import代码是否写成了如下形式。

import numpy

如果出现上述错误,代码应改为如下形式。

import numpy as np

这样就可以解决np模块未找到的错误了。

&0xff是用户在调用cv2.waitKey的时候经常会加在后面的代码,但是它的意义到底是什么呢?其实很简单,如果你的计算机操作系统是64位的,在使用cv2.waitKey这个函数时就需要在其后加上&0xff,形式如下。

cv2.waitKey(0)&0xff

因为系统中的各个按键(例如键盘上的q键)都在ASCII表中有一个对应的值,但是系统中各个按键对应的ASCII码值并不一定只有8位(即不同系统中对应的ASCII码值不一定相同),但最后8位一定相同,所以此处加上&0xff是为了排除不同系统对判断按键的干扰。

用户运行代码时可能会遇到图片无法显示或者程序死机的情况,这时用户可以检查代码的最后是否有如下内容。

cv2.destroyAllWindows()

这一行代码的作用后面会具体介绍。

如果图片只是闪出一瞬间后就自动消失,请检查显示图片的代码中是否存在以下代码。

cv2.waitKey(0)

这行代码的作用是一直等待键盘的命令,如果没有接收到键盘命令。运行过程不会向下继续执行。

如果在运行摄像头捕捉视频的代码时,程序显示的摄像头中的内容一直处于静止状态并且按 q 键后就退出程序,与预先设计的“程序一直展示摄像头所摆内容”不符时,请检查cv2.waitKey函数的参数是否写成了如下形式。

cv2.waitKey(0)==ord('q')

如果是,请按照如下代码进行修改。

cv2.waitKey(1)==ord('q')

之后即可正常捕获图像数据。

OpenCV的版本有很多,一些机器人的树莓派使用的OpenCV版本可能较为老旧,所以会出现一些版本不同带来的问题。这里,笔者举一个极有可能遇到的由版本不同带来问题的函数:cv2.findContours。

在版本号4.0.0及以后的OpenCV中,cv2.findContours的返回值只有两个,分别是contours和 hierarchy,这两个返回值将在后续内容中详细介绍;而在老版本的 OpenCV 中,cv2.findContours的返回值有3个,分别是img、contours和hierarchy。如果不注意这点,可能会造成在计算机上可以运行的程序,在机器人的树莓派中却无法正常运行的错误;或者是在机器人的树莓派中可以运行的程序,在计算机中却无法正常运行的错误。而且不同版本的OpenCV中该函数使用的参数也略有不同,所以对于这个函数的使用大家要多多小心。

在了解了基本的理论后,大家肯定想要上手试一试,所以本节提供了一个示例代码,供读者体验OpenCV的强大之处。

该示例代码的作用是动态识别当前摄像头内色彩差异最大的物体的轮廓,并且推算出物体距离摄像头的距离,按q键退出,并且代码会将刚刚摄像头录制的内容保存到.py文件所在的文件夹内,名字为“text.avi”。示例代码如下。

import cv2
import numpy as np
#参数,根据测距公式:D=(F*W)/P
KNOWN_WIDTH=2.36
KNOWN_HEIGHT=8.27
KNOWN_DISTANCE=7.7
FOCAL_LENGTH=543.45
cap=cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('latest.avi',fourcc,20.0,(640,480))
while 1:
    #读取图像
    ret,img=cap.read()
    #翻转图像
    img=cv2.flip(img,1)
    #颜色转换
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #高斯滤波
    blurred=cv2.GaussianBlur(gray,(5,5),0)
    edges=cv2.Canny(img,35,125)
    #结构化元素
    kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
    #形态学变化
    closed=cv2.morphologyEx(edges,cv2.MORPH_CLOSE,kernel)
    closed=cv2.erode(closed,None,iterations=4)
    closed=cv2.dilate(closed,None,iterations=4)
    #寻找轮廓
    contours,hierarchy=cv2.findContours(closed,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    #寻找最大轮廓
    cnt=max(contours,key=cv2.contourArea)
    img=cv2.drawContours(img,[cnt],-1,(0,255,0),3)
    rect=cv2.minAreaRect(cnt)
    #计算距离
    distance=(KNOWN_WIDTH*FOCAL_LENGTH)/rect[1][0]
    #数据显示
    cv2.putText(img,"%.2fcm"%(distance*2.54),(img.shape[1]-300,img.shape[0]-20),cv2.FONT_HERSHEY_SIMPLEX,2.0,(0,0,255),3)
    #保存视频
    out.write(img)
    #图像显示
    cv2.imshow('img', img)
    cv2.imshow('edges', edges)
    cv2.imshow('closed', closed)
    if cv2.waitKey(1)==ord('q'):
        break
cap.release()
out.release()
cv2.destroyAllWindows()

该代码的视频、测距展示效果如图1.7所示。

图1.7 代码效果

这看起来是不是很神奇呢?下一章,我们将会介绍更多有关OpenCV的有趣知识。

[1] 在计算机视觉处理中,我们一般认为图像指的是“数字图像”,是一种原始连续信号经过抽样、量化后的结果状态:而图片则更多蕴含的是一种“初始”的概念,定义的范围比图像更加广泛。可以说,图像是图片的一种表达形式。


相关图书

计算机图形学编程(使用OpenGL和C++)(第2版)
计算机图形学编程(使用OpenGL和C++)(第2版)
计算机图形学入门:3D渲染指南
计算机图形学入门:3D渲染指南
从零开始:数字图像处理的编程基础与应用
从零开始:数字图像处理的编程基础与应用
趣味掌控板编程
趣味掌控板编程
OpenGL超级宝典(第7版)
OpenGL超级宝典(第7版)
OpenCV 4快速入门
OpenCV 4快速入门

相关文章

相关课程