【问题标题】:Iterate through cv::Points contained in a cv::Mat遍历 cv::Mat 中包含的 cv::Points
【发布时间】:2013-07-31 16:05:18
【问题描述】:

我正在使用 OpenCV 模板匹配在另一个图像中查找图像。

特别是matchTemplate(),它返回一个包含匹配相似图的cv::Mat

除了使用minMaxLoc()之外,还有什么方法可以对cv::Mat中包含的cv::Points进行排序?

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

我试过了:

    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());
    }

成功有限。

【问题讨论】:

  • 你想要达到的结果是什么?积分应该如何排序?
  • 我希望将这些点与基线进行比较,以获得模板匹配的置信度。我正在尝试迭代从最佳匹配到更差匹配的点。

标签: c++ loops opencv template-matching


【解决方案1】:

如果我理解正确,您希望按匹配分数对像素进行排序,然后按排序顺序获取与这些像素对应的点。您可以通过将result 重塑为单行,然后调用cv::sortIdx() 以按排序顺序获取像素的索引来完成此操作。然后,您可以使用索引作为从 result 开头的偏移量来获取该特定像素的位置。

更新:我注意到您的代码中可能存在一个问题。看起来您假设 result 包含 uchar 数据。 cv::matchTemplate() 要求 result 包含 float 数据。

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...
}

【讨论】:

  • 是的,这就是我要找的。不幸的是,与 MinMaxLoc() 相比,您的解决方案给了我一个值差异。 MinMaxLoc() 的最大值和你的手卷最大值是不同的。即Console Output: MinMax: {52, 40} handrolled: {90, 229}
  • @RubenSandwich 查看更新的答案。 result 需要使用float 访问,而不是uchar。此外,排序顺序将取决于您的匹配方法。一些方法给更好的匹配更高的分数,其他方法给他们更低的分数。
  • 用 float 替换 uchar 就可以了。谢谢,我刚刚开始熟悉 OpenCV,我对它周围的社区如此之大感到惊讶。
猜你喜欢
  • 2018-06-10
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多