如何在opencv中获取旋转椭圆的主轴起始和结束坐标(x,y)?

4

我正在执行物体运动追踪,试图识别物体的前后方。该物体不对称,这意味着轮廓的质心比后面更靠近前面。根据这些信息,我按以下方式处理:

  1. Draw contours of object

  2. Find centroid

    centroidx, centroidy = int(moments['m10']/moments['m00']), int(moments['m10']/moments['m00'])
  3. Draw bounding ellipse

    cv2.fitEllipse(contour)
  4. Calculate major axis length as follows (and as shown in the figure)

    MAx, MAy = int(0.5 * ellipseMajorAxisx*math.sin(ellipseAngle)), int(0.5 * ellipseMajorAxisy*math.cos(ellipseAngle))
  5. Calculate beginning and ending x, y coordinates of the major axis

    MAxtop, MAytop = int(ellipseCentrex + MAx), int(ellipseCentrey + MAy)
    MAxbot, MAybot = int(ellipseCentrex - MAx), int(ellipseCentrey - MAy)
  6. Identify which of the points is closer to the centroid of the contour

    distancetop = math.sqrt((centroidx - MAxtop)**2 + (centroidy - MAytop)**2)
    distancebot = math.sqrt((centroidx - MAxbot)**2 + (centroidy - MAybot)**2)
    min(distancetop, distancebot)
我遇到的问题是,虽然大部分时候我得到了椭圆的"前"端正确的位置,但有时点会稍微偏移。据我观察,这似乎是发生在x值正确,但y值不同的情况下(实际上,我认为这代表了垂直于我的椭圆的长轴)。我不确定这是否是opencv计算角度的问题,或者更可能是我的计算错误。我知道这是一个复杂的例子,希望我的数字能够帮助!

Position1 Position2

编辑:当我把椭圆错看成一个垂直的点时,它其实是我的椭圆的镜像。这种情况也会出现在x值上,而不仅仅是y值。

在按照ssm下面的建议后,我大部分时间都得到了期望的点。有时候点还是会出错,但很快就会“回弹”到正确位置。例如,在这种情况下,这是一些帧: improved

顺便说一下,上述图片是通过使用以下代码“修正”角度后得到的:

        if angle > 90:
            angle = 180 - angle

如果我不进行校正,有时候会出现错误的点,如下所示,对于相同的帧。 angle not corrected 因此,看起来我通过角度校正可以得到某些角度的正确点,而未经校正的其他角度则无法获得正确点。如何在两种情况下都获得所有正确的点?
(椭圆内部的白点是轮廓的质心,而椭圆上或外部的点是我得到的点)
1个回答

1

我认为你唯一的问题是 MAytop。你可以考虑采取以下措施:

if ycen<yc:
    # switch MAytop and MAybot
    temp = MAytop
    MAytop = MAybot
    MAybot = temp

你可能需要对x轴进行类似的检查。

3
在Python中,你可以使用MAytop, MAybot = MAybot, MAytop来交换两个变量的值。 - David Zwicker
哦,我没有意识到这一点。但现在你这么说,我看到了元组的内在转换和反向转换。这是如此明显,而我甚至一直没有想到它。谢谢!! - ssm
@ssm 谢谢,这似乎改善了跟踪,但问题仍然存在,看起来可能与角度有关?(请参见我在原始问题中的编辑)。 - srao
@srao 你是否正确考虑了椭圆的角度?对于大多数编程语言,角度是逆时针从x轴测量的。我假设cv2也是如此(尽管我没有检查过cv2文档)。而你正在以顺时针方式从y轴测量角度。 - ssm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接