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在哪裏呢?