opencv (cv2) 在我的代码中检测运动的问题
Problem with opencv (cv2) detecting motion in my code
我已经编写了一个代码来通过网络摄像头检测运动,但每当我启动该代码时,它都能正常工作,但它会检测整个全屏,而不是检测屏幕中移动的对象。我注意到如果我关闭相机,它似乎会删除检测;这是代码:
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 负责相机启动的延迟时间。
试试代码,它在这里工作
我已经编写了一个代码来通过网络摄像头检测运动,但每当我启动该代码时,它都能正常工作,但它会检测整个全屏,而不是检测屏幕中移动的对象。我注意到如果我关闭相机,它似乎会删除检测;这是代码:
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 负责相机启动的延迟时间。 试试代码,它在这里工作