摘要:本篇文章主要講解Python呼叫OpenCV獲取影像屬性,擷取感興趣ROI區域,處理影像通道。
本文分享自華為雲社群《[Python影像處理] 三.獲取影像屬性、興趣ROI區域及通道處理 | 【生長吧!Python】》,作者: eastmount 。
一.獲取影像屬性
1.形狀-shape
通過shape關鍵字獲取影像的形狀,返回包含行數、列數、通道數的元祖。其中灰度影像返回行數和列數,彩色影像返回行數、列數和通道數。如下圖所示:

# -*- coding:utf-8 -*- import cv2 import numpy #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #獲取影像形狀 print(img.shape) #顯示影像 cv2.imshow("Demo", img) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
輸出結果如下圖所示:(445L, 670L, 3L),該圖共445行、670列畫素,3個通道。

2.畫素數目-size
通過size關鍵字獲取影像的畫素數目,其中灰度影像返回行數 * 列數,彩色影像返回行數 * 列數 * 通道數。程式碼如下:
# -*- coding:utf-8 -*- import cv2 import numpy #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #獲取影像形狀 print(img.shape) #獲取畫素數目 print(img.size)
輸出結果:
(445L, 670L, 3L)
894450
3.影像型別-dtype
通過dtype關鍵字獲取影像的資料型別,通常返回uint8。程式碼如下:
# -*- coding:utf-8 -*- import cv2 import numpy #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #獲取影像形狀 print(img.shape) #獲取畫素數目 print(img.size) #獲取影像型別 print(img.dtype)
輸出結果:
(445L, 670L, 3L)
894450
uint8
二.獲取感興趣ROI區域
ROI(Region of Interest)表示感興趣區域。它是指從被處理影像以方框、圓形、橢圓、不規則多邊形等方式勾勒出需要處理的區域。可以通過各種運算元(Operator)和函式求得感興趣ROI區域,並進行影像的下一步處理,被廣泛應用於熱點地圖、人臉識別、影像分割等領域。

通過畫素矩陣可以直接獲取ROI區域,如img[200:400, 200:400]。

程式碼如下:
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #定義200*100矩陣 3對應BGR face = np.ones((200, 100, 3)) #顯示原始影像 cv2.imshow("Demo", img) #顯示ROI區域 face = img[200:400, 200:300] cv2.imshow("face", face) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
輸出結果如下圖所示:

下面將提取的ROI影像進行融合實驗,程式碼如下:
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #定義300*100矩陣 3對應BGR face = np.ones((200, 200, 3)) #顯示原始影像 cv2.imshow("Demo", img) #顯示ROI區域 face = img[100:300, 150:350] img[0:200,0:200] = face cv2.imshow("face", img) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
將提取的頭部融合至影像左上角部分,如下圖所示:

如果想將兩張影像進行融合,只需再讀取一張影像即可,方法原理類似。 實現程式碼如下:
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) test = cv2.imread("test3.jpg", cv2.IMREAD_UNCHANGED) #定義300*100矩陣 3對應BGR face = np.ones((200, 200, 3)) #顯示原始影像 cv2.imshow("Demo", img) #顯示ROI區域 face = img[100:300, 150:350] test[400:600,400:600] = face cv2.imshow("Pic", test) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
輸出結果如下圖所示:

三.影像通道處理
1.通道拆分
OpenCV讀取的彩色影像由B、G、R三原色組成,可以通過下面程式碼獲取不同的通道。
b = img[:, :, 0]
g = img[:, :, 1]
r = img[:, :, 2]

也可以使用split()函式拆分通道,下面是拆分不同通道再顯示的程式碼。
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #拆分通道 b, g, r = cv2.split(img) #顯示原始影像 cv2.imshow("B", b) cv2.imshow("G", g) cv2.imshow("R", r) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
輸出結果如下圖所示:

也可以獲取不同的通道,核心程式碼如下所示: b = cv2.split(a)[0] g = cv2.split(a)[1] r = cv2.split(a)[2]
2.通道合併
影像通道合併主要呼叫merge()函式實現,核心程式碼如下:
m = cv2.merge([b, g, r])
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) #拆分通道 b, g, r = cv2.split(img) #合併通道 m = cv2.merge([b, g, r]) cv2.imshow("Merge", m) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
輸出結果如下:

注意,如果是合併[r,g,b]三通道,則顯示如下所示,因OpenCV是按照BGR進行讀取的。
b, g, r = cv2.split(img)
m = cv2.merge([r, g, b])
cv2.imshow(“Merge”, m)

同時,可以提取影像的不同顏色,提取B顏色通道,G、B通道設定為0,則顯示藍色。程式碼如下所示:
# -*- coding:utf-8 -*- import cv2 import numpy as np #讀取圖片 img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED) rows, cols, chn = img.shape #拆分通道 b = cv2.split(img)[0] g = np.zeros((rows,cols),dtype=img.dtype) r = np.zeros((rows,cols),dtype=img.dtype) #合併通道 m = cv2.merge([b, g, r]) cv2.imshow("Merge", m) #等待顯示 cv2.waitKey(0) cv2.destroyAllWindows()
藍色通道輸出結果如下所示:

綠色通道核心程式碼及輸出結果如下所示:
rows, cols, chn = img.shape
b = np.zeros((rows,cols),dtype=img.dtype)
g = cv2.split(img)[1]
r = np.zeros((rows,cols),dtype=img.dtype)
m = cv2.merge([b, g, r])

紅色通道修改方法與上面類似。希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵。
該系列在github所有原始碼: