Paul Jurczak
Paul Jurczak

Reputation: 8127

no matching function for call to ‘normalize(cv::Point3f&)’ error

I'm getting no matching function for call to ‘normalize(cv::Point3f&)’ error in this code snippet using gcc 9.3.0 and OpenCV 4.3.0:

    cv::Point3f p{3, 0, 0}, q{0, 2, 0};
    p.cross(q);
    cv::normalize(p);

According to current documentation, both cross and normalize accept the same parameter type, which is const Vec< _Tp, cn > &. Why then call to cross compiles, but call to normalize doesn't?

EDIT

I know that cv::normalize((Vec3f)p); works. The question is why this explicit conversion to Vec3f is necessary here, but not in case of cross()?

Upvotes: 2

Views: 1259

Answers (2)

sansuiso
sansuiso

Reputation: 9379

According to the doc for 4.3.0, you need to include <opencv/core/matx.hpp>, have you tried that?

I do also understand from the doc that you need to assign the return value, the input argument is const, and you need to do that also for the cross product. So it's going o be something like:

#include <opencv/core/matx.hpp>
...
cv::Point3f p{3, 0, 0}, q{0, 2, 0};
auto normalized = cv::normalize(p.cross(q));

--EDIT-- There's also a mismatch in the type (Vec instead of Point). This last version builds fine:

cv::Vec3f p{3, 0, 0}, q{0, 2, 0};
auto normalized = cv::normalize(p.cross(q)); // Defined only for Vec_
cv::Point3f p3 = normalized; // Get back a Point3f, or continue with a Vec?

Upvotes: 1

Miki
Miki

Reputation: 41765

cv::norm(...) gives you the norm (a scalar value) of your vector. You can normalize a vector by dividing by its norm.

Given two vector p, q, you can get the normal vector as:

cv::Point3f p{3, 0, 0}, q{0, 2, 0};
cv::Point3f r = p.cross(q);
cv::Point3f rn = r / cv::norm(r);

You can also use cv::Vec3f instead of cv::Point:

cv::Vec3f p{3, 0, 0}, q{0, 2, 0};
cv::Vec3f r = p.cross(q);
cv::Vec3f rn = r / cv::norm(r);
// or
cv::Vec3f rm = cv::normalize(r);

The question is why this explicit conversion to Vec3f is necessary here

Because cv::normalized is defined for cv::Vec_<Tp, 3>, not for cv::Point3_<Tp>

template<typename _Tp, int cn> inline
Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
{
    double nv = norm(v);
    return v * (nv ? 1./nv : 0.);
}

Please note that it just divides the vector by its norm, as showed above for the cv::Point3f case.

but not in case of cross()

cross is a method of the class cv::Point3_

Also note that cv::Point3_ has an overloaded conversion operator for cv::Vec

//! conversion to cv::Vec<>
operator Vec<_Tp, 3>() const;

Upvotes: 4

Related Questions