1

这是一个更普遍的问题,因为我不知道如何有效地解决或解决这个问题:

  • 我正在使用 OpenCV 获取移动对象的实时轮廓点((x,y)坐标元组列表)
  • 我想在这些轮廓点内绘制矩形,具体取决于其中是否有角度

假设下图显示了我手臂的轮廓点。我希望它检测一定角度的角度,并根据它在里面画一些矩形。

在此处输入图像描述

这背后的整个想法是让它稍后在 pygame 中与一些游戏对象(例如球)交互。例如,用手或棍子或任何在镜头前移动的物体移动球。

这就是为什么我想避免使用更多高级库(如 openpose)来获取我的手臂骨架,因为游戏应该可以与任何类型的对象一起玩,而且运行流畅。

如果您知道可以为这个问题命名的合适方法,我将不胜感激!

到目前为止我想到的方法:

  • 我最初的想法是计算每个相邻轮廓点的距离和角度。如果角度大于某个角度,它将被认为是一个新的集群。然而,这似乎不可靠,因为手(手指)有锋利的边缘,我不想得到一个小东西的骨架,而是像上图那样简单的大形状

  • 我的下一个想法是将所有轮廓点连接在一起并形成一个多边形。但是,这会创建一个复杂的蒙版,并且轮廓点不是恒定的,因此它会振荡太多。这就是为什么我认为一个简单的矩形就足够了,即使它没有像素完美的形状

4

1 回答 1

1

另一种方法是在每个点之间画一条线,然后你可以用线制作对象,然后进行线交叉以检查碰撞。我最近制作了一个程序,使用来自维基百科的数学来做到这一点

#check if 2 lines are intersecting
#lines are 2 pygame Vector2 
def LineIntersect(line1, line2):
    #the math is from wikipedia
    x1 = line1[0].x
    y1 = line1[0].y
    x2 = line1[1].x
    y2 = line1[1].y

    x3 = line2[0].x
    y3 = line2[0].y
    x4 = line2[1].x
    y4 = line2[1].y

    #denominator 
    den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
    if den == 0:
        return 
    t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den

    u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den

    if t > 0 and t < 1 and u > 0 and u < 1:
        pt = Vector2()
        pt.x = x1 + t * (x2 - x1)
        pt.y = y1 + t * (y2 - y1)
        return pt
    return

您可以对第一种方法执行的另一种方法是通过消除直线上的点来简化形状。我做了一个测试,得到了以下结果 一堆圈起来的 ,其中黑点被移除,红色是简化的形状。不太确定从那里做什么,所以我想我的第一种方法效果最好?这是它的代码

def Prepare(Points):
    New_points = [Points[0]]
    last_point = Vector2(Points[0])
    for i in range(1,len(Points)-1,1):
        p = Vector2(Points[i])
        Dir = p - last_point
        if i < len(Points) - 1:
            New_dir = Points[i+1] - p
            New_dir = New_dir.normalize()
            angle = Dir.angle_to(New_dir)
            if abs(angle) > 15:
                New_points.append(Points[i])
        #print(last_point.angle_to(p))
        pygame.draw.circle(screen,(255,0,0),(int(p.x),int(p.y)),5)    
        last_point = p
    New_points.append(Points[-1])
    return New_points

我所做的是从上一个点到当前点和下一个点的方向,如果差异超过 15 度,它是一个角落,我添加到新点

于 2020-04-14T03:46:38.323 回答