我目前正在做一个运动检测项目,该项目可以检测运动并在运动周围绘制一个红色的边框。现在,我的程序确实检测到运动并在运动周围绘制了一个边界框,但是还有许多重叠的边界框以及正确的边界框。有什么办法可以减少到1个盒子吗?
这是我的代码:
for c in cnts:
if cv2.contourArea(c) < 500:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x,y), (x + w, y + h), (0, 0, 255), 2)
这是当前结果(在网上找到这张图片,但这是相同的问题):
最佳答案
要在最终结果中仅显示一个边界框,则必须先保存原始图像。然后,每次绘制边界框时,都必须将其绘制在原始原始图像的副本上,并将此新绘制的图像保存为结果。
我假设您正在使用一个循环,并且在此循环内您在图像上绘制了边界框,但是每次都在同一图像变量上绘制,从而导致出现多个可见的边界框。如果这是一个错误的假设,请在问题中进行说明,提供更多代码,并提供一个输出示例,显示可见错误以及所需结果的示例。
如果您只想显示描述运动的最新框,则无需担心以下算法。
groupRectangles()
openCV中存在一个内置函数,该函数将彼此靠近且形状和大小相似的矩形分组为groupRectangles()。它将返回由彼此靠近的组合矩形产生的矩形列表。对于不同版本的openCV(3.0 beta docs of groupRectangles()),应该有相似的功能,即使功能不完全相同。
编写简单的算法:
如hinted by @pypypy在对问题的评论中所示,如果重新绘制的框太小且未显示所需的运动区域,则可以执行简单的算法来组合它们。但是,由于边界框没有描绘出小的移动,因此您可能并不想采用两个框中的较大框(您需要通过示例来阐明所需的输出)。
有一个简单的算法可以将边界框组合在一起,因此您将拥有一个覆盖新边界框和上一个边界框总面积的边界框。该算法涉及从两个框中获取所有x和y值的最大值和最小值,然后仅将基于这些x和y值的新框绘制到原始原始图像的副本上。这将创建一个包围所有当前和先前运动区域的边界框。