OpenCV检测python中的运动

Ale*_*dar 7 python opencv motion-detection

我的目标是检测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"
Run Code Online (Sandbox Code Playgroud)

这段代码有效,但由于我不太了解直方图,我没有设法直接获得值,但是直方图左侧的一些"黑客"是黑色,右边是白色,并black / white给出我想要的结果.我知道这不是很正确,但是当有人进入投资回报率时,当没有投资回报率和0.5-2.0的结果时,它给出了4-9的结果.

我的问题是:有没有其他方法来读取直方图和比较数据,或其他一些方法?阅读文档对我没有帮助.

U.S*_*wap 2

差分图像是两个图像相减的结果

所以差分图像显示了两个图像之间的差异。通过这些图像,您可以使运动变得可见。

在下面的脚本中,我们使用根据三个连续图像 和 计算出的差分图像。这样做的优点是从结果中删除了无趣的背景。

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)
Run Code Online (Sandbox Code Playgroud)

我们要做的最后一件事是将差分图像函数引入到我们之前的脚本中。在循环开始之前,我们读取前三个图像 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")
Run Code Online (Sandbox Code Playgroud)

在这里,您将找到适合您所寻找内容的更详尽的答案。