使用opencv范数函数获得两点的欧几里得距离

新手上路,请多包涵

测试代码很简单:

 #include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
        cv::Point2f a(0.f, 1.f);
        cv::Point2f b(3.f, 5.f);
        std::cout << cv::norm(a - b)<< std::endl;
        return 0;
}

它工作正常。但是如果我换行

std::cout << cv::norm(a - b)<< std::endl;

std::cout << cv::norm(a, b)<< std::endl;

std::cout << cv::norm(a - b, cv::NORM_L2)<< std::endl;

发生错误,它告诉我这样的功能无法匹配。

我不明白为什么不能转换 Point2f 类型,因为唯一的输入参数 a-b 效果很好。

这里 给出的 opencv 范数函数。

原文由 Daniel 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

正如您在文档中看到的那样, norm() 函数集都在通用 InputArray 数据类型上运行。因此,从 这里,您可以看到这可以是 cv::Matstd::vector 但肯定不是 cv::Point2f

在检查了源代码(3.0,但我怀疑它在 2.4 系列中有所不同)后,我看到该函数有 9 个重载,但唯一的 cv::Point<> 只有一个参数。

因此,您需要将您的积分转换为 cv::Mat 。这可以很容易地完成,因为有一个 cv::Mat 的构造函数,它将一个点作为参数。所以就这样做:

 std::cout << cv::norm( cv::Mat(a), cv::Mat(b) ) << std::endl;

但作为旁注,我不确定这是最好的解决方案:它意味着额外的内存分配,并且直接计算距离可能更快(即: sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ) 。看起来很苛刻,但你可以依靠编译器来优化它。

原文由 kebs 发布,翻译遵循 CC BY-SA 3.0 许可协议

请注意, sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) )sqrt( (a - b).x * (a - b).x + (a - b).y * (a - b).y ) 相同,因此您可以调用 cv::norm(a - b)

但是,根据这个(虽然是旧的) 链接,单点对的性能很差。

我刚刚在我的机器上运行了 测试代码。它生成 15,000 个点并计算每个点到其余点的距离。

 a : [0, 0] - b : [2.14748e+09, 2.14748e+09]

euclideanDist : 3.037e+09
distanceBtwPoints : 3.037e+09
cv::norm : 3.037e+09

max_distance euclideanDist : 3.02456e+09 time passed :0.165179
max_distance distanceBtwPoints : 3.02456e+09 time passed :0.259471
max_distance cv::norm : 3.02456e+09 time passed :0.26728

奇怪。最快的代码是

float euclideanDist(cv::Point2f& a, cv::Point2f& b)
{
    cv::Point2f diff = a - b;
    return cv::sqrt(diff.x*diff.x + diff.y*diff.y);
}

使用 cv::norm(a - b) 和下面的代码几乎相等:

 static double distanceBtwPoints(const cv::Point2f &a, const cv::Point2f &b)
{
    double xDiff = a.x - b.x;
    double yDiff = a.y - b.y;

    return std::sqrt((xDiff * xDiff) + (yDiff * yDiff));
}

但这显然是因为 double 的演员表。如果保留为 floatdistanceBtwPointseucledianDist 一样快。

原文由 darda 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题