From 796553d05147b75b9b959c213922d193fd3032d9 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 7 Jul 2010 15:25:42 +0000 Subject: [PATCH] added some quaternion operations on Scalar's. --- modules/core/include/opencv2/core/core.hpp | 5 + .../core/include/opencv2/core/operations.hpp | 137 ++++++++++++++++++ modules/features2d/src/detectors.cpp | 2 +- 3 files changed, 143 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 5e39e8305d..1d7373820a 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -448,6 +448,9 @@ public: _Tp dot(const Vec& v) const; //! dot product computed in double-precision arithmetics double ddot(const Vec& v) const; + //! per-element multiplication + Vec mul(const Vec<_Tp, cn>& v) const; + /*! cross product of the two 3D vectors. @@ -924,6 +927,8 @@ public: Scalar_<_Tp> mul(const Scalar_<_Tp>& t, double scale=1 ) const; //! another helper conversion method. \see cvScalarToRawData template void convertTo(T2* buf, int channels, int unroll_to=0) const; + + Scalar_<_Tp> conj() const; }; typedef Scalar_ Scalar; diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 798b173f3e..75afeb1481 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -321,6 +321,14 @@ template inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, c } +template inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const +{ + Vec<_Tp, cn> w; + for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(val[i]*v.val[i]); + return w; +} + + template inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const { CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined"); @@ -438,6 +446,25 @@ operator * (_Tp alpha, const Vec<_Tp, cn>& a) { return a * alpha; } + + +template static inline Vec<_Tp, 4> +operator * (const Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b) +{ + return Vec<_Tp, 4>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]), + saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]), + saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]), + saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0])); +} + + +template static inline Vec<_Tp, 4>& +operator *= (Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b) +{ + a = a*b; + return a; +} + template static inline Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) @@ -971,6 +998,41 @@ Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) } +template static inline +Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b) +{ + return Point_<_Tp>(a*Vec<_Tp,2>(b)); +} + + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>(a*Vec<_Tp,3>(b)); +} + + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b) +{ + return Point3_<_Tp>(a*Vec<_Tp,3>(b.x, b.y, 1)); +} + + +template static inline +Vec<_Tp, 4> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b) +{ + return a*Vec<_Tp,4>(b.x, b.y, b.z, 1); +} + + +template static inline +Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b) +{ + return Scalar(a*Vec<_Tp,4>(b)); +} + + template inline Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const { @@ -1909,6 +1971,81 @@ template static inline Scalar_<_Tp> operator - (const Scalar_<_Tp> saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3])); } + +template static inline Scalar_<_Tp> +operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]), + saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]), + saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]), + saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0])); +} + +template static inline Scalar_<_Tp>& +operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a*b; + return a; +} + +template inline Scalar_<_Tp> Scalar_<_Tp>::conj() const +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0]), + saturate_cast<_Tp>(-this->val[1]), + saturate_cast<_Tp>(-this->val[2]), + saturate_cast<_Tp>(-this->val[3])); +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] / alpha), + saturate_cast<_Tp>(a.val[1] / alpha), + saturate_cast<_Tp>(a.val[2] / alpha), + saturate_cast<_Tp>(a.val[3] / alpha)); +} + +template<> static inline +Scalar_ operator / (const Scalar_& a, float alpha) +{ + float s = 1/alpha; + return Scalar_(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s); +} + +template<> static inline +Scalar_ operator / (const Scalar_& a, double alpha) +{ + double s = 1/alpha; + return Scalar_(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha) +{ + a = a/alpha; + return a; +} + +template static inline +Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b) +{ + _Tp s = a/(b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]); + return b.conj()*s; +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return a*((_Tp)1/b); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a/b; + return a; +} + //////////////////////////////// Range ///////////////////////////////// inline Range::Range() : start(0), end(0) {} diff --git a/modules/features2d/src/detectors.cpp b/modules/features2d/src/detectors.cpp index 8857c80d11..4ffd41053e 100644 --- a/modules/features2d/src/detectors.cpp +++ b/modules/features2d/src/detectors.cpp @@ -52,7 +52,7 @@ struct MaskPredicate { MaskPredicate( const Mat& _mask ) : mask(_mask) {} - MaskPredicate& operator=(const MaskPredicate&) {} + MaskPredicate& operator=(const MaskPredicate&) { return *this; } bool operator() (const KeyPoint& key_pt) const { return mask.at( (int)(key_pt.pt.y + 0.5f), (int)(key_pt.pt.x + 0.5f) ) == 0;