问题描述
我已经编写了一个代码来检测网络摄像头的运动,但是每当我启动该代码时,它都可以工作,但是它可以检测整个全屏屏幕,而不是屏幕上移动的对象。我注意到,如果关闭相机,似乎会删除检测到的东西。这是代码:
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()
该代码应该只能检测屏幕中的移动物体。
解决方法
刚开始使用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负责相机启动的延迟时间。 试试代码,它在这里起作用