OpenCV是否为cv :: Point提供平方规范函数? [英] Does OpenCV offer a squared norm function for cv::Point?

查看:224
本文介绍了OpenCV是否为cv :: Point提供平方规范函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须对照距离阈值检查点之间的几个距离.我所能做的就是取阈值的平方,然后将其与(a-b)的平方范数进行比较,其中ab是我要检查的点.

I have to check several distances between points against a distance threshold. What I can do is taking the square of my threshold and compare it with the squared norm of (a-b), where a and b are the points I am checking.

我了解 cv::norm 函数,但是我想知道是否存在一个不计算平方根(因此更快)的版本,还是我应该手动实现它.

I know about cv::norm function, but I wonder if there exists a version that doesn't compute the square root (and therefore is faster) or if I should implement it manually.

推荐答案

OP中的说明:
我接受了这个答案,因为它是使用OpenCV可以实现的最佳方法,但我认为在这种情况下,最好的解决方案是使用自定义函数.

是的,它是NORM_L2SQR:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main()
{
    vector<Point> pts{ Point(0, 2) };

    double n = norm(pts, NORM_L2SQR);
    // n is 4

    return 0;
}

您可以在stat.cpp中的函数cv::norm中看到,如果使用NORM_L2SQR,则不会按标准计算sqrt:

You can see in the function cv::norm in stat.cpp that if you use NORM_L2SQR you don't compute the sqrt on the norm:

...
if( normType == NORM_L2 )
{
    double result = 0;
    GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1);
    return std::sqrt(result);
}
if( normType == NORM_L2SQR )
{
    double result = 0;
    GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1);
    return result;
}
...


关于特定问题:


Regarding the specific issue:

我的实际问题是:我有一个点向量,将点合并成比给定距离更近的点. 合并"是指删除一个,然后将另一半移向刚删除的点.

My actual problem is: I have a vector of points, merge points closer to each other than a given distance. "Merging" means remove one and move the other half way towards the just removed point.

您可能

  • 利用带有谓词的 partition 函数如果两个点在给定阈值内,则返回true.
  • 检索同一群集中的所有点
  • 计算每个聚类的质心
  • take advantage of the partition function with a predicate that returns true if two points are within a given threshold.
  • retrieve all points in the same cluster
  • compute the centroid for each cluster

代码在这里:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main()
{
    vector<Point> pts{ Point(0, 2), Point{ 1, 0 }, Point{ 10, 11 }, Point{11,12}, Point(2,2) };

    // Partition according to a threshold
    int th2 = 9;
    vector<int> labels;     
    int n = partition(pts, labels, [th2](const Point& lhs, const Point& rhs) { 
        return ((lhs.x - rhs.x)*(lhs.x - rhs.x) + (lhs.y - rhs.y)*(lhs.y - rhs.y)) < th2;
    });

    // Get all the points in each partition
    vector<vector<Point>> clusters(n);
    for (int i = 0; i < pts.size(); ++i)
    {
        clusters[labels[i]].push_back(pts[i]);
    }

    // Compute the centroid for each cluster
    vector<Point2f> centers;
    for (const vector<Point>& cluster : clusters)
    {
        // Compute centroid
        Point2f c(0.f,0.f);
        for (const Point& p : cluster)
        {
            c.x += p.x;
            c.y += p.y;
        }
        c.x /= cluster.size();
        c.y /= cluster.size();

        centers.push_back(c);
    }

    return 0;
}

将产生两个中心:

centers[0] : Point2f(1.0, 1.3333);
centers[1] : Point2f(10.5, 11.5)

这篇关于OpenCV是否为cv :: Point提供平方规范函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆