Question

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.

Was it helpful?

Solution

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...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top