首頁人工智能技術(shù)資訊正文

meanshift算法通俗講解【meanshift實(shí)例展示】

更新時(shí)間:2021-07-27 來源:黑馬程序員 瀏覽量:

meanshift算法原理

meanshift算法的原理很簡單。假設(shè)你有一堆點(diǎn)集,還有一個(gè)小的窗口,這個(gè)窗口可能是圓形的,現(xiàn)在你可能要移動這個(gè)窗口到點(diǎn)集密度最大的區(qū)域當(dāng)中。

如下圖:

meanshift算法的原理

最開始的窗口是藍(lán)色圓環(huán)的區(qū)域,命名為C1。藍(lán)色圓環(huán)的圓心用一個(gè)藍(lán)色的矩形標(biāo)注,命名為C1_o。

而窗口中所有點(diǎn)的點(diǎn)集構(gòu)成的質(zhì)心在藍(lán)色圓形點(diǎn)C1_r處,顯然圓環(huán)的形心和質(zhì)心并不重合。所以,移動藍(lán)色的窗口,使得形心與之前得到的質(zhì)心重合。在新移動后的圓環(huán)的區(qū)域當(dāng)中再次尋找圓環(huán)當(dāng)中所包圍點(diǎn)集的質(zhì)心,然后再次移動,通常情況下,形心和質(zhì)心是不重合的。不斷執(zhí)行上面的移動過程,直到形心和質(zhì)心大致重合結(jié)束。 這樣,最后圓形的窗口會落到像素分布最大的地方,也就是圖中的綠色圈,命名為C2。

meanshift算法除了應(yīng)用在視頻追蹤當(dāng)中,在聚類,平滑等等各種涉及到數(shù)據(jù)以及非監(jiān)督學(xué)習(xí)的場合當(dāng)中均有重要應(yīng)用,是一個(gè)應(yīng)用廣泛的算法。

圖像是一個(gè)矩陣信息,如何在一個(gè)視頻當(dāng)中使用meanshift算法來追蹤一個(gè)運(yùn)動的物體呢? 大致流程如下:

1.首先在圖像上選定一個(gè)目標(biāo)區(qū)域

2.計(jì)算選定區(qū)域的直方圖分布,一般是HSV色彩空間的直方圖。

3.對下一幀圖像b同樣計(jì)算直方圖分布。

4.計(jì)算圖像b當(dāng)中與選定區(qū)域直方圖分布最為相似的區(qū)域,使用meanshift算法將選定區(qū)域沿著最為相似的部分進(jìn)行移動,直到找到最相似的區(qū)域,便完成了在圖像b中的目標(biāo)追蹤。

5.重復(fù)3到4的過程,就完成整個(gè)視頻目標(biāo)追蹤。

通常情況下我們使用直方圖反向投影得到的圖像和第一幀目標(biāo)對象的起始位置,當(dāng)目標(biāo)對象的移動會反映到直方圖反向投影圖中,meanshift 算法就把我們的窗口移動到反向投影圖像中灰度密度最大的區(qū)域了。如下圖所示:

直方圖反向投影的流程是:

假設(shè)我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的:

1.從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時(shí)圖像;

2.生成臨時(shí)圖像的直方圖;

3.用臨時(shí)圖像的直方圖和模板圖像的直方圖對比,對比結(jié)果記為c;

4.直方圖對比結(jié)果c,就是結(jié)果圖像(0,0)處的像素值;

5.切割輸入圖像從(0,1)至(10,11)的臨時(shí)圖像,對比直方圖,并記錄到結(jié)果圖像;

6.重復(fù)1~5步直到輸入圖像的右下角,就形成了直方圖的反向投影。

meanshift視頻追蹤實(shí)現(xiàn)

在OpenCV中實(shí)現(xiàn)Meanshift的API是:

cv.meanShift(probImage, window, criteria)

參數(shù):

·probImage: ROI區(qū)域,即目標(biāo)的直方圖的反向投影

·window: 初始搜索窗口,就是定義ROI的rect

·criteria: 確定窗口搜索停止的準(zhǔn)則,主要有迭代次數(shù)達(dá)到設(shè)置的最大值,窗口中心的漂移值大于某個(gè)設(shè)定的限值等。

實(shí)現(xiàn)Meanshift的主要流程是:

1.讀取視頻文件:cv.videoCapture()

2.感興趣區(qū)域設(shè)置:獲取第一幀圖像,并設(shè)置目標(biāo)區(qū)域,即感興趣區(qū)域

3.計(jì)算直方圖:計(jì)算感興趣區(qū)域的HSV直方圖,并進(jìn)行歸一化

4.目標(biāo)追蹤:設(shè)置窗口搜索停止條件,直方圖反向投影,進(jìn)行目標(biāo)追蹤,并在目標(biāo)位置繪制矩形框。

示例:

import numpy as np
import cv2 as cv
# 1.獲取圖像
cap = cv.VideoCapture('DOG.wmv')

# 2.獲取第一幀圖像,并指定目標(biāo)位置
ret,frame = cap.read()
# 2.1 目標(biāo)位置(行,高,列,寬)
r,h,c,w = 197,141,0,208  
track_window = (c,r,w,h)
# 2.2 指定目標(biāo)的感興趣區(qū)域
roi = frame[r:r+h, c:c+w]

# 3. 計(jì)算直方圖
# 3.1 轉(zhuǎn)換色彩空間(HSV)
hsv_roi =  cv.cvtColor(roi, cv.COLOR_BGR2HSV)
# 3.2 去除低亮度的值
# mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
# 3.3 計(jì)算直方圖
roi_hist = cv.calcHist([hsv_roi],[0],None,[180],[0,180])
# 3.4 歸一化
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)

# 4. 目標(biāo)追蹤
# 4.1 設(shè)置窗口搜索終止條件:最大迭代次數(shù),窗口中心漂移最小值
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )

while(True):
    # 4.2 獲取每一幀圖像
    ret ,frame = cap.read()
    if ret == True:
        # 4.3 計(jì)算直方圖的反向投影
        hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
        dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)

        # 4.4 進(jìn)行meanshift追蹤
        ret, track_window = cv.meanShift(dst, track_window, term_crit)

        # 4.5 將追蹤的位置繪制在視頻上,并進(jìn)行顯示
        x,y,w,h = track_window
        img2 = cv.rectangle(frame, (x,y), (x+w,y+h), 255,2)
        cv.imshow('frame',img2)

        if cv.waitKey(60) & 0xFF == ord('q'):
            break        
    else:
        break
# 5. 資源釋放        
cap.release()
cv.destroyAllWindows()

下面是三幀圖像的跟蹤結(jié)果:

meanshift視頻追蹤效果

Camshift算法

大家認(rèn)真看下上面的結(jié)果,有一個(gè)問題,就是檢測的窗口的大小是固定的,而狗狗由近及遠(yuǎn)是一個(gè)逐漸變小的過程,固定的窗口是不合適的。所以我們需要根據(jù)目標(biāo)的大小和角度來對窗口的大小和角度進(jìn)行修正。CamShift可以幫我們解決這個(gè)問題。

CamShift算法全稱是“Continuously Adaptive Mean-Shift”(連續(xù)自適應(yīng)MeanShift算法),是對MeanShift算法的改進(jìn)算法,可隨著跟蹤目標(biāo)的大小變化實(shí)時(shí)調(diào)整搜索窗口的大小,具有較好的跟蹤效果。

Camshift算法首先應(yīng)用meanshift,一旦meanshift收斂,它就會更新窗口的大小,還計(jì)算最佳擬合橢圓的方向,從而根據(jù)目標(biāo)的位置和大小更新搜索窗口。如下圖所示:

Camshift算法

Camshift在OpenCV中實(shí)現(xiàn)時(shí),只需將上述的meanshift函數(shù)改為Camshift函數(shù)即可:

將Camshift中的:

 # 4.4 進(jìn)行meanshift追蹤
        ret, track_window = cv.meanShift(dst, track_window, term_crit)
        # 4.5 將追蹤的位置繪制在視頻上,并進(jìn)行顯示
        x,y,w,h = track_window
        img2 = cv.rectangle(frame, (x,y), (x+w,y+h), 255,2)

改為:

#進(jìn)行camshift追蹤
    ret, track_window = cv.CamShift(dst, track_window, term_crit)

        # 繪制追蹤結(jié)果
        pts = cv.boxPoints(ret)
        pts = np.int0(pts)
        img2 = cv.polylines(frame,[pts],True, 255,2)

算法總結(jié)

meanshift

原理:一個(gè)迭代的步驟,即先算出當(dāng)前點(diǎn)的偏移均值,移動該點(diǎn)到其偏移均值,然后以此為新的起始點(diǎn),繼續(xù)移動,直到滿足一定的條件結(jié)束。

API:cv.meanshift()

優(yōu)缺點(diǎn):簡單,迭代次數(shù)少,但無法解決目標(biāo)的遮擋問題并且不能適應(yīng)運(yùn)動目標(biāo)的的形狀和大小變化

camshift

原理:對meanshift算法的改進(jìn),首先應(yīng)用meanshift,一旦meanshift收斂,它就會更新窗口的大小,還計(jì)算最佳擬合橢圓的方向,從而根據(jù)目標(biāo)的位置和大小更新搜索窗口。

API:cv.camshift()

優(yōu)缺點(diǎn):可適應(yīng)運(yùn)動目標(biāo)的大小形狀的改變,具有較好的跟蹤效果,但當(dāng)背景色和目標(biāo)顏色接近時(shí),容易使目標(biāo)的區(qū)域變大,最終有可能導(dǎo)致目標(biāo)跟蹤丟失

《圖像處理OpenCV入門教程》課程導(dǎo)讀


加QQ:2217622915,獲取《圖像處理OpenCV入門教程》全套視頻教程+筆記+源碼



猜你喜歡:

SIFT算法原理:SIFT算法詳細(xì)介紹

什么是圖像特征?如何讓計(jì)算機(jī)理解圖像特征?

Harris角點(diǎn)檢測原理

OpenCV圖像疊加和圖像混合

黑馬程序員人工智能開發(fā)課程

分享到:
在線咨詢 我要報(bào)名
和我們在線交談!