我有一個Raspberry Pi,它記錄來自PIR傳感器的運動檢測的視頻。有時,「隨機」熱量變化會錯誤地觸發傳感器,並在沒有任何動作時錄製視頻。如果圖片中沒有任何動作,我想通過使用OpenCV進行圖像處理來過濾掉這些視頻2.4.8來自太陽的運動檢測照明
要保存的視頻有兩個標準:觸發PIR傳感器和動作的熱量分佈在視頻中。它適用於大多數視頻,但我注意到照明有時會有很大差異,模仿視頻中的真實動作並錯誤地觸發過濾器。
# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
return cv2.bitwise_and(d1, d2)
kernel = np.ones((5,5),np.uint8)
for dirpath, dnames, fnames in os.walk("/path/to/videos"):
for f in fnames:
cap = cv2.VideoCapture(os.path.join(dirpath, f))
total = 0
count = 0
# Read three images first:
t_minus = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cap.read()[1], cv2.COLOR_RGB2GRAY)
while True:
opening = cv2.morphologyEx(diffImg(t_minus, t, t_plus), cv2.MORPH_OPEN, kernel)
total += cv2.countNonZero(opening)
# Read next image
t_minus = t
t = t_plus
ret, frame = cap.read()
if ret == False:
break
t_plus = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
count += 1
if total/count < 800:
print "file %s has no motion (%d)" % (os.path.join(dirpath, f), total/count)
我的算法很簡單。它抓取三幀並計算差異,並使用cv2.bitwise_and創建二進制圖像。爲了去除噪聲,它在該差分圖像上執行形態學開放。最後它使用cv2.countNonZero來確定該幀中的運動量。最後,我將動作總數除以幀數(讓我們稱之爲動作/幀)來獲得一個數字。如果這個數字小於800,那麼視頻會持續不動。
下面是兩個例子(一個正的檢測和一個假陽性檢測)
陽性:
https://www.dropbox.com/s/ryvemvkoda6morn/2016-05-11_07-12-20.ts?dl=0(運動/幀:843) 誤報:
https://www.dropbox.com/s/lqegj92jxhjjegv/2016-05-12_19-16-10.ts?dl=0(運動/幀:879)
從後者可以看出,當照度變化很大時,它被錯誤地檢測爲運動。我如何從光照變化中刪除這些誤報?
另一件值得一提的事情是,這個過濾器將作爲一個後處理來運行,即它不會實時進行,因此我可以採用比我現有的方法性能更重的解決方案。
(編輯:我運行Linux這樣的解決方案需要在Linux上工作)
謝謝,我會再看看這一點,看看我能否找到解決方案。 – Linus
我在Python工作,需要我的解決方案在Linux上工作,因此我無法使用該特定的實現,但感謝您的鏈接。 – Linus