我有一个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上运行)
答案 0 :(得分:2)
研究照明不变运动检测算法,即对比度拉伸或亮度均衡等。
您是否已经研究过物理/硬件解决方案,或许可以用可能减少眩光效果的PIR传感器覆盖?
编辑:
我刚刚发现this result有关通过遮蔽去除眩光效果的问题。它可能会对你有帮助。
编辑2:
在发布答案时无法记住这一点,但很久以前我遇到了this implementation,用C ++编写。