Search code examples
pythonopencvkeypointransacgoodness-of-fit

Keypoint Descriptor Matching: How to calculate a goodness-of-fit per template?


I am not sure whether this belongs on stackoverflow or another stackexchange site - input very welcome here.

I have used python OpenCV to match a target image's BRISK keypoint descriptors to - in turn - three different templates.

What is a practical, robust, statistically-sound way to decide which template is the best-fitting one?

Right now I calculate the number of cv2.RANSAC inliers returned by cv2.findHomography (which incidentally doesn't return a goodness-of-fit statistic) and take the template that has the highest number.

I have looked at histograms of descriptor distances, which always seem to be gaussians centred (weirdly) at about 105 (units?).

https://en.wikipedia.org/wiki/Random_sample_consensus seems quite useful.

Guidance much appreciated - thanks!


Solution

  • This started as a comment but was getting a bit too long.

    Indeed OpenCV computes the reprojection error internally and does not return it. But you could do the same by yourself once you obtain the homography, no? As a matter of fact the algorithm minimizes the sum of the reprojection error over all the points. A quite complete description of the process is in the OpenCV docs

    Since you have the matches (hence the image coordinates of both source and template points). You can compute the average reprojection error, possibly only using points that are treated as inliers, for each of the templates and choose the lowest one.

    From a similar answer on another site:

    computed_pt = H * source_pt
    error_pt = sqrt( (computed_pt.x - dst_pt.x)*(computed_pt.x - dst_pt.x) + (computed_pt.y - dst_pt.y)*(computed_pt.y - dst_pt.y) )
    

    to compute the euclidean distance between the two points.