openCV:背景建模

幀間差分法背景建模

定義

由于場(chǎng)景中的目標(biāo)在運(yùn)動(dòng),目標(biāo)的影像在不同圖像幀中的位置不同。該類算法對(duì)時(shí)間上連續(xù)的兩幀圖像進(jìn)行差分運(yùn)算,不同幀對(duì)應(yīng)的像素點(diǎn)相減,判斷灰度差的絕對(duì)值,當(dāng)絕對(duì)值超過(guò)一定閾值時(shí),即可判斷為運(yùn)動(dòng)目標(biāo),從而實(shí)現(xiàn)目標(biāo)的檢測(cè)功能。

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):算法簡(jiǎn)單,不易受環(huán)境光線影響
  • 缺點(diǎn):
    • 不能用于運(yùn)動(dòng)的攝像頭中;
    • 無(wú)法識(shí)別靜止或運(yùn)動(dòng)速度很慢的目標(biāo);
    • 運(yùn)動(dòng)目標(biāo)表面有大面積灰度值相似區(qū)域的情況下,在做差分時(shí)圖像會(huì)出現(xiàn)空洞;

混合高斯模型背景建模

基本原理

  • 在進(jìn)行前景檢測(cè)前,先對(duì)背景進(jìn)行訓(xùn)練,對(duì)圖像中每個(gè)背景采用一個(gè)混合高斯模型進(jìn)行模擬,每個(gè)背景的混合高斯的個(gè)數(shù)可以自適應(yīng)。
  • 然后在測(cè)試階段,對(duì)新來(lái)的像素進(jìn)行GMM匹配,如果該像素值能夠匹配其中一個(gè)高斯,則認(rèn)為是背景,否則認(rèn)為是前景。
  • 由于整個(gè)過(guò)程GMM模型在不斷更新學(xué)習(xí)中,所以對(duì)動(dòng)態(tài)背景有一定的魯棒性。
  • 最后通過(guò)對(duì)一個(gè)有樹枝搖擺的動(dòng)態(tài)背景進(jìn)行前景檢測(cè),取得了較好的效果。

在視頻中對(duì)于像素點(diǎn)的變化情況通常是符合高斯分布

背景的實(shí)際分布應(yīng)當(dāng)是多個(gè)高斯分布混合在一起,每個(gè)高斯模型也可以帶有權(quán)重

混合高斯模型學(xué)習(xí)方法

  • 1.首先初始化每個(gè)高斯模型矩陣參數(shù)。

  • 2.取視頻中T幀數(shù)據(jù)圖像用來(lái)訓(xùn)練高斯混合模型。來(lái)了第一個(gè)像素之后用它來(lái)當(dāng)做第一個(gè)高斯分布。

  • 3.當(dāng)后面來(lái)的像素值時(shí),與前面已有的高斯的均值比較,如果該像素點(diǎn)的值與其模型均值差在3倍的方差內(nèi),則屬于該分布,并對(duì)其進(jìn)行參數(shù)更新。

  • 4.如果下一次來(lái)的像素不滿足當(dāng)前高斯分布,用它來(lái)創(chuàng)建一個(gè)新的高斯分布。

混合高斯模型測(cè)試方法

在測(cè)試階段,對(duì)新來(lái)像素點(diǎn)的值與混合高斯模型中的每一個(gè)均值進(jìn)行比較,如果其差值在2倍的方差之間的話,則認(rèn)為是背景,否則認(rèn)為是前景。將前景賦值為255,背景賦值為0。這樣就形成了一副前景二值圖。

import numpy as np
import cv2

#經(jīng)典的測(cè)試視頻
cap = cv2.VideoCapture('test.avi')
#形態(tài)學(xué)操作需要使用
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
#創(chuàng)建混合高斯模型用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()

while(True):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    #形態(tài)學(xué)開運(yùn)算去噪點(diǎn)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    #尋找視頻中的輪廓
    im, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:
        #計(jì)算各輪廓的周長(zhǎng)
        perimeter = cv2.arcLength(c,True)
        if perimeter > 188:
            #找到一個(gè)直矩形(不會(huì)旋轉(zhuǎn))
            x,y,w,h = cv2.boundingRect(c)
            #畫出這個(gè)矩形
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)    

    cv2.imshow('frame',frame)
    cv2.imshow('fgmask', fgmask)
    k = cv2.waitKey(150) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

混合高斯背景建模.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容