opencv 通過色彩空間實現對象追蹤·基礎(包含一個實踐操作)

                         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實現了指定位置/範圍的與/即圖像修改。
【除掩碼外的另外兩個傳入參數是必須要有的,如果只是對掩碼處理,不妨就傳入一個相同的圖像~】

通過色域選定實現對象追蹤

實現思路

  1. 進行色域轉換——直接處理BGR與處理HSV,我們選擇後者——因爲後者更容易表現顏色,換句話說更好被處理。
  2. 獲取指定色域的範圍——list類型——用numpy創建數組
  3. 使用inRange獲取指定區域的掩碼
  4. 把掩碼摻入到實際的圖像中——這裏採用圖像混合中常用的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()

效果

說明:圖中噪點寫成噪聲了,很抱歉,請諒解。
在這裏插入圖片描述
至於如何除噪聲,我會在後邊單獨整理後發出,但是可以有很多濾波方式來消噪——消除噪點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章