使用python開啟你的opencv之旅---圖像的讀入,存儲


python的便捷是如此的引人着迷,而opencv給python提供的接口使我們能夠使用python來快速驗證我們的想法,或者與別的模塊快速結合,在這個系列文章我會通過jupyter notebook來快速展示opencv的使用

#在開頭引入必要的庫
import matplotlib.pyplot as plt
import numpy as np
import cv2
#ipython 
%matplotlib inline

圖像讀取

opencv使用imread讀取圖片,imshow顯示圖片,但是對於我而言,常使用jupyter作為展示的工具,imshow在瀏覽器環境中就失去了它的作用,因此我會使用matplotlib來展示

#讀取一張圖片
cv2.imread(img,flag)
#img這一參數中填入圖片的完全路徑或者相對路徑

這里我們需要稍微了解下flag這個參數,這決定了opencv是如何讀入我們的圖像的
我們知道通常圖像每個像素點的顏色我們以RGB的格式來描述(或者RGBA),可以通過三基色(red,green,blue)來描述所有顏色,對於透明圖片我們會增加一個a(alpha)來描述其顏色的透明度.

    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名,通過補全驗證你的想法

我們在剛剛使用了默認的flag讀入了圖片,那么讓我們用用另外兩個試試效果

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圖是看不出區別的

圖片在python下的儲存方式

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM