文章目錄
QQ:3020889729 小蔡
opencv色域轉換
將會使用cv.cvtColor()函數實現圖像色域的轉換,它的參數如下
- 第一個參數爲輸入圖像
- 第二個參數爲轉換色域的選擇——一般在色域追蹤中,可能將opencv默認的BGR轉換位HSV會查找更簡單一些。(雖然opencv默認色域是RGB;但是,實質上它是採用的BGR存儲的,所以我們在處理數據時,按照BGR來處理就好)
- 第三個參數爲色域通道數設置——默認爲0,意味着原圖形默認的通道數
至於輸出圖像,採用返回值的方式來實現就好。
img = cv.imread('1.png', 1)
hsv = cv.cvtColor(img , cv.COLOR_BGR2HSV) # COLOR_BGR2HSV是指將圖像色域轉換爲HSV
色域轉換的本質
其本質我認爲主要是對數據的等權重數據轉換吧——就比如,我們常常舉例說明一樣,都是爲了問題的簡便。
捕獲指定區域(採用獲取指定範圍的掩碼實現捕獲)
cv.inRange()函數獲取指定數據的範圍——也就是掩飾掉我們需要的數據之外的數據
主要參數:
- 第一個參數:輸入數組(需要提取指定範圍的圖像數組)
- 第二個參數:查找滿足條件的下限值
- 第三個參數:查找滿足條件的上限值——由二、三參數可以得到我們搜索的數據範圍
至於輸出掩碼——我們採用就收返回值的方式獲取。
對於色域判斷,我們通常是把某個色域的上下限取出來,然後放入inRange中作爲判斷條件。然後得到的掩碼——就是隻包含這個區域的圖像信息的數組。
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255]) # 設置色域範圍
mask = cv.inRange(hsv, lower_blue, upper_blue) # 返回一個滿足指定色域外的其它區域值置0的掩碼(圖像)
官方函數功能的說明:(我就不多說了,就提兩句)
該函數在一維時,就直接將在lowerb和upperb的數據保留,其它捨去——置零
——可類推多維度,見下面文檔
補充: 如果是圖像色域範圍的篩選,那麼滿足爲就爲閾值(全1位),否則就爲0
The function checks the range as follows:
For every element of a single-channel input array: % 0 表示下標,對應維度
dst(I) = lowerb(I)0≤src(I)0≤upperb(I)0
For two-channel arrays:
dst(I) = lowerb(I)0≤src(I)0≤upperb(I)0∧lowerb(I)1≤src(I)1≤upperb(I)1
and so forth.
That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the specified 1D, 2D, 3D, ... box and 0 otherwise.
通過以上步驟,已經可以操作色域的轉換,實現問題的一些簡化,又可以通過,對滿足指定色域的圖像範圍的讀取/獲取。那麼接着我們就應該讓滿足條件的圖像區域呈現我們實際的圖像了——這裏就要用到圖像的與,實現圖像的混合了。
圖像與cv.bitwise_and(),實現掩碼與原圖像融合
主要參數:
- 第一參數:輸入圖像1(輸入數組1/標量)
- 第二參數:輸入圖像2(另一個數組/標量)
- 第三參數:輸出數組——通常按返回值獲取輸出數組
- 第四參數:與操作的掩碼輸入——8位單通道數組,用於指定要更改的輸出數組的元素[對應維度]。
實例:(簡單理解可以是:輸入圖像1與輸入圖像2的按位與,而當mask不等於0時,就是將mask添加到圖像混合中,作爲與的元素)
res = cv.bitwise_and(frame, frame, mask=mask) # 用圖像與操作,實現掩碼原圖像混合
上面採用原圖混合(本來是無任何變化的),由於摻入mask實現了指定位置/範圍的與/即圖像修改。
【除掩碼外的另外兩個傳入參數是必須要有的,如果只是對掩碼處理,不妨就傳入一個相同的圖像~】
通過色域選定實現對象追蹤
實現思路
- 進行色域轉換——直接處理BGR與處理HSV,我們選擇後者——因爲後者更容易表現顏色,換句話說更好被處理。
- 獲取指定色域的範圍——list類型——用numpy創建數組
- 使用inRange獲取指定區域的掩碼
- 把掩碼摻入到實際的圖像中——這裏採用圖像混合中常用的bitwise_and
代碼實例(實現藍色追蹤)
import cv2 as cv
import numpy as np
if __name__ == "__main__":
cap = cv.VideoCapture(0) # 默認攝像設備
while True:
_, frame = cap.read() # 讀取設備幀圖像——frame爲圖像
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) # 轉換色域——因爲HSV更容易在圖像中查找色彩區域
# 也可通過cvtColor獲取不同色域下的顏色值——比如,傳入一個BGR(對應cv.COLOR_BGR2HSV)的色值,然後得到HSV下的該色色值
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255]) # 設置需要的色域範圍
mask = cv.inRange(hsv, lower_blue, upper_blue) # 返回一個滿足指定色域外的其它區域值置0的掩碼
res = cv.bitwise_and(frame, frame, mask=mask) # 用圖像與操作,實現掩碼與原圖像的混合
cv.imshow('imag', frame) # 顯示原圖像
cv.imshow('mask', mask) # 顯示掩碼圖像
cv.imshow('res', res) # 顯示混合圖像——也就是追蹤圖像
if cv.waitKey(5) & 0xFF == 27:
break
cv.destroyAllWindows()
效果
說明:圖中噪點寫成噪聲了,很抱歉,請諒解。
至於如何除噪聲,我會在後邊單獨整理後發出,但是可以有很多濾波方式來消噪——消除噪點。