使用網絡攝像頭和Python中的OpenCV構建運動檢測器(Translate)


點擊上方小白學視覺」,選擇加"星標"或「置頂算法

重磅乾貨,第一時間送達編程

本期咱們將學習如何使用OpenCV實現運動檢測服務器


運動檢測是指檢測物體相對於周圍環境的位置是否發生了變化。接下來,讓咱們一塊兒使用Python實現一個運動檢測器應用程序吧!微信


該運動檢測器能夠完成如下任務:網絡

1)在家工做時在屏幕前查找時間app

2) 監控孩子在屏幕前的時間ide

3) 在你的後院發現非法侵入函數

4) 在你的房間/房子/小巷周圍找到不須要的公共/動物活動……。學習


想要實現該運動檢測器程序咱們須要具有如下條件:優化

1)硬件要求:裝有網絡攝像機或任何類型攝像機的計算機。

2)軟件需求:Pyhton3或者更高版本。

3)附加要求:對運動檢測有必定的興趣。


接下來咱們將一步步的完成該應用程序的構建。


首先,咱們將經過網絡攝像頭捕獲第一幀,並將它視爲基準幀,以下圖所示。經過計算該基準幀中的對象與新幀對象之間的相位差來檢測運動。咱們也將獲得的結果稱爲Delta幀。


接下來,咱們將使用像素強度來優化Delta幀,優化後的幀稱爲閾值幀。而且,咱們將應用一些複雜的圖像處理技術,例如陰影消除、擴張輪廓等,以完成在閾值幀上提取對象物體。如下是您要實現的目標:

被探測對象


當這個對象進入幀和退出幀時,咱們可以很容易的捕獲這兩幀的時間戳。所以,將可以準確的在視頻中找到相關片斷。


咱們但願小夥伴都能本身實現這個程序,所以咱們就不直接嵌入代碼了。


從最基本的安裝開始,咱們須要安裝Python3或更高版本,並使用pip安裝pandas和OpenCV這兩個庫。這些工做作好,咱們的準備工做就完成了。


第一步:導入須要的庫:



第二步:初始化變量,列表,data frame


在下面的代碼中,咱們將會了解到在何時須要使用上面涉及到的每一項。


第三步:使用網絡攝像機捕獲視頻幀:


在OpenCV中有可以打開相機並捕獲視頻幀的內置函數。其中輸入參數「0」表示計算機硬件端口號爲0的攝像機。若是咱們擁有了多個攝像頭或閉路電視等設置,能夠經過該參數提供相應的端口號。


第四步:將捕捉到的幀轉換爲灰度圖像,並應用高斯模糊去除噪聲:


因爲彩色圖片中每一個像素均具備三個顏色通道,實際上咱們並不須要使用這麼多的信息,所以首先將彩色幀轉換成灰度幀。再利用高斯模糊對圖像進行平滑處理,進而提升檢測精度。在高斯模糊函數中,咱們利用第2個參數定義了高斯核的寬度和高度;利用第3個參數,定義了標準誤差值。在這裏咱們可使用核大小爲(21,21),標準誤差爲0的標準值。想要了解有關高斯平滑的更多信息,請參考:

Smoothing Images - OpenCV 2.4.13.7 documentation In an analogous way as the Gaussian filter, the bilateral filter also considers the neighboring pixels with weights…

docs.opencv.org


第五步:捕獲第一個灰度幀


第一幀是整個處理過程當中的基準幀。經過計算此基準幀與新幀之間特定對象的相位差來檢測運動。在拍攝第一幀時,特定對象相機前不該有任何移動。可是獲得的第一幀並不須要後續處理,所以咱們能夠用continue語句跳事後續過程。


第六步:建立Delta幀和閾值幀


如今,咱們須要找出第一幀和當前幀之間的區別。所以,咱們使用absdiff函數並將獲得的結果稱爲delta幀。對於咱們的用例來講,僅僅找到一個差別是不夠的,因此咱們須要定義一個像素閾值,它能夠被視爲真實的對象。


咱們能夠選擇30像素做爲標準閾值,並將標準閾值的顏色定義爲白色(顏色代碼:255). 二元閾值函數THRESH_BINARY返回一個元組值,其中只有第二項([0]是第一項,[1]是第二項)包含生成的閾值幀。二元閾值函數用於處理含有2個離散值的非連續函數:如0或1。若是攝影機前面沒有對象,咱們將當前幀的狀態視爲0;若是攝影機前面存在對象,則將當前幀的狀態視爲1。


更多閾值圖像處理相關知識,請參考:

Miscellaneous Image Transformations - OpenCV 2.4.13.7 documentation Performs a marker-based image segmentation using the watershed algorithm. The function implements one of the variants…

docs.opencv.org


第七步:膨脹閾值幀並在其中找到輪廓像素


「咱們的眼睛老是被光線吸引,但陰影處有更多內容。」—格雷戈裏·馬奎爾


對象的每一個部分都會在背景或自身的其餘部分留下必定的陰影。這彷佛老是讓咱們感到很困惑。例如,鼻子投射在嘴脣上的陰影,較大的靜止物體在旁邊的小物體上投射的陰影。飄動的光源,不一樣發光強度的多個光源,你房間的窗簾,光源的方向和視角等等都會對陰影形成必定的影響。


如下是在實時捕獲的幀中發現的一些干擾。所以,爲了使這些噪聲最小化,咱們須要對圖像進行濾波。在膨脹函數Dilate中,咱們能夠經過設置迭代次數來設置平滑度。迭代次數越多,平滑度越高,處理時間也就越長。所以,建議保持標準化設置爲3。膨脹函數中的「None」參數表示咱們的應用中不須要元素結構。


關於膨脹的更多知識,你能夠參考:

Image Filtering - OpenCV 2.4.13.7 documentation Functions and classes described in this section are used to perform various linear or non-linear filtering operations…

docs.opencv.org


完成過濾之後,咱們須要在該幀中找到對象輪廓。咱們用當前幀中的輪廓來識別對象的大小和位置。爲了實現這一點,咱們將該幀的一個副本傳遞到findCounters方法中,使用這個副原本查找輪廓。使用副本的緣由是,咱們不但願輪廓識別影響到原始過濾幀。


這裏有個麻煩,由於咱們必須將輪廓存儲在一個元組中,而且只須要使用該元組的第一個值。請參閱Python3中聲明元組的語法:(name,_)。


如今,咱們只須要在過濾層上找到對象的外部輪廓。對於咱們的用例來講,除了極端外部輪廓之外的其餘輪廓都是無用的。所以咱們必須使用一些近似方法來優化輪廓的提取過程。例如使用曲線近似或曲線插值,也可使用簡單鏈近似規則,即壓縮水平、垂直和對角線線段,只保留其端點。所以,咱們可以很快獲得最佳擬合輪廓。



第八步:找到輪廓區域,並在矩形中造成端點:

實際上咱們並不想捕捉像昆蟲這樣的小物體,而是要捕捉像人或動物這樣的大物體。所以咱們採用輪廓區域的概念,即跳過那些面積小於10000像素的對象。對於大於此區域的輪廓,咱們將狀態設置爲1,即檢測到對象。


想知道關於圖像處理中的輪廓,能夠參考:

Structural Analysis and Shape Descriptors - OpenCV 2.4.13.7 documentation Draws contours outlines or filled contours. The function draws contour outlines in the image if or fills the area…

docs.opencv.org


如今咱們使用boundingRect函數捕捉輪廓的座標。而後,咱們使用這些座標在彩色幀上繪製一個特定顏色、特定厚度的矩形。此矩形描述了實際檢測到的對象。


第九步:捕獲對象進入幀(場景)和退出幀(場景)時的時間戳

「狀態」列表status_list存儲值0:表明未檢測到對象,1:表明檢測到對象。此狀態值從0更改成1的時刻就是對象進入幀的那一時刻。一樣,此狀態值從1變爲0的時刻就是對象從幀中消失的那一時刻。所以,咱們從狀態列表的最後兩個值能夠得到這兩個切換事件的時間戳。


第十步:顯示全部不一樣的畫面(幀)



使用imshow()方法,咱們將在一個獨立的窗口中顯示每一個幀並進行比較。



咱們使用waitKey函數來延遲進程,直到按下某個鍵。在這裏,咱們使用waitKey(1)從攝像機得到連續的實時反饋。想中止拍攝視頻時,只需按鍵盤上的「Q」鍵便可。



咱們同時須要在按下「Q」的同時捕獲最後一個時間戳,由於這將幫助程序結束從攝像機捕獲視頻的過程,並生成時間數據。


下面是使用該應用程序生成的實際圖像輸出。第一個圖像表示基準幀的4個幀類型,第二個圖像表示帶有對象的幀的4種類型的幀。你能比較一下區別嗎?


Baseline First Frame

Frame with a detected object



第十一步:生成時間數據


到目前爲止,全部的時間戳都存儲在pandas的data-frame變量中。爲了從生成的數據中得到更多信息,咱們將把data-frame變量導出到本地磁盤的csv文件中。


請不要忘記釋放視頻變量,由於它在內存中佔用了很多空間。同時銷燬全部窗口以免出現沒必要要的錯誤


這就是生成的csv的樣子。正如咱們所看到的那樣,在程序結束以前,這個對象已經被檢測了3次。您能夠查看開始時間和結束時間,並計算對象在攝影機前面的時間。


這個應用程序還不夠使人興奮嗎?這個應用程序是否是遠離了典型的無聊編程?物聯網愛好者甚至能夠把這個程序部署到樹莓派服務器Raspberry Pi上,並創造奇蹟!


若是本文對小夥伴有幫助,但願能夠在文末來個「一鍵三連」。


交流羣

歡迎加入公衆號讀者羣一塊兒和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫學影像、GAN算法競賽等微信羣(之後會逐漸細分),請掃描下面微信號加羣,備註:」暱稱+學校/公司+研究方向「,例如:」張三 + 上海交大 + 視覺SLAM「。請按照格式備註,不然不予經過。添加成功後會根據研究方向邀請進入相關微信羣。請勿在羣內發送廣告,不然會請出羣,謝謝理解~


本文分享自微信公衆號 - 小白學視覺(NoobCV)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索