使用Numpy和Opencv完成基本圖像的數據分析(1)
來自專欄我是程序員
53 人贊了文章
摘要: 隨著科技的進步,使用Python包訪問數字圖像的內部變得更容易理解其屬性和性質,掌握對數字圖像處理的能力顯得是十分有必要。

關於像素的一些知識
在程序世界裡,圖像輸入到計算機中時,與人眼所見的圖像的形式不太一樣。計算機將圖像存儲為類似於馬賽克的小方塊,就像古老的方塊馬賽克藝術的形式。如果方形塊太大,那麼就很難製作出光滑的邊緣和曲線。使用的方塊越小,則越平滑,或者說圖像的像素就越少,方塊的大小有時候也被稱為圖像的解析度。
矢量圖像是存儲圖像的一些不同方法,目的是為了避免與像素相關的問題。但是,即使是矢量圖像,最終也會顯示為像素級的馬賽克。像素一詞表示圖像元素,描述每個像素的簡單方法是使用三種顏色的組合,即紅色(Red),綠色(Green),藍色(Blue),即我們平時所說的RGB圖像。在RGB圖像中,每個像素由分別與紅色,綠色,藍色的值相關聯的三個8比特數表示。假設使用放大鏡觀察,如果我們放大圖片,就會看到圖片是由微小的光點或更加具體的像素組成,更有趣的是,看到的那些小光點實際上是多個微小不同顏色的小光點,且顏色只有紅色、綠色和藍色。 假設現在從遠處觀察,創建一張圖像,可以看到一張圖像實際上由像素點值的開關決定(像素值為1表示開,像素值為0表示關),這些開關組合創建了圖像,基本上,我們每天在屏幕上看到的圖像都是這種。每張圖像都以數字形式的像素組成,像素是構成圖片的最小信息單位,通常是圓形或方形,且位於二維網格中。 現在,如果RGB三個值都處於全強度,這意味著其組合值為255,該值表示為白色,如果所有三種顏色都被減弱,或者值設置為0,其值表示為黑色。反過來,三者的不同組合將為我們提供不同特定的像素顏色。由於每個數字都是8比特,因此像素值的取值範圍為0-255,從下圖可以看到,但R的強度為37.3%,G的強度為45.9%,B的強度為18.8%時,組合成的顏色為深綠(dark green)。
- 導入圖像並觀察其屬性
- 拆分圖層
- 灰度化
- 對像素值使用邏輯運算符
- 使用邏輯運算符進行掩碼
- 衛星圖像數據分析
導入圖像
下面載入圖像並觀察其各種屬性。注意,在輸入下面代碼請確保好已經安裝好對應的python數據包。if__name__==__main__:importimageioimportmatplotlib.pyplotasplt%matplotlibinlinepic=imageio.imread(F:/demo_2.jpg)plt.figure(figsize=(15,15))plt.imshow(pic)

rint(Type of the image : ,type(pic))print()print(Shape of the image : {}.format(pic.shape))print(Image Hight {}.format(pic.shape[0]))print(Image Width {}.format(pic.shape[1]))print(Dimension of Image {}.format(pic.ndim))
其輸出
Type of the image :<class imageio.core.util.Image>Shape of the image : (562, 960, 3)Image Hight 562Image Width 960Dimension of Image 3 ndarray的形狀表明它是一個三維矩陣,輸出結果的前兩個數字分別表示高度(height)和寬度(width),第三個數字(即3)表示是該圖像是三通道彩色圖:紅色、綠色和藍色。因此,如果我們計算RGB圖像的大小,則總像素大小將是weiheigh x width x 3。print(Image size {}.format(pic.size))print(Maximum RGB value in this image {}.format(pic.max()))print(Minimum RGB value in this image {}.format(pic.min()))Image size 1618560Maximum RGB value in this image 255Minimum RGB value in this image 0
這些值對於驗證而言是很重要的,因為8位顏色強度不能超出0到255範圍。
使用圖片可以分配變數,此外還可以訪問圖像的任何特定像素值,並且還可以分別訪問每個RGB通道。pic[100, 50 ]Image([109, 143, 46], dtype=uint8)
在這種情況下:R = 109、G = 143、 B = 46,從這個配置可以看出該像素中有很多綠色,也可以通過三個通道的索引值來從中選擇出一個。根據一般規定:
- 索引0表示紅色通道
- 索引1表示綠色通道
- 索引2表示藍色通道但在OpenCV中,Images並不是按照RGB的順序規定,而是BGR。 imageio.imread將圖像載入為RGB(或RGBA),但OpenCV假定圖像為BGR或BGRA(BGR是OpenCVcolour的默認的式)。
print(Value of only R channel {}.format(pic[ 100, 50, 0]))print(Value of only G channel {}.format(pic[ 100, 50, 1]))print(Value of only B channel {}.format(pic[ 100, 50, 2]))Value of only R channel 109Value of only G channel 143Value of only B channel 46
plt.title(R channel)plt.ylabel(Height {}.format(pic.shape[0]))plt.xlabel(Width {}.format(pic.shape[1])) plt.imshow(pic[ : , : , 0])plt.show()

plt.title(G channel)plt.ylabel(Height {}.format(pic.shape[0]))plt.xlabel(Width {}.format(pic.shape[1])) plt.imshow(pic[ : , : , 1])plt.show()

plt.title(B channel)plt.ylabel(Height {}.format(pic.shape[0]))plt.xlabel(Width {}.format(pic.shape[1])) plt.imshow(pic[ : , : , 2])plt.show()

- R通道:第100行到110行
- G通道:第200行到210行
- B通道:行300行到310行
本次測試只在一張圖像上進行綜合處理,方便我們同時查看每個通道的值對圖像的影響。
pic =imageio.imread(F:/demo_2.jpg)pic[50:150 , : , 0] =255# full intensity to those pixels R channelplt.figure( figsize= (10,10))plt.imshow(pic)plt.show()

pic[200:300 , : , 1] =255# full intensity to those pixels G channelplt.figure( figsize= (10,10))plt.imshow(pic)plt.show()

pic[350:450 , : , 2] =255# full intensity to those pixels B channelplt.figure( figsize= (10,10))plt.imshow(pic)plt.show()

pic[50:450 , 400:600 , [0,1,2] ] =200plt.figure( figsize= (10,10))plt.imshow(pic)plt.show()

importnumpyasnppic=imageio.imread(F:/demo_2.jpg) fig,ax=plt.subplots(nrows=1,ncols=3,figsize=(15,5)) forc,axinzip(range(3),ax): # create zero matrixsplit_img=np.zeros(pic.shape,dtype="uint8")# dtype by default: numpy.float64 # assing each channel split_img[:,:,c]=pic[:,:,c]# display each channelax.imshow(split_img)

- 灰度:灰色陰影的範圍:0~255
- 二進位:像素為黑色或白色:0或255 灰度處理過程,就是將圖像從全彩色轉換為灰度圖。在圖像處理工具中,例如:在OpenCV中,在使用很多含住之前,需要將圖像進行灰度處理,這樣做是因為灰度處理簡化了圖像,幾乎像降噪一樣,這是因為灰度圖像中的信息比較少。
在python中有兩種方法可以將圖像轉換為灰度。但是,更直接的方法是使用matplotlib包,該包執行的操作是獲取原始圖像的RGB值後進行加權平均。
Y = 0.299 R + 0.587 G + 0.114 Bpic=imageio.imread(F:/demo_2.jpg) gray=lambdargb:np.dot(rgb[...,:3],[0.299,0.587,0.114])gray=gray(pic) plt.figure(figsize=(10,10))plt.imshow(gray,cmap=plt.get_cmap(name=gray))plt.show()

- 亮度(Lightness)灰度等級計算為
Lightness = ?×(max(R,G,B)+ min(R,G,B)) - 照明度(Luminosity)灰度級將計算為
Luminosity= 0.21×R + 0.7×G + 0.07×B - 平均亮度灰度級將計算為
Average Brightness=(R + G + B)÷3
下面讓我們嘗試實現一下這三個演算法中的一種吧,本文選擇Luminosity。
pic=imageio.imread(F:/demo_2.jpg) gray=lambdargb:np.dot(rgb[...,:3],[0.21,0.72,0.07])gray=gray(pic) plt.figure(figsize=(10,10))plt.imshow(gray,cmap=plt.get_cmap(name=gray))plt.show() print(Type of the image : ,type(gray))print() print(Shape of the image : {}.format(gray.shape))print(Image Hight {}.format(gray.shape[0]))print(Image Width {}.format(gray.shape[1]))print(Dimension of Image {}.format(gray.ndim))print() print(Image size {}.format(gray.size))print(Maximum RGB value in this image {}.format(gray.max()))print(Minimum RGB value in this image {}.format(gray.min()))print(Random indexes [X,Y] : {}.format(gray[100,50]))

Type of the image :<class imageio.core.util.Image> Shape of the image : (562,960)Image Height 562Image Widht 960Dimension of Image 2 Image size 539520Maximum RGB value in this image 254.9999999997Minimum RGB value in this image 0.0Random indexes [X,Y] : 129.07
本文由阿里云云棲社區組織翻譯。
文章原標題《Basic Image Data Analysis Using Numpy and OpenCV – Part 1》,譯者:海棠,審校:Uncle_LLD。文章為簡譯,更為詳細的內容,請查看原文。更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎
推薦閱讀:
※Numpy基礎, Python大牛筆記精講, 看了後我連Matlab都學會了!
※一文帶你了解pandas的DataFrame
※numpy 數組的初步練習
※關於numy中np.expand_dims方法的理解?
