我的目标是在IP摄像机流上检测特定区域的运动。我成功地编写了工作代码,但这是基于我个人的理解。
import cv2
import numpy as np
import os
import time
import datetime
import urllib
import pynotify
stream=urllib.urlopen('http://user:pass@192.168.198.120/video.mjpg')
bytes=''
fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
bytes+=stream.read(16384)
a = bytes.find('\xff\xd8')
b = bytes.find('\xff\xd9')
if a!=-1 and b!=-1:
jpg = bytes[a:b+2]
bytes= bytes[b+2:]
img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.IMREAD_COLOR)
rows,cols,c = img.shape
mask = np.zeros(img.shape, dtype=np.uint8)
roi_corners = np.array([[(940,220),(1080,240), (1080,310), (940,290)]], dtype=np.int32)
channel_count = img.shape[2]
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(img, mask)
fgmask = fgbg.apply(masked_image)
iii = fgmask[220:310,940:1080]
hist,bins = np.histogram(iii.ravel(),256,[0,256])
black, white, cnt1, cnt2 = 0,0,0,0
for i in range(0,127):
black += hist[i]
cnt1+=1
bl = float(black / cnt1)
for i in range(128,256):
white += hist[i]
cnt2+=1
wh = float(white / cnt2)
finalResult = ((bl+1) / (wh+1))/10
if finalResult < 1.0:
pynotify.init("cv2alert")
notice = pynotify.Notification('Alert', 'Alert text')
try:
notice.show()
except gio.Error:
print "Error"这段代码可以工作,但是由于我对直方图不太了解,所以我没有直接得到值,但是对于一些“黑客”,比如直方图的左边是黑色的,右边是白色的,black / white给出了我想要的结果。我知道这是不完全正确的,但它给了我4-9的结果,当没有人在ROI和0.5-2.0的结果,当有人进入这个ROI。
我在这里的问题是:是否有其他方法来读取直方图和比较数据,或者其他方法?阅读文档对我没有帮助。
发布于 2016-11-21 10:35:05
差分图像是两幅图像相减的结果。
因此,差分图像显示了两幅图像的差异。有了这些图像,你可以使运动可见。
在下面的脚本中,我们使用从三个连续图像计算出的差异图像,以及。这样做的好处是从结果中删除了不感兴趣的背景。
OpenCV提供了使用absdiff()从彼此之间减去两个图像的可能性。另外,对两个图像的逻辑操作已经实现。我们使用bitwise_and()方法来实现最终的差分图像。在python中,如下所示:
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
return cv2.bitwise_and(d1, d2)我们必须做的最后一件事是将差分图像函数引入到前面的脚本中。循环开始前,我们读取前三幅图像t_minus、t和t_plus,并将它们转换为灰度图像,因为我们不需要颜色信息。有了这些图像,就有可能开始计算差分图像。在显示了微分图像之后,我们只需要去掉最老的图像,然后读取下一个图像。最后的脚本如下:
import cv2
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
return cv2.bitwise_and(d1, d2)
cam = cv2.VideoCapture(0)
winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.WINDOW_AUTOSIZE)
# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
while True:
cv2.imshow( winName, diffImg(t_minus, t, t_plus) )
# Read next image
t_minus = t
t = t_plus
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
key = cv2.waitKey(10)
if key == 27:
cv2.destroyWindow(winName)
break
print("Goodbye")http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
发布于 2016-11-16 17:43:30
一种检测运动的方法是使用cv2.accumulateWeighted保持场景的运行平均值。然后,将每个新帧与使用cv2.absdiff的平均值进行比较,以获得表示场景变化的图像。
我正是在我的视频处理项目中这样做的。查看文件diffavg1.py中的主循环,在其中运行累加器并执行diff。
(该项目的研究是利用多核CPU架构来实现实时视频处理,因此较晚版本的diffavg2.py、diffavg3.py和diffavg4.py的性能逐步提高,但底层的累加差分算法是相同的。)
发布于 2019-05-08 16:22:34
这可以用ecapture来完成。
安装
pip install ecapture代码
from ecapture import motion as md
md.motion_detect(0,"x")
print("detected")这段代码将打印
detected一旦在摄像机的视野中有运动
https://stackoverflow.com/questions/40514508
复制相似问题