我阅读了this博客文章,他使用激光和网络摄像头来估算纸板与网络摄像头的距离。
我对此有另一个想法。我不想计算与网络摄像头的距离。
我想检查对象是否正在接近网络摄像头。根据我的说法,算法将是:
由于我想检测随机对象,我使用findContours()
方法查找视频Feed中的轮廓。使用它,我至少会在视频源中包含对象的轮廓。源代码是:
import numpy as np
import cv2
vid=cv2.VideoCapture(0)
ans, instant=vid.read()
average=np.float32(instant)
cv2.accumulateWeighted(instant, average, 0.01)
background=cv2.convertScaleAbs(average)
while(1):
_,f=vid.read()
imgray=cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
ret, thresh=cv2.threshold(imgray,127,255,0)
diff=cv2.absdiff(f, background)
cv2.imshow("input", f)
cv2.imshow("Difference", diff)
if cv2.waitKey(5)==27:
break
cv2.destroyAllWindows()
输出结果为:
我被困在这里。我将轮廓存储在一个数组中。当尺寸增加时我该怎么办?我该怎么办?
答案 0 :(得分:3)
这里遇到的一个问题是识别并区分移动对象与视频源中的其他内容。一种方法可能是让相机“学习”没有物体的背景。然后,您可以不断地将其输入与此背景进行比较。获得背景的一种方法是使用平均运行。
任何大于小阈值的差异都意味着存在移动物体。如果你经常显示这种差异,你基本上有一个运动跟踪器。对象的大小只是所有非零(阈值)像素或其边界矩形的总和。您可以跟踪此大小并使用它来猜测对象是移动得更近还是更远。形态学操作可以帮助将轮廓分组成一个有凝聚力的对象。
由于它将跟踪任何移动,如果有两个对象,它们将被计算在一起。您可以在此处使用轮廓来查找和跟踪单个对象,例如使用轮廓边界或质心。你也可以用颜色分开它们。
以下是使用此策略的一些结果(灰色斑点是我的手):
它实际上做得很好,可以猜测我的手在哪个方向移动。
代码:
import cv2
import numpy as np
AVERAGE_ALPHA = 0.2 # 0-1 where 0 never adapts, and 1 instantly adapts
MOVEMENT_THRESHOLD = 30 # Lower values pick up more movement
REDUCED_SIZE = (400, 600)
MORPH_KERNEL = np.ones((10, 10), np.uint8)
def reduce_image(input_image):
"""Make the image easier to deal with."""
reduced = cv2.resize(input_image, REDUCED_SIZE)
reduced = cv2.cvtColor(reduced, cv2.COLOR_BGR2GRAY)
return reduced
# Initialise
vid = cv2.VideoCapture(0)
average = None
old_sizes = np.zeros(20)
size_update_index = 0
while (True):
got_frame, frame = vid.read()
if got_frame:
# Reduce image
reduced = reduce_image(frame)
if average is None: average = np.float32(reduced)
# Get background
cv2.accumulateWeighted(reduced, average, AVERAGE_ALPHA)
background = cv2.convertScaleAbs(average)
# Get thresholded difference image
movement = cv2.absdiff(reduced, background)
_, threshold = cv2.threshold(movement, MOVEMENT_THRESHOLD, 255, cv2.THRESH_BINARY)
# Apply morphology to help find object
dilated = cv2.dilate(threshold, MORPH_KERNEL, iterations=10)
closed = cv2.morphologyEx(dilated, cv2.MORPH_CLOSE, MORPH_KERNEL)
# Get contours
contours, _ = cv2.findContours(closed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(closed, contours, -1, (150, 150, 150), -1)
# Find biggest bounding rectangle
areas = [cv2.contourArea(c) for c in contours]
if (areas != list()):
max_index = np.argmax(areas)
max_cont = contours[max_index]
x, y, w, h = cv2.boundingRect(max_cont)
cv2.rectangle(closed, (x, y), (x+w, y+h), (255, 255, 255), 5)
# Guess movement direction
size = w*h
if size > old_sizes.mean():
print "Towards"
else:
print "Away"
# Update object size
old_sizes[size_update_index] = size
size_update_index += 1
if (size_update_index) >= len(old_sizes): size_update_index = 0
# Display image
cv2.imshow('RaptorVision', closed)
显然,在识别,选择和跟踪物体等方面需要做更多的工作(如果在背景中有其他东西移动的话,它会非常可怕)。还有许多参数可以改变和调整(那些设置适用于我的系统)。我会把它留给你。
一些链接:
如果你想通过删除背景获得更多高科技,请看一下:
答案 1 :(得分:1)
Detect the object in the webcam feed. If the object is approaching the webcam it'll grow larger and larger in the video feed. Use this data for further calculations.
好主意。 如果要使用轮廓检测方法,可以通过以下方式进行:
另外,您可以尝试修剪不属于正确轮廓的点并使用覆盖矩形。通过这种方式检查尺寸非常容易,但我不知道如何轻松地选择"正确"分。