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



我正在尝试制作一个程序,用我的笔记本电脑(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,表明出了问题。当脚本运行时,阈值窗口都是白色的,我相信如果是黑色的,问题就会解决。此外,我如何改进我的代码,使其能够更快、更好地检测?

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

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在有灯和。。。使用;但正如我所说,我不知道原因。

最新更新