天天看點

手把手教你用Python給小姐姐美個顔

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

01 圖像的顔色空間

彩色圖像比灰階圖像擁有更豐富的資訊,它的每個像素通常是由紅(R)、綠(G)、藍(B)3個分量來表示的,每個分量介于0~255之間。

圖像中呈現的不同的顔色都是由R、G、B這3種顔色混合而成的。在OpenCV裡面,彩色圖像擁有3個顔色通道,但是通道的順序是可以變換的,RGB、BRG、BGR、GBR、GRB都有可能。

在讀取一幅圖像的時候,我們對于圖像的顔色通道排布并不清楚,是以需要先把圖像的顔色通道固定下來,這就需要調用OpenCV的cvtColor()函數。

cvtColor()函數的功能是對圖像進行顔色空間變換,原型如下:

dst=cv2.cvtColor(src, code )           

參數說明:

  • src:輸入圖像即要進行顔色空間變換的原圖像,可以是Mat類。
  • code:轉換的代碼或辨別,即在此确定将什麼制式的圖檔轉換成什麼制式的圖檔,後面會詳細講述。

函數輸出進行顔色空間變換後存儲圖像。

通過調用cvtColor()函數,還可以将一幅彩色圖像轉換成灰階圖像,示例代碼見程式3-5,代碼運作效果如圖3.9所示。

手把手教你用Python給小姐姐美個顔

程式3-5 彩色圖像轉灰階圖像示例:

color2gray.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('1.jpg')
   img2 = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
                                          #從彩色圖像轉化成灰階圖像
   cv2.imshow('img2.bmp ', img2)
   cv2.waitKey(0)
if __name__ == '__main__':
   main()           
手把手教你用Python給小姐姐美個顔

注意:cvtColor()函數還可以通過改變參數cv2.COLOR_RGB2BRG等改變圖像顔色通道的排列順序。另外也可以直接在讀取圖像函數imread時設定參數為0,直接将彩色圖像讀取為灰階圖像,img = cv2.imread('1.jpg',0)。

02 彩色圖像的通道分離和混合

灰階圖像是單通道的,彩色圖像擁有R、G、B三個顔色通道。是以在圖像處理時,經常把顔色通道分離,單獨處理一個通道的數組,然後再合并成一幅彩色圖像。

在實際的代碼編寫中,隻需要調用OpenCV中的split()和merge()函數就可以實作圖像的通道分離和合并。

split()函數的功能是将多通道的矩陣分離成單通道矩陣,原型如下:

[,mv]=cv2.split (src)           

參數說明:輸入參數為要進行分離的圖像矩陣,輸出參數為一個Mat數組。

merge()函數的功能是将多個單通道圖像合成一幅多通道圖像,原型如下:

dst=cv2.merge([,dst] )           

參數說明:輸入參數可以是Mat數組,輸出為合并後的圖像矩陣。

03 彩色圖像的通道分離和混合程式示例

輸入一幅彩色圖像,通過程式3-6将其分割成R、G、B這3個通道的圖像并顯示。在分割前需要先确定圖像的顔色通道分布,是以先調用cvtColor()函數固定顔色通道。示例代碼參見程式3-6,效果如圖3.10所示。

程式3-6 彩色圖像通道分離示例:

colorsplit.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('1.jpg')    
   img2 = cv2.cvtColor(img,cv2.COLOR_BRG2RGB)
   r,g,b = cv2.split(img2)   #img分離成三個單通道的圖像
   cv2.imshow("Red", r)
   cv2.imshow("Green", g)
   cv2.imshow("Blue", b)
   cv2.waitKey(0)
if __name__ == '__main__':
   main()           
手把手教你用Python給小姐姐美個顔

可以看出,在圖像通道分離後,不同顔色通道的圖像顯示深淺不一,單通道的圖像呈現該顔色通道的灰階資訊。接下來把這3個顔色通道混合一下,在代碼中加入一行代碼:img3 = cv2.merge([b,g,r]);,這樣img3又回到了原來輸入的彩色圖像樣式,顯示效果如圖3.11所示。

手把手教你用Python給小姐姐美個顔

04 彩色圖像的二值化

圖像的二值化是将圖像上的像素點的灰階值設定為0或255,也就是将整個圖像呈現出明顯的黑白效果。彩色圖像二值化最簡單的步驟如下:

1.彩色圖像轉灰階。

2.圖像門檻值化處理,即像素值高于某門檻值的像素指派為255,反之為0。

其中,門檻值的操作會調用OpenCV的threshold()函數。

threshold()函數聲明如下:

ret, dst = cv2.threshold(src, thresh, maxval, type);           

函數功能:實作圖像固定門檻值的二值化。

src:輸入圖,隻能輸入單通道圖像,通常來說為灰階圖。

dst:輸出圖。

thresh:門檻值。

maxval:當像素值超過了門檻值(或者小于門檻值,根據type來決定)時所賦予的值。

type:二值化操作的類型,包含5種類型,即cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、cv2.THRESH_TRUNC、cv2.THRESH_TOZERO和cv2.THRESH_TOZERO_INV。

舉例參考程式3-7。

程式3-7 彩色圖像二值化示例:

colorthreshold.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('1.jpg',0)
   thresh1,dst =cv2.threshold(img,127,255,cv2.THRESH_BINARY)
                                               #圖像二值化
   cv2.imshow("dst", dst)
   cv2.waitKey(0)
if __name__ == '__main__':
   main()           

如程式3-7所示,高于127的像素全部置為255,低于的全部置為0,得到如圖3.12所示的輸出結果。

手把手教你用Python給小姐姐美個顔

05 彩色圖像的周遊

灰階圖像的周遊按照通路二維數組的方式得到坐标位置的像素。那對于彩色圖像呢?彩色圖像可以看出是3維數組,周遊方式參見程式3-8。

程式3-8 周遊彩色圖像示例:

color1.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('1.jpg')    
   height,width,n = img.shape #得到圖檔的寬高和次元
   img2 = img.copy()  #複制一個跟img相同的新圖檔
   #寬高兩個次元周遊圖檔
   for i in range(height):
      for j in range(width):
         img2[i, j][0] = 0 #将第一個通道内的元素重新指派
   cv2.imshow('img2.jpg', img2)
   cv2.waitKey(0)
if __name__ == '__main__':
   main()           

由于第一個通道裡面的顔色資訊全部變為了0,圖像顯示結果如圖3.13所示。

手把手教你用Python給小姐姐美個顔

在讀取不同通道的圖像像素值時,需要先确定圖像的通道排列是RGB還是BRG。

06 彩色圖像和灰階圖像的轉換

經過前面的學習,我們知道彩色圖像轉成灰階圖像有3種路徑:

imread讀取圖像的時候直接設定參數為0,彩色圖像自動被讀成灰階圖像。

調用cvtColor()函數,參數設定為cv2.COLOR_BGR2GRAY。

調用split()函數,可以将一幅彩色圖像分離成3個單通道的灰階圖像。

那麼灰階圖像有沒有可能轉換成彩色圖像呢?

我們知道灰階圖像是單通道的,彩色圖像是RGB 3這個顔色通道。那麼是否可以人為地增加圖像的通道,僞造出另外兩個通道,而另外兩個通道可以随機地指派呢?程式3-9做出了嘗試。

程式3-9 增加圖像通道示例:

gray2color1.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('gray1.jpg')    
   gray = np.zeros((512, 512, 3), np.uint8)  # 生成一個空彩色圖像
   height,width,n = img.shape
   #圖像像素級周遊
   for i in range(height):
      for j in range(width):
         gray[i, j][0] = img[i, j][0]
         gray[i, j][1] = 0
         gray[i, j][2] = 0
   cv2.imshow('gray.jpg', gray)
   cv2.waitKey(0)
=if __name__ == '__main__':
   main()           

上述程式建立了一個3通道的空的彩色圖像,然後将讀取的灰階圖像放在建立的彩色圖像的第一個通道,也就是B通道,其他兩個通道指派0,是以圖像整體呈現藍色,程式運作結果如圖3.14所示。

手把手教你用Python給小姐姐美個顔

上述方法轉換的圖像顔色很單一。有沒有更加智能的方法呢?在攝像技術不是很成熟的時期,人們給拍攝出來的黑白照片上色,發明了一種僞彩色圖像技術。在OpenCV裡面,可以用預定義好的Colormap(色度圖)來給圖檔上色,示例代碼參見程式3-10。

程式3-10 僞彩色圖像技術示例:

gray2color2.py

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
#定義main()函數
def main():
   img = cv2.imread('gray1.jpg')    
   im_color = cv2.applyColorMap(img, cv2.COLORMAP_JET)  #色度圖上色
   cv2.imshow("im_color.jpg", im_color)
   cv2.waitKey(0)
if __name__ == '__main__':
   main()           

程式運作結果如圖3.15所示。僞彩色圖像目前主要應用在對高度、壓力、密度、濕度等描述上,彩色資料可視化。

手把手教你用Python給小姐姐美個顔

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/zhibo

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-05-25

本文作者: 方圓圓

本文來自:“

大資料DT 微信公衆号

”,了解相關資訊可以關注“

大資料DT