python的便捷是如此的引人着迷,而opencv给python提供的接口使咱们可以使用python来快速验证咱们的想法,或者与别的模块快速结合,在这个系列文章我会经过jupyter notebook来快速展现opencv的使用python
#在开头引入必要的库 import matplotlib.pyplot as plt import numpy as np import cv2 #ipython %matplotlib inline
opencv使用imread读取图片,imshow显示图片,可是对于我而言,常使用jupyter做为展现的工具,imshow在浏览器环境中就失去了它的做用,所以我会使用matplotlib来展现c++
#读取一张图片 cv2.imread(img,flag) #img这一参数中填入图片的彻底路径或者相对路径
这里咱们须要稍微了解下flag这个参数,这决定了opencv是如何读入咱们的图像的
咱们知道一般图像每一个像素点的颜色咱们以RGB的格式来描述(或者RGBA),能够经过三基色(red,green,blue)来描述全部颜色,对于透明图片咱们会增长一个a(alpha)来描述其颜色的透明度.api
cv2.IMREAD_COLOR : 读入图片,任何与透明度相关通道的会被忽视,默认以这种方式读入. cv2.IMREAD_GRAYSCALE : 以灰度图的形式读入图片. cv2.IMREAD_UNCHANGED : 保留读取图片原有的颜色通道.
能够简单的用-1,0,1来分别表示这3个flag数组
就让咱们从著名的lenna图开始吧浏览器
lenna_img = cv2.imread("lena.jpg") plt.imshow(lenna_img) plt.axis("off")#去除坐标轴 plt.show()
当把这张图片打印出来后,你必定在疑惑,咦,这张图怎么变青色了?函数
缘由就在于opencv默认的imread是以BGR的方式进行存储的,而matplotlib的imshow默认则是以RGB格式展现,因此此处咱们必须对图片的通道进行转换工具
lenna_img = cv2.cvtColor(lenna_img,cv2.COLOR_BGR2RGB) plt.imshow(lenna_img) plt.axis("off") plt.show()
Lenna终于恢复了她的原本样子了
这里咱们了解一下cvtColor这个函数,它的第一个参数是图片,第二个参数则是颜色通道的转化方式
它的命名是有规律的一般以COLOR做为开头,后面则跟着它的转化方式,BGR通道转化为RGB,所以就是cv2.COLOR_BGR2RGB
你能够试着猜想从RGB通道转化为BGR通道的api名,经过补全验证你的想法code
咱们在刚刚使用了默认的flag读入了图片,那么让咱们用用另外两个试试效果orm
gray_lenna_img = cv2.imread("lena.jpg",0) orign_lenna_img = cv2.imread("lena.jpg",1) plt.subplot(121) plt.imshow(gray_lenna_img,cmap=plt.cm.gray) plt.axis("off") plt.subplot(122) orign_lenna_img = cv2.cvtColor(orign_lenna_img,cv2.COLOR_BGR2RGB) plt.imshow(orign_lenna_img) plt.axis("off") plt.show()
由于lenna图并无包含透明度这一通道,读入的仍然是BGR格式,因此咱们从lenna图是看不出区别的对象
opencv的一个Image对象在python和C++下的存储方式是不一样的,在c++下,经过opencv实现的Mat来进行存储,而python下则基于numpy
numpy对于使用python进行科学计算的人都不算陌生,它为python提供了一个高效的矩阵运算模块.
这就意味着咱们能够直接使用numpy的api对图片进行计算和处理.
print("Lenna图在python中存储的类型为",type(lenna_img)) print("读入lenna图的shape为",lenna_img.shape) print("以灰白图读入lenna图的shape为",gray_lenna_img.shape) #Lenna图在python中存储的类型为 <class 'numpy.ndarray'> #读入lenna图的shape为 (512, 512, 3) #以灰白图读入lenna图的shape为 (512, 512)
上文实现的bgr装RGB咱们也可使用numpy来轻松的实现
lenna_img = cv2.imread("lena.jpg") b,g,r = cv2.split(lenna_img) lenna_img = cv2.merge([r,g,b]) plt.imshow(lenna_img) plt.axis("off") plt.show() #结果以下
咱们能够对以前的函数进行一些包装,毕竟每次都要设定坐标轴为off怎么也会厌烦的啊
def show_cv_img(cv_image): image = cv2.cvtColor(cv_image,cv2.COLOR_BGR2RGB) plt.imshow(image) plt.axis("off")
考虑到subplot此处没有直接plt.show
show_cv_img(cv2.imread("lena.jpg"))#jupyter result
虽说咱们一般使用jupyter来使用opencv,但仍是要了解下opencv默认的imshow
img = cv2.imread("lenna.jpg") cv2.namedWindow('image', cv2.WINDOW_NORMAL)#给显示的窗口命名,后面的flag默认为cv2.WINDOW_AUTOSIZE,自动调整边框 #,可是在条形图过长时,使用windownormal咱们能够自行调整边框 cv2.imshow('image',img)#展现图片 cv2.waitKey(0)#等待按键按下 cv2.destroyAllWindows()#清除全部窗口
咱们可使用imwrite来存储一张图片,接受一个numpy的数组做为参数.
cv2.imwrite('cope_lenna_img.jpg',lenna_img) #result: True
他会返回一个bool值来表示它是否成功存储.
咱们成功在当前目录存储了一个叫作copy_lenna_img.jpg的图像.
Warning:
注意后缀.你的后缀是jpg仍是png决定它以怎样的方式保存
Opencv对于图像的读入和存储都已经封装好了给咱们,是咱们可以轻松的读入,存储,避免去了解图片文件的格式才能读取,存储图片,但仅仅这样显然不是opencv的真正面目,还不如直接用pillow呢.
那么Opencv到底NB在哪里呢?