The test code is simple:
#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;
}
It works fine. But if I change the linestd::cout << cv::norm(a - b)<< std::endl;
to std::cout << cv::norm(a, b)<< std::endl;
or std::cout << cv::norm(a - b, cv::NORM_L2)<< std::endl;
error occurs and it tells me that such function cannot be matched.
I don't understand why Point2f
type cannot be converted since the only input parameter ab
works well.
The opencv norm function given here .
Note that, sqrt( (ax-bx)*(ax-bx) + (ay-by)*(ay-by) )
is the same as saying sqrt( (a - b).x * (a - b).x + (a - b).y * (a - b).y )
, so you can call cv::norm(a - b)
.
However, according to this (albeit old) link , performance is poor for single point pairs.
I just ran the test code on my machine. It generates 15,000 points and calculates the distance from each to the remaining points.
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
Surprising. The fastest code is
float euclideanDist(cv::Point2f& a, cv::Point2f& b)
{
cv::Point2f diff = a - b;
return cv::sqrt(diff.x*diff.x + diff.y*diff.y);
}
Using cv::norm(a - b)
and the code below are nearly equal:
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));
}
But that's evidently because of the casts to double
. If left as float
, distanceBtwPoints
is as fast as eucledianDist
.
As you can read in the doc, the norm()
set of functions all operate on the generic InputArray
datatype. So, from here , you can see that this can be either a cv::Mat
or std::vector
but certainly not cv::Point2f
.
After checking in the sources (of 3.0, but I doubt it was different in 2.4 series), I see that that function has 9 overloads, but the only ones with cv::Point<>
only have one argument.
So you will need to to convert your points to cv::Mat
. This can be done easily, as there is a constructor for cv::Mat
that takes a point as argument. So just do:
std::cout << cv::norm( cv::Mat(a), cv::Mat(b) ) << std::endl;
But as a side comment, I am not sure that this is the best solution: it implies additional memory allocation, and it is probably faster to compute the distance directly (ie: sqrt( (ax-bx)*(ax-bx) + (ay-by)*(ay-by) )
. It seems harsh, but you can rely on the compiler to optimize that.
As an alternative you can use:
#include <cmath> // hypot
std::hypot((a - b).x, (a - b).y);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.