【OpenCV 学习笔记】第一章: OpenCV入门

一、人工智能介绍

AI、5G、物联网 ---> 人工智能+物联网、互联网+移动互联网+物联网
随着5G设备的商用,越来越多的设备开始能够联网,比如通过语音控制,比如扫地机器人、智能音响、智能家居、自动驾驶等就是互联网+移动互联网+物联网的产物。所以,软件和硬件的结合就更为重要。
理论、实践

  • 机器视觉(Machine Vision) vs 计算机视觉(Computer Vision)
    通俗的说二者都是研究如何使机器看懂东西。或者说,二者都是研究如何用摄像机和电脑代替人眼对目标进行识别、跟踪和测量。比如,对目标物体的识别、确定目标物体的位置和姿态、对三维静物进行符号描述和解释等。目的是将图像处理成成适合人眼观察的图形,或者是处理成适合传送给仪器检测设备识别的图形。实现物体定位、特征检测、缺陷判断、目标识别、计数、运动跟踪等。

    所以计算机视觉第一步就是采集图像,采集图像可以由单个或者多个传感器获得,也可以由单个传感器在不同时刻获取图像序列
    第二步就是对采集到的图像进行处理,处理的技术手段有:几何模型、复杂的知识表达、基于模型的匹配和搜索技术、搜索的策略常使用自底向上、自顶向下、分层和启发式控制策略。

    机器视觉,十年前主要是指硬件设备,偏重于计算机视觉技术工程化,能够自动获取和分析特定的图像,以控制响应的行为。比如安保行业中的摄像头设备就自带的人脸识别、报警系统等,这种是偏硬件的机器视觉。而我们现在的计算机视觉,是偏重于算法、理论的。但是现在这两个概念基本已经不再进行区分了。

    计算机视觉为机器视觉提供图像和景物分析的理论及算法基础,机器视觉为计算机视觉的实现提供传感器模型、系统构造和实现手段。

  • 机器视觉的应用
    识别:人脸识别,车辆检测,体温检测,识别图像中的文字OCR(optical character recognition),QQ截图、提取文字
    图像拼接、修复、背景替换

二、OpenCV介绍

opencv是一款由intel公司俄罗斯团队,于1999年开发,2000年发布,的一个计算机视觉处理开源软件库,支持传统的计算机视觉算法、主流的机器学习算法以及其他深度学习算法的支持。目前这个库使用的人越来越多。
opencv最初是用C写的,后来重构过一次代码,用C++又写了一遍。同时在C/C++的基础上又封装了一层Java、JS、python、ruby、matlab等语言的接口。opencv-python是opencv的python API 。
我们选择python语言,是因为python语言简单,开发速度快。opencv底层使用C/C++的代码,速度有保障。而且opencv经过20多年的发展已经形成完整的生态链,所以使用起来比较方便。
跨平台:opencv可以在不同的系统平台上使用,包括windows,linux, os, android, ios, 而且基于CUDA和OpenCL的高速GPU操作接口也在积极开发中。
所有opencv的数组结构都转换为numpy数组,numpy是一个高度优化的数据库操作库,并且具有matplot风格的语法,所以安装opencv库之前一定要安装numpy库和matplotlib。

opencv里面基础的模块是core、highgui、imgproc三个模块。本课程主要就是围绕这几个模块展开。

  • core 模块
    实现最核心的数据结构及其基本运算,如绘图函数、数组操作相关函数等
  • highgui 模块
    是视频与图像的读取、显示、存储等接口
  • imgproc 模块
    实现图像处理的基础方法,包括图像滤波、图像的几何变换、平滑、阈值分割、形态学处理、边缘检测、目标检测、运行分析和对象跟踪等。

图像处理更高层次的模块:

  • features2d模块
    用于提取图像特征以及进行特征匹配,nonfree模块还有一些专利算法,是收费的,如sift特征。。
  • objdetect模块
    实现一些目标检测功能,经典的基于Haar、LBP特征的人脸检测,基于HOG的行人、汽车等目标检测,分类器使用Cascade Classification级联分类和Latent SVM等级联检测器。
  • stitching模块
    实现图像拼接功能。当我们要使用全景图片时,我们对目标进行部分部分的拍照,拍完照片后要进行拼接实现全景效果。这种技术在遥感影像中使用的比较多。
  • FLANN模块
    fast library for approximate nearest neighbors,快速近似最近邻搜索FLANN和聚类Clustering算法。
  • ml模块
    机器学习模块,包括svm, 决策树, Boosting等等。
  • photo模块
    包括图像修复和图像去噪两部分。
  • video模块
    针对视频处理,比如背景分离,前景检测,对象跟踪等。
  • calib3d模块
    就是Calibration(校准)3D,这个模块主要是相机校准和三维重建相关的内容。包含了基本的多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D信息的重建等等。
  • G-API模块
    包含超高效的图像处理pipeline引擎。

三、创建虚拟环境、安装OpenCV

  • 电脑硬件要求
    深度学习对电脑要求比较高,建议配置一个至少是8G的显卡。
    查看你的电脑上的显卡:我的电脑-管理-设备管理器-显示适配器-NVIDIA GeForce RTX 2070

  • 创建一个新的虚拟环境
    现在我们要装opencv的包,但是不想和以前的sklearn等混在一起,就想再新搭建一个虚拟环境。
    这里我打算把所有安装包放在D盘的OpenCV-0502文件夹里面,我就先打开OpenCV-0502文件夹,然后在路径条上敲cmd就进入当前路径下的cmd黑窗口,输入命令:pip install virtualenv,这个是安装虚拟环境的包,要创建新的虚拟环境,先要安装这个包。
    安装完毕后,继续输入命令:virtualenv lyyopencv,就是创建一个名字为lyyopencv的虚拟环境,回车,就把python外部环境拷贝到OpenCV-0502文件夹里面的lyyopencv文件夹里面了,我们可以在lyyopencv文件夹里面看到有Lib,Scripts文件夹和另外两个文件,这就是一个新建的、独立的新的虚拟环境。
    然后进入Scripts文件夹里面,在路径条里面cmd,进入Scripts下的cmd黑窗口,敲命令:activate,回车,就进入你上面创建的虚拟环境了:(lyyopencv) D:\OpenCV-0502\lyyopencv\Scripts>
    进入我们新建的虚拟环境后,就可以安装我们需要的opencv包以及opencv依赖的各种包了。但是opencv依赖的包比较多,比如numpy、pandas、matplotlib、jupyter等等,安装起来麻烦,我们可以安装:pip install opencv-python==3.4.1.15,等号后面是opencv的版本号,选这个版本号是因为Opencv在3.4.2之后有些算法申请了专利,用不了了,得付费使用。如果你的代码效果想和我的一模一样,建议你最好也按照和我一样的版本。
    选择安装opencv的扩展包:pip install opencv-contrib-python==3.4.1.15
    如果你想opencv、opencv扩展包以及其他依赖包一起装,用空格就可以:pip install opencv-python==3.4.1.15 opencv-contrib-python==3.4.1.15 jupyter matplotlib -i https://pypi.douban.com/simple,回车。 由于jupyter、matplotlib等包比较大,所以命令后面一定要跟一个国内的镜像源,就是-i后面的网址,由于豆瓣的网址好记忆,我这里就用豆瓣的镜像源,也可以用清华源等,都可以。
    安装完毕后,敲命令:ipython,回车,再敲命令:import cv2,再敲命令:cv2.version,再敲exit(),环境就搭建好了。
    说明:虚拟环境不能快速复制到别的电脑,需要重新安装。安装时一定要关闭VPN。

  • 进入上面创建的虚拟环境编写代码:
    从我的电脑进入到D-->OpenCV-0502-->lyyopencv-->Scripts,在路径条内cmd,进入D:\OpenCV-0502\lyyopencv\Scripts>,敲:activate,激活,进入:(lyyopencv) D:\OpenCV-0502\lyyopencv\Scripts>表示成功进入你创建的虚拟环境,敲:jupyter notebook,回车,进入jupyter notebook的根目录界面,这个界面里面的所有文件都是Scripts文件夹里面的文件,所以不能随便删。但是我们不应该在这个目录下面创建文档文件,因为这样的话,文档文件和环境文件就夹杂在一起,十分混乱!
    此时在小黑窗口敲:ctrl+c,c连敲2下,就退出notebook了,重新到(lyyopencv) D:\OpenCV-0502\lyyopencv\Scripts>,敲:cd ../..回车,进入:(lyyopencv) D:\OpenCV-0502>进入上两级目录(说明如果是cd ..就是进入上一级目录),此时敲命令:jupyter notebook,就进入以OpenCV-0502为根目录的环境下,可以在这个目录下建立你的文档文件夹名字("opencv学习笔记"),这样文档文件和环境文件夹就分开了。我这里的环境文件是lyyopencv文件夹里面的文件。文档文件是"opencv学习笔记"文件夹里面的文件。这样,环境文件和文档文件一目了然。
    我们使用Jupyer是因为我们讲的是opencv,opencv主要是处理图像,jupyter处理图片可以把处理的中间结果保留下了,方便我们随时查看。另一方面,pycharm是一个相对重型的IDE工具,而jupyter方便一些。

  • 环境变量查看:
    我的电脑-属性-关于-高级系统设置-环境变量-用户变量、系统变量的path双击查看。
    说明:一旦环境弄乱了,只能全部删除重新安装。

四、图片处理入门代码 

  • 1、倒库
    import cv2
  • 2、创建窗口
    cv2.namedWindow()
    cv2.resizeWindow() #改变窗口大小
    cv2.namedWindow('lena', cv2.WINDOW_AUTOSIZE)    #创建命名窗口  A  
    
    
    #更改窗口大小,但是在cv2.WINDOW_AUTOSIZE模式下无法更改窗口大小  
    cv2.namedWindow('chuangkou', cv2.WINDOW_NORMAL)   #在window_normal模式下更改窗口大小
    cv2.resizeWindow('chuangkou', 800, 600)   #窗口更改为800x600大小的尺寸  

A:第一个参数是窗口的名称,第二个参数flag,是规定窗口的一些性质,比如flag=cv2.WINDOW_AUTOSIZE,就表示窗口大小随要显示的图片的大小变化而变化,在这种模式下,窗口不能再更改大小了。
注意:一运行这行代码,电脑屏幕上就会出现一个窗口,我们点击这个窗口,就会卡死,显示未响应,就得关闭程序,就是关闭这个jupyter文件对应的进程。这种不是规范的操作,因为没有imshow(),就是没有展示的图片。

  • 3、加载图像
    就是把图像数据从硬盘中读到内存
    cv2.imread()
    img = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
    img.shape
    img.dtype

    第一个参数是图像的路径。路径一定要正确。路径不能有汉字。路径是一个字符串所以要用单引号括起来,路径里面有反斜杠所以前面要加r。
    第二个参数如果是0(单通道的灰度图像),1(3通道的BGR图像),-1(原格式),默认值是1。
    查看图像: img.shape ; img.dtype 

  • 4、显示图像

(1)使用opencv显示图像

cv2.imshow('lena', img)       #生成画布并且显示图像
cv2.waitKey(3000)             #设置图像显示的时间    
cv2.destroyWindow('lena')     #释放(销毁)图像和图像窗口

返回: -1

cv2.imshow('aaa', img)
显示图像函数;第一个参数是要显示的图像的窗口名称,第二个参数是要显示的图像对象。
如果暂时没有图片可以用0代替,例如:cv2.imshow('chuangkou',0),此时运行代码就会出现一个几乎没有显示窗口的窗口。
说明:这个函数实际上可以实现先创建窗口再显示图像两个功能,所以如果前面没有创建窗口也没关系,这行代码会自动创建新窗口的。

cv2.waitKey()
等待用户输入,也就是等待按键。参数delay就是延迟的意思。如果没有这行代码,前面的cv2.imshow()代码运行完毕后,图像只能一瞬间显示一下就没有了,我们肉眼可能都看不到图像是否显示了。如果加上这行代码就表示图像在规定时间内一直显示,这样我们就能看到窗口里面的图片了。
函数参数默认值是0。当参数为默认值0或者为负值时,底层就会一直执行while循环执行这行代码,等待键盘的输入,也就是程序就会一直卡在这行代码上,不会往下执行,这样窗口就会一直显示图片,直到一旦有键盘输入敲击,这行代码停止执行,窗口图片消失,并且返回被敲击的键的ASCALL码,代码开始往下继续执行。
当参数值为大于0的值时,就表示图像显示时间,以毫秒ms为单位,比如参数=10000时,就表示图像显示10秒钟。如果在这10秒钟内没有触碰键盘,在这10秒钟内就一直执行这行代码,就是程序一直在执行图像显示的功能,不能执行下面的代码。当时间超过10秒,这个函数执行完毕返回-1,开始执行后面的代码。当时间没有超过10秒,如果窗口就收到键盘敲击,则这行代码也结束运行,并返回被敲击键的ASCALL码。

ord('a')  #python内置函数,用来获取字符的ascll码值。

cv2.destroyWindow('aaa')  #释放指定窗口;参数表示要释放的窗口的名称。

cv2.destroyAllWindows()  #释放所有的窗口;不填任何参数。

说明:python函数编码规范,单词首字母小写,单词与单词之间用下划线连接,比如wait_key,而C和C++的规范是waitKey驼峰式命名。

#小知识点:我们可以利用cv2.waitKey()来销毁窗口,不然每次都要重启python  
key = cv2.waitKey(0)        #用一个对象key来接受函数的返回值
if key & 0xFF == ord('q'):  #& 0xFF可以省略,也可以写上。A
    cv2.destroyAllWindows()

A:因为cv2.waitKey()函数返回值key是一个int类型,最少都是16位的,但是ascii码是8位的,只有8位。一个F表示4位,FF表示8位,0xFF就表示最后8位,
&符号相当于and条件,就是多加一个判断条件,就是把key的最后8位取出来,再和ord('q')对比是否相等。用C和C++的程序员习惯这样的写法。

说明:cv2.imshow()和cv2.waitKey()和cv2.destroyWindow()这三个函数是一套的,一般都放在一起,不然要么无法显示,要么就是被卡死,需要重启Pyhton。

#把显示图片的方法封装成一个函数,这样就方便复用  
def cv_show(windowName, img):
    cv2.imshow(windowName, img)
    key = cv2.waitKey(0)
    if key & 0xFF == ord('q'):
        cv2.destroyAllWindows()

说明:把上面的函数放到一个.py文件里面,以后导包就可以调用这个函数了。
方法是:打开一个记事本,把上面的代码复制到记事本里,保存文件时命名文件为utils.py,把这个py文件放到根目录下面。
用的时候用代码:
from utils import cv_show
cv_show('chuangkoumingcheng', img)
也可以直接执行一下utils.py这个外部文件,执行之后,jupyter就会自动把外部函数导入了:
%run utils.py

(2)使用matplotlib显示图像
除了用opencv显示图像,我们还可以用matplotlib显示图像:

#使用matplotlib显示彩色图像
import cv2
import matplotlib.pyplot as plt
lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')   #opencv读取的图像是BGR格式
plt.imshow(lenacolor[:,:,::-1])  #matplotlib显示的图像是rgb格式,所以要把图像的通道顺序倒序排列一下。
plt.show()

【OpenCV 学习笔记】第一章: OpenCV入门_第1张图片

#使用matplotlib显示灰色图像
lenagray = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png', 0)  #读取的图像的时候可以将彩色图像直接就转化为灰度图像
plt.imshow(lenagray, cmap=plt.cm.gray)   #因为这是个灰度图像,所以要用第二个参数
plt.title('lena_gray'), plt.xticks([]), plt.yticks([])
plt.show()

【OpenCV 学习笔记】第一章: OpenCV入门_第2张图片

说明:
1、使用matplotlib显示图像就直接在jupyter里面显示了,如果用opencv显示会另外再生成一个图像显示的窗口,图像在窗口里面显示。

2、同样一个图像数据,用matplotlib显示出来和opencv显示出来是不一样的。matplotlib是按RGB的顺序读出并显示的。opencv是按BGR的顺序读出并显示的。

  • 5、保存图像
    cv2.imwrite(path, img)
    img2 = cv2.imwrite(r'C:\Users\25584\Desktop\lena3.bmp', img)

    第一个参数是要保存的目标文件的完整路径和文件名文件扩展名(文件格式)。
    第二个参数是被保存图像的名称。
    保存成功,返回值img2=true, 保存失败img2=false。

五、代码案例

#例1.1  读出lenacolor,并且打印出图像数据
import cv2
lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
print(lenacolor)
#例1.2  先生成一个窗口,再在这个窗口中显示图片
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.namedWindow('lena')
cv2.imshow('lena', lena)
cv2.waitKey(1000)

返回:-1

#例1.3 练习waitKey函数
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.imshow('nvshen', lena)
key = cv2.waitKey(20000)
if key==-1:
    print('女神别走!')
if key==32:
    cv2.destroyWindow('nvshen') 

返回:女神别走!

#例1.4 练习waitKey函数
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.imshow('nihao', lena)
key = cv2.waitKey()
if key!=-1:
    print('女神要消失啦')
    cv2.destroyWindow('nihao') 

返回:女神要消失啦

#例1.5 练习destroyWindow函数
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.imshow('demo', lena)
cv2.waitKey(1000)
cv2.destroyWindow('demo')
#例1.6 练习destroyAllWindows函数
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.imshow('demo1', lena)
cv2.imshow('demo2', lena)
cv2.waitKey()
cv2.destroyAllWindows()
#例1.7 将读取的图像保存到目标目录下
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp')
cv2.imwrite(r'C:\Users\25584\Desktop\lena4.bmp', lena)

返回:True

#例1.8 用while循环优化退出逻辑  
import cv2 
cv2.namedWindow('img', cv2.WINDOW_NORMAL)  #创建出来比较小,下面就把这个窗口resize一下
cv2.resizeWindow('img', 320, 240)
img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')

while True:
    cv2.imshow('img', img)
    key = cv2.waitKey(0)
    
    if key & 0xFF == ord('q'):
        break
    elif key & 0xFF == ord('s'):
        cv2.imwrite(r'C:\Users\25584\Desktop\lena5.bmp', img)
    else:
        print(key)
        
cv2.destroyAllWindows()

返回:-1

六、本章其他小知识点

1、图像是什么?
图:是物体反射或透射光的分布,是物体本身的固有的特征。
像:是人的视觉系统所接受的图在人脑中形成的印象或认识。

2、模拟图像和数字图像
模拟图像是连续存储的数据,易受噪声干扰,人眼看起来不是很清晰。
数字图像是分级存储的数据,一般是分256级,即8位。
目前模拟图像基本全部都已经被数字图像替代了。

你可能感兴趣的:(opencv,学习,计算机视觉)