計算機視覺 | Python OpenCV 3 使用背景減除進行目標檢測
歡迎訪問我們的官方網站:www.leadai.org
背景減除(Background Subtraction)是許多基於計算機視覺的任務中的主要預處理步驟。如果我們有完整的靜止的背景幀,那麼我們可以通過幀差法來計算像素差從而獲取到前景對象。但是在大多數情況下,我們可能沒有這樣的圖像,所以我們需要從我們擁有的任何圖像中提取背景。當運動物體有陰影時,由於陰影也在移動,情況會變的變得更加複雜。為此引入了背景減除演算法,通過這一方法我們能夠從視頻中分離出運動的物體前景,從而達到目標檢測的目的。 OpenCV已經實現了幾種非常容易使用的演算法。
環境
- Python 3.6
- OpenCV 3.2 + contrib
在Python下可以通過直接導入wheel包來安裝opencv+contrib,可以從下面這個網址下載對應的文件:
opencv_python?3.2.0+contrib?cp36?cp36m?win_amd64.whl http://www.lfd.uci.edu/~gohlke/pythonlibs/
KNN
KNN演算法,即K-nearest neigbours - based Background/Foreground Segmentation Algorithm。2006年,由Zoran Zivkovic 和Ferdinand van der Heijden在論文"Efficient adaptive density estimation per image pixel for the task of background subtraction."中提出。
bs = cv2.createBackgroundSubtractorKNN(detectShadows=True) nfg_mask = bs.apply(frame)n
MOG
MOG演算法,即高斯混合模型分離演算法,全稱Gaussian Mixture-based Background/Foreground Segmentation Algorithm。2001年,由P.KadewTraKuPong和R.Bowden在論文「An improved adaptive background mixture model for real-time tracking with shadow detection」中提出。它使用一種通過K高斯分布的混合來對每個背景像素進行建模的方法(K = 3?5)。
bs = cv2.bgsegm.createBackgroundSubtractorMOG(history=history) n bs.setHistory(history)n fg_mask = bs.apply(frame)n
MOG2
MOG2演算法,也是高斯混合模型分離演算法,是MOG的改進演算法。它基於Z.Zivkovic發布的兩篇論文,即2004年發布的「Improved adaptive Gausian mixture model for background subtraction」和2006年發布的「Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction」中提出。該演算法的一個重要特徵是 它為每個像素選擇適當數量的高斯分布,它可以更好地適應不同場景的照明變化等。
bs = cv2.createBackgroundSubtractorMOG2(history=history, detectShadows=True)nbs.setHistory(history)nfg_mask = bs.apply(frame)n
GMG
該演算法結合統計背景圖像估計和每像素貝葉斯分割。由 Andrew B. Godbehere, Akihiro Matsukawa, Ken Goldberg在2012年的文章「Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive Audio Art Installation」中提出。該演算法使用前幾個(默認為120)幀進行後台建模。它採用概率前景分割演算法,使用貝葉斯推理識別可能的前景對象。
bs = cv2.bgsegm.createBackgroundSubtractorGMG(initializationFrames=history) n fg_mask = bs.apply(frame)n
使用KNN根據前景面積檢測運動物體
代碼:
# coding:utf8nimport cv2ndef detect_video(video): ncamera = cv2.VideoCapture(video) nhistory = 20 # 訓練幀數 nbs = cv2.createBackgroundSubtractorKNN(detectShadows=True) # 背景減除器,設置陰影檢測 bs.setHistory(history) nframes = 0 nwhile True: nres, frame = camera.read() nif not res: nbreak nfg_mask = bs.apply(frame) # 獲取 foreground mask nif frames < history: nframes += 1 ncontinue n# 對原始幀進行膨脹去噪 nth = cv2.threshold(fg_mask.copy(), 244, 255, cv2.THRESH_BINARY)[1] nth = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=2) dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 3)), iterations=2) # 獲取所有檢測框 image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) nfor c in contours: n# 獲取矩形框邊界坐標 nx, y, w, h = cv2.boundingRect(c) n# 計算矩形框的面積 narea = cv2.contourArea(c) nif 500 < area < 3000: ncv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) ncv2.imshow("detection", frame) ncv2.imshow("back", dilated) n if cv2.waitKey(110) & 0xff == 27: nbreak ncamera.release()n if __name__ == __main__:nvideo = person.avi ndetect_video(video)n
效果:
查閱更為簡潔方便的分類文章以及最新的課程、產品信息,請移步至全新呈現的「LeadAI學院官網」:
http://www.leadai.org
請關注人工智慧LeadAI公眾號,查看更多專業文章
http://weixin.qq.com/r/ZDnC2j-E5GKbrXu592x2 (二維碼自動識別)
推薦閱讀:
※python爬蟲之豆瓣音樂top250
※Requests 庫學習筆記
※巧用抓包 ― 爬遍SCU玻璃杯事件所有神回復
※黑客你好,請使用Python編寫一個滲透測試探測器
※再也不用擔心網頁編碼的坑了!