【问题标题】:Problem with opencv (cv2) detecting motion in my codeopencv(cv2)在我的代码中检测运动的问题
【发布时间】:2020-08-22 22:34:14
【问题描述】:

我编写了一个代码来检测通过网络摄像头的运动,但每当我启动代码时,它都会工作,但它会检测到整个屏幕而不是在屏幕中移动的对象。我注意到,如果我关闭相机,它似乎会移除检测;代码如下:

import cv2

first_frame = None

video = cv2.VideoCapture(0)

while True:
    check, frame = video.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21,21),0)

    if first_frame is None:
        first_frame=gray
        continue

    delta_frame = cv2.absdiff(first_frame,gray)
    thresh_frame = cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
    thresh_frame = cv2.dilate(thresh_frame,None, iterations=2)

    (cnts,_) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for contour in cnts:
        if cv2.contourArea(contour) < 4000:
            continue

        (x,y, w, h)= cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h),(0,225,0),3)


    cv2.imshow("Delta Frame",delta_frame)
    cv2.imshow("Capturing",gray)
    cv2.imshow("Threshold Frame",thresh_frame)
    cv2.imshow("Color Frame",frame)

    key = cv2.waitKey(5)

    if key==ord('q'):
        break

video.release()
cv2.destroyAllWindows()

代码应该只能检测到屏幕中的移动物体。

【问题讨论】:

  • 请让您的代码可重现。
  • 不熟悉 cv2 包,但似乎delta_frame = cv2.absdiff(first_frame,gray) 本质上是在调用absdiff(gray, gray),因为前面的行设置了first_frame=gray。这是预期的代码,还是您的意思是absdiff(frame, gray)

标签: python opencv cv2


【解决方案1】:

我刚开始使用 opencv 时遇到过类似的问题;程序的问题是第一帧,第一帧捕捉到了黑屏。第一帧(first_frame)与下一帧(灰色)的 cv2.absdiff 检测到的差异足够大,以至于 cv2.findContours 显示在整个屏幕上。这可能是由于相机延迟造成的

可以通过在相机加载到程序使用 time.sleep() 记录第一帧(first_frame)之间加入轻微延迟来解决。试试这个:

import cv2, time


first_frame = None

video = cv2.VideoCapture(0)
# the camera has some lag time hence the starting of video.read outside loop and sleep
video.read()
time.sleep(2)

while True:
    check, frame = video.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21,21),0)

    if first_frame is None:
        first_frame=gray
        continue

    delta_frame = cv2.absdiff(first_frame,gray)
    thresh_frame = cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
    thresh_frame = cv2.dilate(thresh_frame,None, iterations=2)

    (cnts,_) = cv2.findContours(thresh_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for contour in cnts:
        if cv2.contourArea(contour) < 4000:
            continue

        (x,y, w, h)= cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h),(0,225,0),3)


    cv2.imshow("Delta Frame",delta_frame)
    cv2.imshow("Capturing",gray)
    cv2.imshow("Threshold Frame",thresh_frame)
    cv2.imshow("Color Frame",frame)

    key = cv2.waitKey(5)

    if key==ord('q'):
        break

video.release()
cv2.destroyAllWindows()

time.sleep 负责相机启动的延迟时间。 试试这个代码,它在这里工作

【讨论】:

    猜你喜欢
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    相关资源
    最近更新 更多