Ask Your Question

Revision history [back]

I finally managed to solve this problem and this is how I went about doing it.

  1. I translated my contours back to the origin.
  2. Then I rotated them about the origin to match the alignment of my template image.
  3. Implemented the brute-force Hausdorff distance as illustrated here and allowed contours which passed my set threshold.

My new Hausdorff distance implementation looked like this:

int distance(vector<Point>const& image, vector<Point>const& tempImage)
{
    int totalDistance = 0;

    for(Point imagePoint: image)
    {
        int minDistance = numeric_limits<int>::max();

        for(Point tempPoint: tempImage)
        {
            Point diff = imagePoint - tempPoint;
            int length = (diff.x * diff.x) + (diff.y * diff.y);

            if(length < minDistance) minDistance = length;
            if(length == 0) break;
        }

        if(minDistance > totalDistance) totalDistance = minDistance;
    }
    return totalDistance;
}

With regards to scale, that's where the image pyramids came into play. Turned out the slidingWindows were entirely useless.

Aside from the first two steps, the previous Hausdorff Distance implementation was not working for me at all. Why you might ask?

  1. The maxDistance += minDistance part was just killing me. I was getting huge values as my distance even though my frame size was nowhere close to being that huge. Distances north of 3k were the norm.
  2. When comparing two equal images, granted it gave me a 0 for the one contour that matched perfectly but the next closest contour had a value of 28.5657 followed by 358.049. With the revised version, the perfect match had a 0, then followed by 4.12311 then 50.04.
  3. The revised version made it easier and sensible to even set a threshold for qualifying contours.

With that said, I am still learning so before down voting, please point out my mistake so I can learn from it.

I finally managed to solve this problem and this is how I went about doing it.

  1. I translated my contours back to the origin.
  2. Then I rotated them about the origin to match the alignment of my template image.
  3. Implemented the brute-force Hausdorff distance as illustrated here and allowed contours which passed my set threshold.

My new Hausdorff distance implementation looked like this:

int distance(vector<Point>const& image, vector<Point>const& tempImage)
{
    int totalDistance = 0;

    for(Point imagePoint: image)
    {
        int minDistance = numeric_limits<int>::max();

        for(Point tempPoint: tempImage)
        {
            Point diff = imagePoint - tempPoint;
            int length = (diff.x * diff.x) + (diff.y * diff.y);

            if(length < minDistance) minDistance = length;
            if(length == 0) break;
        }

        if(minDistance > totalDistance) totalDistance = minDistance;
    }
    return totalDistance;
}

With regards to scale, that's where the image pyramids came into play. Turned out the slidingWindows were entirely useless.

Aside from the first two steps, the previous Hausdorff Distance implementation was not working for me at all. Why you might ask?

  1. The maxDistance += minDistance part was just killing me. I was getting huge values as my distance even though my frame size was nowhere close to being that huge. Distances north of 3k were the norm.
  2. When comparing two equal images, granted it gave me a 0 for the one contour that matched perfectly but the next closest contour had a value of 28.5657 followed by 358.049. With the revised version, the perfect match had a 0, then followed by 4.12311 then 50.04.
  3. The revised version made it easier and sensible to even set a threshold for qualifying contours.

With that said, I am still learning so before down voting, please point out my mistake so I can learn from it.

EDIT I

After performing multiple tests, I observed two things

  1. Without +=, the detection work just fine when the camera is pointed directly at the object.
  2. += worked best even with weird camera angles but the thresholding is still tricky.

Thanks to @berak, I finally caved in to +=