我会用
changes = (fgmask>200).sum()
比较具有几乎白色值(> 200)的所有像素并计算这些像素。
然后我可以将结果与某个值进行比较以将其视为移动。
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
ret, frame = cap.read()
if frame is None:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(gray)
#changes = sum(sum(fgmask>200))
changes = (fgmask>200).sum()
is_moving = (changes > 10000)
print(changes, is_moving)
cv2.imshow('frame', fgmask)
k = cv2.waitKey(10) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
print()
需要一些时间来显示文本,因此打印所有像素(循环多次)会减慢程序的速度。所以我跳过这个。我不必知道所有像素的值。
编辑:在如何使用opencv检测大#白色像素区域中使用答案?并添加可以找到白色区域并绘制矩形的代码。程序打开两个窗口 - 一个是灰度的fgmask
,另一个是 RGB 的frame
,它们可以一个接一个地隐藏。您必须移动一个窗口才能看到另一个窗口。
编辑:我添加了代码,该代码使用cv2.contourArea(cnt)
并(x,y,w,h) = cv2.boundingRect(cnt)
为所有计数创建包含项目(面积、x、y、w、h)的列表,然后获得max(items)
具有最大面积的轮廓。然后它(x + w//2, y + h//2)
用作红色圆圈的中心。
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
ret, frame = cap.read()
if frame is None:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(gray)
#changes = sum(sum(fgmask>200))
changes = (fgmask>200).sum() #
is_moving = (changes > 10000)
print(changes, is_moving)
items = []
contours, hier = cv2.findContours(fgmask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
area = cv2.contourArea(cnt)
if 200 < area:
(x,y,w,h) = cv2.boundingRect(cnt)
cv2.rectangle(fgmask, (x,y),(x+w,y+h),255, 2)
cv2.rectangle(frame, (x,y),(x+w,y+h),(0,255,0), 2)
items.append( (area, x, y, w, h) )
if items:
main_item = max(items)
area, x, y, w, h = main_item
if w > h:
r = w//2
else:
r = h//2
cv2.circle(frame, (x+w//2, y+h//2), r, (0,0,255), 2)
cv2.imshow('fgmask', fgmask)
cv2.imshow('frame', frame)
k = cv2.waitKey(10) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()