OpenCV将整个视频帧检测为对象

时间:2018-11-01 17:47:44

标签: python python-3.x opencv computer-vision

我正在尝试制作一个使用我的笔记本电脑(win 10)网络摄像头检测对象的程序,为此,我正在使用python 3.7和openCV 3.4。这是我的代码:

import cv2
first_frame = None
video = cv2.VideoCapture(0)

while True:

    check, frame = video.read()
    status = 0

    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, 40, 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) < 10000:
            continue

        status = 1
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)

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

    key = cv2.waitKey(1)

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

    print(status, end=" ")
cv2.destroyAllWindows()
video.release()

它应该在移动或刚进入帧的对象周围绘制一个红色矩形。我在移动不多的地方使用它,因此在电影中可以正常工作。首先将图片作为第一帧并将其与其余帧进行比较,依此类推。问题在于,每当我运行脚本时,它都会将出现在窗口中的整个视频帧检测为一个对象(一个大的红色矩形覆盖了显示窗口的所有边缘和角落)。房间(更确切地说是静态背景)不是黑暗的。为了测试是否将背景检测为对象,我添加了status,该对象最初为零,并且无论何时和对象进入帧或将其移动到应更改为1的状态,控制台中将打印状态。即使没有输入任何帧1,也表明出现了问题。当脚本运行时,阈值窗口全为白色,我相信如果它是黑色的,则可以解决问题。另外,我该如何改善我的代码,使其可以更快更好地进行检测?

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,但是我真的不明白为什么它起作用。这是我的解决方案:
考虑我的代码的这一行:

 thresh_frame = cv2.threshold(delta_frame, 40, 255, cv2.THRESH_BINARY)[1]

通过将cv2.THRESH_BINARY更改为cv2.THRESH_BINARY_INV似乎可以解决问题。有趣的是,我在中午和晚上进行了实验,因此光线条件大部分是人为的,因此我决定进行实验早上有阳光(我没有更改设置)。早上发生了同样的问题(整个帧都被检测为物体),所以这次我将cv2.THRESH_BINARY_INV更改为cv2.THRESH_BINARY并解决了问题。总之,我得出的结论是cv2.THRESH_BINARY适用于有阳光的地方,cv2.THRESH_BINARY_INV适用于使用灯和...的情况;但是正如我说的,我没有理由。