1. 程式人生 > >Python 影象處理 OpenCV (3):影象屬性、影象感興趣 ROI 區域及通道處理

Python 影象處理 OpenCV (3):影象屬性、影象感興趣 ROI 區域及通道處理

![](https://cdn.geekdigging.com/opencv/opencv_header.png) 前文傳送門: [「Python 影象處理 OpenCV (1):入門」](https://www.geekdigging.com/2020/05/17/5513454552/) [「Python 影象處理 OpenCV (2):畫素處理與 Numpy 操作以及 Matplotlib 顯示影象」](https://www.geekdigging.com/2020/05/18/4936041986/) ## 影象屬性 影象屬性包括行數,列數和通道數,影象資料型別,畫素數等。 ### 1. 形狀:shape 影象的形狀可以通過 `shape` 關鍵字進行獲取,使用 `shape` 關鍵的後,獲取的資訊包括行數、列數、通道數的元祖。 > 需要注意的是,如果是灰度圖片,只會返回影象的行數和列數,而彩色圖片才會影象的行數、列數和通道數。 示例如下: ```python import cv2 as cv # 讀取彩色圖片 color_img = cv.imread("maliao.jpg", cv.IMREAD_ANYCOLOR) print(color_img.shape) # 結果列印 (310, 560, 3) # 讀取灰度圖片 gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE) print(gray_img.shape) # 結果列印 (310, 560) ``` ### 2. 畫素數量:size 影象的畫素數量可以通過關鍵字 `size` 進行獲取。 > 同樣需要注意的是,灰度圖片的畫素數量是要小於彩色圖片的,具體的關係是 1/3 。 ```python import cv2 as cv # 讀取彩色圖片 color_img = cv.imread("maliao.jpg", cv.IMREAD_ANYCOLOR) print(color_img.size) # 結果列印 520800 # 讀取灰度圖片 gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE) print(gray_img.size) # 結果列印 173600 ``` ### 3. 影象型別-dtype 影象型別是通過關鍵字 `dtype` 獲取的,通常返回 uint8 ,這個屬性在彩色圖片和灰度圖片中是保持一致的。 > 注意 dtype 在除錯時非常重要,因為 OpenCV-Python 程式碼中的大量錯誤是由無效的資料型別引起的。 ```python import cv2 as cv # 讀取彩色圖片 color_img = cv.imread("maliao.jpg", cv.IMREAD_ANYCOLOR) print(color_img.dtype) # 結果列印 uint8 # 讀取灰度圖片 gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE) print(gray_img.dtype) # 結果列印 uint8 ``` ## 獲取影象感興趣 ROI 區域 ROI(Region of Interest)表示感興趣區域。 它是指從被處理影象以方框、圓形、橢圓、不規則多邊形等方式勾勒出需要處理的區域。可以通過各種運算元(Operator)和函式求得感興趣ROI區域,並進行影象的下一步處理,被廣泛應用於熱點地圖、人臉識別、影象分割等領域。 如果我們要對於影象中的眼睛檢測,首先對整個影象進行人臉檢測。在獲取人臉影象時,我們只選擇人臉區域,搜尋其中的眼睛,而不是搜尋整個影象。它提高了準確性(因為眼睛總是在面部上:D )和效能(因為我們搜尋的區域很小)。 我們通過畫素矩陣可以直接得到 ROI 區域,如: `img[200:400, 200:400]` 。 比如下面這個示例我們獲取馬里奧的臉,然後再把它顯示出來: ```python import cv2 as cv img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED) face = img[10:175, 100:260] # 原始影象顯示 cv.imshow("demo", img) # 馬里奧的臉顯示 cv.imshow("face", face) #等待顯示 cv.waitKey(0) cv.destroyAllWindows() ``` 它的結果如下: ![](https://cdn.geekdigging.com/opencv/03/pic_1.png) 如果我們要把這兩張影象合成一張影象,可以對影象進行區域賦值: ```python import cv2 as cv img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED) # 獲取 ROI 區域 face = img[10:175, 100:260] # 影象賦值 img[0:165, 0:160] = face # 原始影象顯示 cv.imshow("demo", img) #等待顯示 cv.waitKey(0) cv.destroyAllWindows() ``` 結果如下: ![](https://cdn.geekdigging.com/opencv/03/pic_2.png) 這裡我稍微偷點懶,直接就把 ROI 區域放在了圖片的左上角,這個位置可以隨意指定,但是指定的區域要和 ROI 的區域一樣大,否則會報一個 `ValueError` 的錯誤。 ## 拆分和合並影象通道 ### 1. 拆分影象通道 有些時候,我們需要分別處理影象的 B,G,R 通道。的通道,用 PS 摳過圖的人應該都清楚摳圖的時候可以使用單通道進行摳圖操作。 將影象的通道拆分出來可以使用 `split()` 函式,如下: ```python import cv2 as cv img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED) #拆分通道 b, g, r = cv.split(img) # 分別顯示三個通道的影象 cv.imshow("B", b) cv.imshow("G", g) cv.imshow("R", r) # 等待顯示 cv.waitKey(0) cv.destroyAllWindows() ``` 結果如下: ![](https://cdn.geekdigging.com/opencv/03/pic_3.png) 可以看到,三個通道的影象看起來都是灰白色的,這個玩過 PS 的人應該都很熟悉。 除了使用 `split()` 函式獲取影象通道,還可以通過索引進行獲取,程式碼如下: ```python b = img[:, :, 0] g = img[:, :, 1] r = img[:, :, 2] ``` 如果需要將所有紅色畫素都設定為零,無需先拆分通道,索引更快: ```python img[:, :, 2] = 0 ``` > 注意: `split()` 函式是一項耗時的操作(就時間而言)。因此,僅在必要時才這樣做。否則請進行Numpy索引。 ### 2. 合併影象通道 合併影象通道我們使用函式 `merge()` ,示例如下: ```python import cv2 as cv img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED) # 拆分通道 b, g, r = cv.split(img) # 合併影象通道 m = cv.merge([r, g, b]) cv.imshow('merge', m) # 等待顯示 cv.waitKey(0) cv.destroyAllWindows() ``` 結果如下: ![](https://cdn.geekdigging.com/opencv/03/pic_4.png) 這裡如果是按照 `[r, g, b]` 進行影象通道合併,我們的馬里奧就會變身成為藍精靈,因為 OpenCV 是按照 BGR 讀取的,如果想要顯示會原圖,合併的時候也按照 `[b, g, r]` 合併即可,如下: ![](https://cdn.geekdigging.com/opencv/03/pic_5.png) 如果我們想要做一個真正的藍精靈,可以只提取 B 顏色通道,其餘兩個 G 、 R 通道全部設定為 0 ,這樣,我們就獲得了一個真正的藍精靈(整個影象只有藍色通道),程式碼如下: ```python import cv2 as cv import numpy as np # 讀取圖片 img = cv.imread("maliao.jpg", cv.IMREAD_UNCHANGED) rows, cols, chn = img.shape # 拆分通道 b = img[:, :, 0] g = np.zeros((rows,cols), dtype=img.dtype) r = np.zeros((rows,cols), dtype=img.dtype) # 合併影象通道 m = cv.merge([b, g, r]) cv.imshow('merge', m) # 等待顯示 cv.waitKey(0) cv.destroyAllWindows() ``` 結果如下: ![](https://cdn.geekdigging.com/opencv/03/pic_6.png) 同理,如果想要綠精靈和紅精靈,一樣可以做出來。 ## 示例程式碼 如果有需要獲取原始碼的同學可以在公眾號回覆「OpenCV」進行獲取。 ## 參考 https://blog.csdn.net/eastmount/article/details/82177300 http://woshic