4

I am using OpenCV template matching to find an image within another image.

Specifically matchTemplate() which returns a cv::Mat containing a similarity map of the matches.

Is there any way to sort through the cv::Points contained in that cv::Mat besides using minMaxLoc()?

    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

I have tried:

    cv::Mat_<uchar>::iterator it = result.begin<uchar>();
    cv::Mat_<uchar>::iterator end = result.end<uchar>();
    for (; it != end; ++it)
    {
        cv::Point test(it.pos());
    }

With limited success.

Aurelius
  • 11,111
  • 3
  • 52
  • 69
RubenSandwich
  • 379
  • 1
  • 6
  • 12
  • What is the result you're trying to accomplish? How should the points be sorted? – Aurelius Jul 31 '13 at 16:56
  • I am hoping to compare the points to a baseline in order to get a confidence factor for the template matching. I'm trying to iterator through the points from best match to worse match. – RubenSandwich Jul 31 '13 at 17:03

1 Answers1

4

If I understand you correctly, you wish to sort pixels by their match score, and then get the points corresponding to these pixels in the sorted order. You can accomplish this by reshaping result to be a single row, and then calling cv::sortIdx() to get the indices of the pixels in sorted order. Then, you can use the indices as offsets from the beginning of result to get the position of that particular pixel.

UPDATE: I noticed one possible issue in your code. It looks like you assume result contains uchar data. cv::matchTemplate() requires that result contain float data.

cv::Mat_<int> indices;
cv::sortIdx(result.reshape(0,1), indices, CV_SORT_DESCENDING + CV_SORT_EVERY_ROW);

cv::Mat_<float>::const_iterator begin = result.begin<float>();
cv::Mat_<int>::const_iterator it = indices.begin();
cv::Mat_<int>::const_iterator end = indices.end();
for (; it != end; ++it)
{
    cv::Point pt = (begin + *it).pos();
    // Do something with pt...
}
Aurelius
  • 11,111
  • 3
  • 52
  • 69
  • Yes, this is what I am looking for. Unfortunately your solution is giving me a discrepancy in values compared to MinMaxLoc(). The value of MinMaxLoc()'s max and the value of your hand rolled max is is different. i.e. `Console Output: MinMax: {52, 40} handrolled: {90, 229}` – RubenSandwich Jul 31 '13 at 18:27
  • @RubenSandwich See the updated answer. `result` needs to be accessed with `float`, not `uchar`. Also, the sort order will depend on your match method. Some methods give better matches higher scores, other methods give them lower scores. – Aurelius Jul 31 '13 at 18:47
  • Replacing uchar with float did the trick. Thank you, I'm just beginning to become familiar with OpenCV and I am surprised by how great the community around it is. – RubenSandwich Jul 31 '13 at 18:52