4

I am performing motion tracking of an object, and I am trying to identify the front and back of the object. The object is asymmetrical, which means that the centroid of the contour is closer to the front than the back. Using this information, I am approaching this as follows:

  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)

The problem I am encountering is, while I get the "front" end of the ellipse correct most of the time, occasionally the point is a little bit away. As far as I have observed, this seems to be happening such that the x value is correct, but y value is different (in effect, I think this represents the major axis of an ellipse that is perpendicular to mine). I am not sure if this is an issue with opencv's calculation of angles or (more than likely) my calculations are incorrect. I do realize this is a complicated example, hope my figures help!

Position1 Position2

EDIT: When I get the wrong point, it is not from a perpendicular ellipse, but of a mirror image of my ellipse. And it happens with the x values too, not just y.

After following ssm's suggestion below, I am getting the desired point most of the time. The point still goes wrong occasionally, but "snaps back" into place soon after. For example, this is a few frames when this happens: improved

By the way, the above images are after "correcting" for angle by using this code:

        if angle > 90:
            angle = 180 - angle

If I do not do the correction, I get the wrong point at other times, as shown below for the same frames. angle not corrected

So it looks like I get it right for some angles with angle correction and the other angles without correction. How do I get all the right points in both conditions?

(White dot inside the ellipse is the centroid of the contour, whereas the dot on or outside the ellipse is the point I am getting)

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
srao
  • 308
  • 1
  • 3
  • 13

1 Answers1

1

I think your only problem is MAytop. You can consider doing the following:

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

You may have to do a similar check on the x - scale

ssm
  • 5,277
  • 1
  • 24
  • 42
  • 3
    In python, you can do `MAytop, MAybot = MAybot, MAytop`. – David Zwicker Jan 30 '16 at 00:54
  • Oh. I didn't realize that. But now that you say that I see the intrinsic conversion to tuple, and back. It is so obvious, and I didn't even think about it all this while. Thanks!! – ssm Jan 30 '16 at 00:58
  • @ssm Thanks, this seems to improve the tracking, but the issue persists and it seems like it might be something to do with the angle? (please see my edit in original question). – srao Jan 30 '16 at 11:21
  • @srao Have you considered the ellipse angle correctly? For most languages, the angle is measured anti-clockwise from the x-axis. I assume that it is the same for `cv2` (although I haven't checked cv2 documentation). You are measuring the angle from the y-axis in a clockwise manner. – ssm Feb 01 '16 at 04:23