天天看點

python opencv 讀取圖檔_Python opencv 讀取圖像

對于 matlab 起家做數字圖像處理的人來講都非常适應matlab對圖像處理的操作和思路,尤其是它可以非常友善直覺的看到圖像的RGB值。

由于最近在研究深度學習的計算機視覺方面的東西,于是完全自學接觸到opencv的Python接口,後面需要用到opencv幫助做一些圖像處理。但是作為一個自學小白,第一步就被讀取資料卡住了一晚上,後來終于想明白了。我查了半天,也沒有人對這個顯示做過多的說明,可能這個問題太簡單了不需要多說,但是畢竟我可能比較笨,是以就由我多嘴來說說這個事。

讀取圖像代碼:

import numpy as np

import cv2

im=cv2.imread("123.png")

print (im)

'''for x in range(10):print (im[1,x])'''

随便截了一張RGB圖,讀進來,發現是一堆這個。

請原諒我的無知,一開始我确實看不明白這個東西,想了很久,于是打開了matlab也讀了進來,後來想明白了。如果大家還是不明白可以自己讀入matlab和python做一個對比。

opencv的Python接口對于RGB圖像的讀入以後化成了标準的numpy數組的形式,但是是多元數組。顯示上,他是一個像素一個像素來顯示的,一顯示就是三個次元也就是【211 101 5】【裡面三個值是對應一個像素的】。然後一行一行的顯示,由于太多了,中間用...來省略了;每一行顯示完了,顯示第二行直到最後一行。同時opencv讀入的RGB圖像顯示通道是BGR,也就是第一個211的值其實是B,這一點和MATLAB是不同的,千萬注意。

也就是說這個奇葩的顯示說的其實是:

第一行第一個像素BGR值為:【211 101 5】 第一行第二個像素BGR值為:【210 100 4】中間太多了省略掉...,即按照以上的形式來顯示,第一行倒數第二個是【194 74 8】,第一行最後一個是【194 74 8】,然後第一行顯示完了,開始顯示第二行。

就這樣有省略之後,一直到最後。以上是我做的實驗。

下面貼一個整體上詳細的介紹:

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中存儲的類型為

#讀入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呢.

好了,以上系統的介紹是我貼的一個部落格上我覺得寫的特别好的大神的,連結在Referece中,其中的圖太麻煩,我就沒貼,想象一下就OK啦

Reference:https://www.cnblogs.com/lynsyklate/p/7720045.html​www.cnblogs.com