template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
-/////////////////////////// short vector (Vec) /////////////////////////////
+//////////////////////////////// Matx /////////////////////////////////
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
+
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx()
{
- for(int i = 0; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 0; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0)
{
val[0] = v0;
- for(int i = 1; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 1; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
{
- assert(cn >= 2);
+ assert(channels >= 2);
val[0] = v0; val[1] = v1;
- for(int i = 2; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 2; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
{
- assert(cn >= 3);
+ assert(channels >= 3);
val[0] = v0; val[1] = v1; val[2] = v2;
- for(int i = 3; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 3; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
{
- assert(cn >= 4);
+ assert(channels >= 4);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
- for(int i = 4; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 4; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
{
- assert(cn >= 5);
+ assert(channels >= 5);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
- for(int i = 5; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 5; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5)
{
- assert(cn >= 6);
+ assert(channels >= 6);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5;
- for(int i = 6; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 6; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6)
{
- assert(cn >= 7);
+ assert(channels >= 7);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6;
- for(int i = 7; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 7; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7)
{
- assert(cn >= 8);
+ assert(channels >= 8);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
- for(int i = 8; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 8; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8)
{
- assert(cn >= 9);
+ assert(channels >= 9);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8;
- for(int i = 9; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 9; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9)
{
- assert(cn >= 10);
+ assert(channels >= 10);
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8; val[9] = v9;
- for(int i = 10; i < cn; i++) val[i] = _Tp(0);
+ for(int i = 10; i < channels; i++) val[i] = _Tp(0);
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
+template<typename _Tp, int m, int n>
+inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11)
{
- for( int i = 0; i < cn; i++ ) val[i] = values[i];
+ assert(channels == 12);
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
}
-
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
+template<typename _Tp, int m, int n>
+inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9, _Tp v10, _Tp v11,
+ _Tp v12, _Tp v13, _Tp v14, _Tp v15)
{
- for( int i = 0; i < cn; i++ ) val[i] = v.val[i];
+ assert(channels == 16);
+ val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+ val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
+ val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
+ val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(const _Tp* values)
{
- Vec v;
- for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
- return v;
+ for( int i = 0; i < channels; i++ ) val[i] = values[i];
+}
+
+template<typename _Tp, int m, int n> inline Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
+{
+ Matx<_Tp, m, n> M;
+ for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
+ return M;
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
+{
+ return all(0);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
+{
+ return all(1);
+}
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
+{
+ Matx<_Tp,m,n> M;
+ for(int i = 0; i < MIN(m,n); i++)
+ M(i,i) = 1;
+ return M;
}
-template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::dot(const Vec<_Tp, cn>& v) const
+template<typename _Tp, int m, int n> inline _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
{
_Tp s = 0;
- for( int i = 0; i < cn; i++ ) s += val[i]*v.val[i];
+ for( int i = 0; i < m*n; i++ ) s += val[i]*M.val[i];
return s;
}
-template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, cn>& v) const
+template<typename _Tp, int m, int n> inline double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
{
double s = 0;
- for( int i = 0; i < cn; i++ ) s += (double)val[i]*v.val[i];
+ for( int i = 0; i < m*n; i++ ) s += (double)val[i]*M.val[i];
return s;
}
-
-template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
+
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Matx<_Tp,MIN(m,n),1>& d)
{
- Vec<_Tp, cn> w;
- for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(val[i]*v.val[i]);
- return w;
+ Matx<_Tp,m,n> M;
+ for(int i = 0; i < MIN(m,n); i++)
+ M(i,i) = d[i];
+ return M;
}
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
+{
+ Matx<_Tp,m,n> M;
+ Mat matM(M, false);
+ cv::randu(matM, Scalar(a), Scalar(b));
+ return M;
+}
-template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
{
- CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
- return Vec<_Tp, cn>();
+ Matx<_Tp,m,n> M;
+ Mat matM(M, false);
+ cv::randn(matM, Scalar(a), Scalar(b));
+ return M;
}
-
-template<typename _Tp, int cn> inline Matx<_Tp, 1, cn> Vec<_Tp, cn>::t() const
+template<typename _Tp, int m, int n> template<typename T2>
+inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
{
- return (const Matx<_Tp, 1, cn>&)*this;
+ Matx<T2, m, n> M;
+ for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
+ return M;
}
-
-template<typename _Tp, int cn> template<typename T2>
-inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
+
+template<typename _Tp, int m, int n> template<int m1, int n1> inline
+Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
{
- Vec<T2, cn> v;
- for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(val[i]);
- return v;
+ CV_DbgAssert(m1*n1 == m*n);
+ return (const Matx<_Tp, m1, n1>&)*this;
}
-template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
+
+template<typename _Tp, int m, int n>
+template<int m1, int n1> inline
+Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
{
- CvScalar s = {{0,0,0,0}};
- int i;
- for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = val[i];
- for( ; i < 4; i++ ) s.val[i] = 0;
+ CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
+ Matx<_Tp, m1, n1> s;
+ for( int di = 0; di < m1; di++ )
+ for( int dj = 0; dj < n1; dj++ )
+ s(di, dj) = (*this)(i+di, j+dj);
return s;
}
-template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
{
- CV_DbgAssert( (unsigned)i < (unsigned)cn );
- return val[i];
+ CV_DbgAssert((unsigned)i < (unsigned)m);
+ return Matx<_Tp, 1, n>(&val[i*n]);
}
+
-template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator [](int i)
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
{
- CV_DbgAssert( (unsigned)i < (unsigned)cn );
- return val[i];
+ CV_DbgAssert((unsigned)j < (unsigned)n);
+ Matx<_Tp, m, 1> v;
+ for( int i = 0; i < m; i++ )
+ v[i] = val[i*n + j];
+ return v;
}
-template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, MIN(m,n), 1> Matx<_Tp, m, n>::diag() const
{
- CV_DbgAssert( (unsigned)i < (unsigned)cn );
- return val[i];
+ diag_type d;
+ for( int i = 0; i < MIN(m, n); i++ )
+ d.val[i] = val[i*n + i];
+ return d;
}
-template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator ()(int i)
-{
- CV_DbgAssert( (unsigned)i < (unsigned)cn );
- return val[i];
-}
-template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
-operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
+template<typename _Tp, int m, int n> inline
+const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const
{
- for( int i = 0; i < cn; i++ )
- a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
- return a;
-}
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
+ return this->val[i*n + j];
+}
-template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
-operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
-{
- for( int i = 0; i < cn; i++ )
- a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
- return a;
-}
-template<typename _Tp, int cn> static inline Vec<_Tp, cn>
-operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
+template<typename _Tp, int m, int n> inline
+_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
{
- Vec<_Tp, cn> c = a;
- return c += b;
+ CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
+ return val[i*n + j];
}
-template<typename _Tp, int cn> static inline Vec<_Tp, cn>
-operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
+
+template<typename _Tp, int m, int n> inline
+const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
{
- Vec<_Tp, cn> c = a;
- return c -= b;
+ CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
+ return val[i];
}
-template<typename _Tp> static inline
-Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha)
+
+template<typename _Tp, int m, int n> inline
+_Tp& Matx<_Tp, m, n>::operator ()(int i)
{
- a[0] *= alpha; a[1] *= alpha;
- return a;
+ CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
+ return val[i];
}
-template<typename _Tp> static inline
-Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha)
+
+template<typename _Tp1, typename _Tp2, int m, int n> static inline
+Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
{
- a[0] *= alpha; a[1] *= alpha; a[2] *= alpha;
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
return a;
-}
+}
-template<typename _Tp> static inline
-Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha)
+
+template<typename _Tp1, typename _Tp2, int m, int n> static inline
+Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
{
- a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha;
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
return a;
-}
+}
-template<typename _Tp, int cn> static inline Vec<_Tp, cn>
-operator * (const Vec<_Tp, cn>& a, _Tp alpha)
-{
- Vec<_Tp, cn> c = a;
- return c *= alpha;
-}
-template<typename _Tp, int cn> static inline Vec<_Tp, cn>
-operator * (_Tp alpha, const Vec<_Tp, cn>& a)
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
{
- return a * alpha;
+ for( int i = 0; i < m*n; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
}
-
-template<typename _Tp> static inline Vec<_Tp, 4>
-operator * (const Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
{
- 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]));
+ for( int i = 0; i < m*n; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
}
-
-template<typename _Tp> static inline Vec<_Tp, 4>&
-operator *= (Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
+
+template<typename _Tp, int m, int n> template<typename _T2> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
{
- a = a*b;
- return a;
+ for( int i = 0; i < m*n; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
}
-
-template<typename _Tp, int cn> static inline Vec<_Tp, cn>
-operator - (const Vec<_Tp, cn>& a)
+
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
{
- Vec<_Tp,cn> t;
- for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
- return t;
+ for( int i = 0; i < m*n; i++ )
+ val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
}
-
-template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
+
+
+template<typename _Tp, int m, int n> template<int l> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
{
- return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
- val[2]*v.val[0] - val[0]*v.val[2],
- val[0]*v.val[1] - val[1]*v.val[0]);
-}
-
-template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
-{
- return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
- val[2]*v.val[0] - val[0]*v.val[2],
- val[0]*v.val[1] - val[1]*v.val[0]);
-}
-
-template<typename T1, typename T2> static inline
-Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
-{
- a[0] = saturate_cast<T1>(a[0] + b[0]);
- a[1] = saturate_cast<T1>(a[1] + b[1]);
- return a;
-}
-
-template<typename T1, typename T2> static inline
-Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
-{
- a[0] = saturate_cast<T1>(a[0] + b[0]);
- a[1] = saturate_cast<T1>(a[1] + b[1]);
- a[2] = saturate_cast<T1>(a[2] + b[2]);
- return a;
+ for( int i = 0; i < m; i++ )
+ for( int j = 0; j < n; j++ )
+ {
+ _Tp s = 0;
+ for( int k = 0; k < l; k++ )
+ s += a(i, k) * b(k, j);
+ val[i*n + j] = s;
+ }
}
-
-template<typename T1, typename T2> static inline
-Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
-{
- a[0] = saturate_cast<T1>(a[0] + b[0]);
- a[1] = saturate_cast<T1>(a[1] + b[1]);
- a[2] = saturate_cast<T1>(a[2] + b[2]);
- a[3] = saturate_cast<T1>(a[3] + b[3]);
- return a;
-}
-
-template<typename T1, int n> static inline
-double norm(const Vec<T1, n>& a)
+template<typename _Tp, int m, int n> inline
+Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
{
- double s = 0;
- for( int i = 0; i < n; i++ )
- s += (double)a.val[i]*a.val[i];
- return std::sqrt(s);
+ for( int i = 0; i < m; i++ )
+ for( int j = 0; j < n; j++ )
+ val[i*n + j] = a(j, i);
}
-template<typename T1, int n> static inline
-double norm(const Vec<T1, n>& a, int normType)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
- if( normType == NORM_INF )
- {
- T1 s = 0;
- for( int i = 0; i < n; i++ )
- s = std::max(s, std::abs(a.val[i]));
- return s;
- }
-
- if( normType == NORM_L1 )
- {
- T1 s = 0;
- for( int i = 0; i < n; i++ )
- s += std::abs(a.val[i]);
- return s;
- }
-
- CV_DbgAssert( normType == NORM_L2 );
- return norm(a);
+ return Matx<_Tp, m, n>(a, b, Matx_AddOp());
}
-template<typename T1, int n> static inline
-bool operator == (const Vec<T1, n>& a, const Vec<T1, n>& b)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
- for( int i = 0; i < n; i++ )
- if( a[i] != b[i] ) return false;
- return true;
-}
+ return Matx<_Tp, m, n>(a, b, Matx_SubOp());
+}
-template<typename T1, int n> static inline
-bool operator != (const Vec<T1, n>& a, const Vec<T1, n>& b)
+
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
{
- return !(a == b);
-}
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+}
-template<typename _Tp, typename _T2, int n> static inline
-VecCommaInitializer<_Tp, n> operator << (const Vec<_Tp, n>& vec, _T2 val)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
{
- VecCommaInitializer<_Tp, n> commaInitializer((Vec<_Tp, n>*)&vec);
- return (commaInitializer, val);
-}
-
-template<typename _Tp, int n> inline
-VecCommaInitializer<_Tp, n>::VecCommaInitializer(Vec<_Tp, n>* _vec)
- : vec(_vec), idx(0)
-{}
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+}
-template<typename _Tp, int n> template<typename _T2> inline
-VecCommaInitializer<_Tp, n>& VecCommaInitializer<_Tp, n>::operator , (_T2 value)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
{
- CV_DbgAssert( idx < n );
- vec->val[idx++] = saturate_cast<_Tp>(value);
- return *this;
-}
+ for( int i = 0; i < m*n; i++ )
+ a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
+}
-template<typename _Tp, int n> inline
-Vec<_Tp, n> VecCommaInitializer<_Tp, n>::operator *() const
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
{
- CV_DbgAssert( idx == n );
- return *vec;
-}
-
-//////////////////////////////// Matx /////////////////////////////////
-
-
-template<typename _Tp, int m, int n> Matx<_Tp,m,n>::Matx()
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0)
-: Matx<_Tp,m,n>::base_type(v0)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1)
-: Matx<_Tp,m,n>::base_type(v0, v1)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2)
-{}
-
-template<typename _Tp, int m, int n> Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4, v5)
-{}
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4, v5, v6)
-{}
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
- _Tp v4, _Tp v5, _Tp v6, _Tp v7)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4, v5, v6, v7)
-{}
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
+{
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2,
- _Tp v3, _Tp v4, _Tp v5,
- _Tp v6, _Tp v7, _Tp v8)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4, v5, v6, v7, v8)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4,
- _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
-: Matx<_Tp,m,n>::base_type(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
-{}
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
- _Tp v4, _Tp v5, _Tp v6, _Tp v7,
- _Tp v8, _Tp v9, _Tp v10, _Tp v11)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
{
- assert(m*n == 12);
- this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3;
- this->val[4] = v4; this->val[5] = v5; this->val[6] = v6; this->val[7] = v7;
- this->val[8] = v8; this->val[9] = v9; this->val[10] = v10; this->val[11] = v11;
-}
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
- _Tp v4, _Tp v5, _Tp v6, _Tp v7,
- _Tp v8, _Tp v9, _Tp v10, _Tp v11,
- _Tp v12, _Tp v13, _Tp v14, _Tp v15)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
{
- assert(m*n == 16);
- this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3;
- this->val[4] = v4; this->val[5] = v5; this->val[6] = v6; this->val[7] = v7;
- this->val[8] = v8; this->val[9] = v9; this->val[10] = v10; this->val[11] = v11;
- this->val[12] = v12; this->val[13] = v13; this->val[14] = v14; this->val[15] = v15;
-}
-
-
-template<typename _Tp, int m, int n>
-inline Matx<_Tp,m,n>::Matx(const _Tp* vals)
-: Matx<_Tp,m,n>::base_type(vals)
-{}
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-
-template<typename _Tp, int m, int n>
- inline Matx<_Tp,m,n>::Matx(const Vec<_Tp,m*n>& v)
-: base_type(v)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
{
-}
+ return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
+}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::all(_Tp alpha)
+template<typename _Tp, int m, int n> static inline
+Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
{
- base_type v = base_type::all(alpha);
- return (Matx<_Tp,m,n>&)v;
+ return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
+
+template<typename _Tp, int m, int n, int l> static inline
+Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
{
- return all(0);
+ return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
+
+template<typename _Tp> static inline
+Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
{
- return all(1);
+ return Point_<_Tp>(a*Vec<_Tp,2>(b));
}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
+
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
{
- Matx<_Tp,m,n> M;
- for(int i = 0; i < MIN(m,n); i++)
- M(i,i) = 1;
- return M;
-}
+ return Point3_<_Tp>(a*Vec<_Tp,3>(b));
+}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Vec<_Tp,MIN(m,n)>& d)
+template<typename _Tp> static inline
+Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
{
- Matx<_Tp,m,n> M;
- for(int i = 0; i < MIN(m,n); i++)
- M(i,i) = d[i];
-}
+ return Point3_<_Tp>(a*Vec<_Tp,3>(b.x, b.y, 1));
+}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
-{
- Matx<_Tp,m,n> M;
- Mat matM(M, false);
- cv::randu(matM, Scalar(a), Scalar(b));
- return M;
-}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
+template<typename _Tp> static inline
+Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
{
- Matx<_Tp,m,n> M;
- Mat matM(M, false);
- cv::randn(matM, Scalar(a), Scalar(b));
- return M;
-}
+ return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
+}
+
-template<typename _Tp, int m, int n> template<typename T2>
-inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
+template<typename _Tp> static inline
+Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
{
- Vec<T2, m*n> v = *this;
- return (Matx<T2, m, n>&)v;
-}
+ return Scalar(a*Matx<_Tp, 4, 1>(b));
+}
-template<typename _Tp, int m, int n> template<int m1, int n1> inline
-Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
{
- CV_DbgAssert(m1*n1 == m*n);
- return (const Matx<_Tp, m1, n1>&)*this;
+ return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
}
-
-template<typename _Tp, int m, int n>
-template<int m1, int n1> inline
-Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
-{
- CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
- Matx<_Tp, m1, n1> s;
- for( int di = 0; di < m1; di++ )
- for( int dj = 0; dj < n1; dj++ )
- s(di, dj) = (*this)(i+di, j+dj);
- return s;
-}
+
+CV_EXPORTS int LU(float* A, int m, float* b, int n);
+CV_EXPORTS int LU(double* A, int m, double* b, int n);
+CV_EXPORTS bool Cholesky(float* A, int m, float* b, int n);
+CV_EXPORTS bool Cholesky(double* A, int m, double* b, int n);
-template<typename _Tp, int m, int n> inline
-Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
+template<typename _Tp, int m> struct CV_EXPORTS Matx_DetOp
{
- CV_DbgAssert((unsigned)i < (unsigned)m);
- return (Matx<_Tp, 1, n>&)(*this)(i,0);
-}
-
+ double operator ()(const Matx<_Tp, m, m>& a) const
+ {
+ Matx<_Tp, m, m> temp = a;
+ double p = LU(temp.val, m, 0, 0);
+ if( p == 0 )
+ return p;
+ for( int i = 0; i < m; i++ )
+ p *= temp(i, i);
+ return p;
+ }
+};
-template<typename _Tp, int m, int n> inline
-Vec<_Tp, m> Matx<_Tp, m, n>::col(int j) const
-{
- CV_DbgAssert((unsigned)j < (unsigned)n);
- Vec<_Tp, m> v;
- for( int i = 0; i < m; i++ )
- v[i] = (*this)(i,j);
- return v;
-}
-
-template<typename _Tp, int m, int n> inline
-Vec<_Tp, MIN(m,n)> Matx<_Tp, m, n>::diag() const
+template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
{
- diag_type d;
- for( int i = 0; i < MIN(m, n); i++ )
- d[i] = (*this)(i,i);
- return d;
-}
+ double operator ()(const Matx<_Tp, 1, 1>& a) const
+ {
+ return a(0,0);
+ }
+};
-
-template<typename _Tp, int m, int n> inline
-const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const
-{
- CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
- return this->val[i*n + j];
-}
-
-template<typename _Tp, int m, int n> inline
-_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
+template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
{
- CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
- return this->val[i*n + j];
-}
+ double operator ()(const Matx<_Tp, 2, 2>& a) const
+ {
+ return a(0,0)*a(1,1) - a(0,1)*a(1,0);
+ }
+};
-template<typename _Tp, int m, int n> inline
-const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
+template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
{
- CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
- return this->val[i];
-}
-
-
-template<typename _Tp, int m, int n> inline
-_Tp& Matx<_Tp, m, n>::operator ()(int i)
+ double operator ()(const Matx<_Tp, 3, 3>& a) const
+ {
+ return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
+ a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
+ a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
+ }
+};
+
+template<typename _Tp, int m> static inline
+double determinant(const Matx<_Tp, m, m>& a)
{
- CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
- return this->val[i];
+ return Matx_DetOp<_Tp, m>()(a);
}
+
-
-template<typename _Tp1, typename _Tp2, int m, int n> static inline
-Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
+template<typename _Tp, int m, int n> static inline
+double trace(const Matx<_Tp, m, n>& a)
{
- for( int i = 0; i < m*n; i++ )
- a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
- return a;
-}
+ _Tp s = 0;
+ for( int i = 0; i < std::min(m, n); i++ )
+ s += a(i,i);
+ return s;
+}
-template<typename _Tp1, typename _Tp2, int m, int n> static inline
-Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
-{
- for( int i = 0; i < m*n; i++ )
- a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
- return a;
-}
-
-
template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
+Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
{
- for( int i = 0; i < m*n; i++ )
- this->val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
+ return Matx<_Tp, n, m>(*this, Matx_TOp());
}
-
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
-{
- for( int i = 0; i < m*n; i++ )
- this->val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
-}
-
-
-template<typename _Tp, int m, int n> template<typename _T2> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
+
+template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
{
- for( int i = 0; i < m*n; i++ )
- this->val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
-}
-
+ bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
+ {
+ Matx<_Tp, m, m> temp = a;
+
+ // assume that b is all 0's on input => make it a unity matrix
+ for( int i = 0; i < m; i++ )
+ b(i, i) = (_Tp)1;
+
+ if( method == DECOMP_CHOLESKY )
+ return Cholesky(temp.val, m, b.val, m);
+
+ return LU(temp.val, m, b.val, m) != 0;
+ }
+};
+
-template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
+template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
{
- for( int i = 0; i < m*n; i++ )
- this->val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
-}
-
+ bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ b(1,1) = a(0,0)*d;
+ b(0,0) = a(1,1)*d;
+ b(0,1) = -a(0,1)*d;
+ b(1,0) = -a(1,0)*d;
+ return true;
+ }
+};
+
-template<typename _Tp, int m, int n> template<int l> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
+template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
{
- for( int i = 0; i < m; i++ )
- for( int j = 0; j < n; j++ )
- {
- _Tp s = 0;
- for( int k = 0; k < l; k++ )
- s += a(i, k) * b(k, j);
- this->val[i*n + j] = s;
- }
-}
-
+ bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
+ b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
+ b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
+
+ b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
+ b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
+ b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
+
+ b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
+ b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
+ b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
+ return true;
+ }
+};
+
template<typename _Tp, int m, int n> inline
-Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
+Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const
{
- for( int i = 0; i < m; i++ )
- for( int j = 0; j < n; j++ )
- this->val[i*n + j] = a(j, i);
+ Matx<_Tp, n, m> b;
+ bool ok;
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
+ ok = Matx_FastInvOp<_Tp, m>()(*this, b, method);
+ else
+ {
+ Mat A(*this, false), B(b, false);
+ ok = invert(A, B, method);
+ }
+ return ok ? b : Matx<_Tp, n, m>::zeros();
}
-
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+
+template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
{
- return Matx<_Tp, m, n>(a, b, Matx_AddOp());
-}
-
-
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
+ bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
+ Matx<_Tp, m, n>& x, int method) const
+ {
+ Matx<_Tp, m, m> temp = a;
+ x = b;
+ if( method == DECOMP_CHOLESKY )
+ return Cholesky(temp.val, m, x.val, n);
+
+ return LU(temp.val, m, x.val, n) != 0;
+ }
+};
+
+
+template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
{
- return Matx<_Tp, m, n>(a, b, Matx_SubOp());
-}
-
+ bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
+ Matx<_Tp, 2, 1>& x, int method) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
+ x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
+ return true;
+ }
+};
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
+
+template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
{
- for( int i = 0; i < m*n; i++ )
- a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
-}
+ bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
+ Matx<_Tp, 3, 1>& x, int method) const
+ {
+ _Tp d = determinant(a);
+ if( d == 0 )
+ return false;
+ d = 1/d;
+ x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
+ a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
+ a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
+
+ x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
+ b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
+ a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
+
+ x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
+ a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
+ b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
+ return true;
+ }
+};
+
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
+template<typename _Tp, int m, int n> template<int l> inline
+Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
{
- for( int i = 0; i < m*n; i++ )
- a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
-}
+ Matx<_Tp, n, l> x;
+ bool ok;
+ if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
+ ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
+ else
+ {
+ Mat A(*this, false), B(rhs, false), X(x, false);
+ ok = cv::solve(A, B, X, method);
+ }
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
-{
- for( int i = 0; i < m*n; i++ )
- a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
-}
+ return ok ? x : Matx<_Tp, n, l>::zeros();
+}
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
-{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
+double norm(const Matx<_Tp, m, n>& M)
{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
+ double s = 0;
+ for( int i = 0; i < m*n; i++ )
+ s += (double)M.val[i]*M.val[i];
+ return std::sqrt(s);
+}
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
-{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
-{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
-
-template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
+double norm(const Matx<_Tp, m, n>& M, int normType)
{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
-
+ if( normType == NORM_INF )
+ {
+ T1 s = 0;
+ for( int i = 0; i < m*n; i++ )
+ s = std::max(s, std::abs(M.val[i]));
+ return s;
+ }
+
+ if( normType == NORM_L1 )
+ {
+ T1 s = 0;
+ for( int i = 0; i < m*n; i++ )
+ s += std::abs(M.val[i]);
+ return s;
+ }
+
+ CV_DbgAssert( normType == NORM_L2 );
+ return norm(M);
+}
+
+
template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
+bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
- return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
-}
+ for( int i = 0; i < m*n; i++ )
+ if( a[i] != b[i] ) return false;
+ return true;
+}
template<typename _Tp, int m, int n> static inline
-Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
+bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
- return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
+ return !(a == b);
}
-template<typename _Tp, int m, int n, int l> static inline
-Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
+template<typename _Tp, typename _T2, int m, int n> static inline
+MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
{
- return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
+ MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
+ return (commaInitializer, val);
}
-
-template<typename _Tp, int m, int n> static inline
-Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b)
-{
- return Matx<_Tp, m, 1>(a, (const Matx<_Tp, n, 1>&)b, Matx_MatMulOp());
-}
+template<typename _Tp, int m, int n> inline
+MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
+ : dst(_mtx), idx(0)
+{}
-
-template<typename _Tp> static inline
-Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
+template<typename _Tp, int m, int n> template<typename _T2> inline
+MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
{
- return Point_<_Tp>(a*Vec<_Tp,2>(b));
+ CV_DbgAssert( idx < m*n );
+ dst->val[idx++] = saturate_cast<_Tp>(value);
+ return *this;
}
-
-template<typename _Tp> static inline
-Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
+template<typename _Tp, int m, int n> inline
+Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
{
- return Point3_<_Tp>(a*Vec<_Tp,3>(b));
+ CV_DbgAssert( idx == n*m );
+ return *dst;
}
+/////////////////////////// short vector (Vec) /////////////////////////////
-template<typename _Tp> 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<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
+ : Matx<_Tp, cn, 1>(v0)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
+ : Matx<_Tp, cn, 1>(v0, v1)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
+ : Matx<_Tp, cn, 1>(v0, v1, v2)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8)
+{}
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
+ _Tp v4, _Tp v5, _Tp v6, _Tp v7,
+ _Tp v8, _Tp v9)
+ : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
+{}
-template<typename _Tp> static inline
-Vec<_Tp, 4> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
+ : Matx<_Tp, cn, 1>(values)
+{}
+
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
+ : Matx<_Tp, cn, 1>(v.val)
+{}
+
+template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
{
- return a*Vec<_Tp,4>(b.x, b.y, b.z, 1);
-}
+ Vec v;
+ for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
+ return v;
+}
-
-template<typename _Tp> static inline
-Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
+template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
{
- return Scalar(a*Vec<_Tp,4>(b));
-}
+ 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<typename _Tp, int m, int n> inline
-Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
+template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
{
- return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
+ CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
+ return Vec<_Tp, cn>();
}
-
-CV_EXPORTS int LU(float* A, int m, float* b, int n);
-CV_EXPORTS int LU(double* A, int m, double* b, int n);
-CV_EXPORTS bool Cholesky(float* A, int m, float* b, int n);
-CV_EXPORTS bool Cholesky(double* A, int m, double* b, int n);
+template<typename _Tp, int cn> template<typename T2>
+inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
+{
+ Vec<T2, cn> v;
+ for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(val[i]);
+ return v;
+}
+template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
+{
+ CvScalar s = {{0,0,0,0}};
+ int i;
+ for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = val[i];
+ for( ; i < 4; i++ ) s.val[i] = 0;
+ return s;
+}
-template<typename _Tp, int m> struct CV_EXPORTS Matx_DetOp
+template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
{
- double operator ()(const Matx<_Tp, m, m>& a) const
- {
- Matx<_Tp, m, m> temp = a;
- double p = LU(temp.val, m, 0, 0);
- if( p == 0 )
- return p;
- for( int i = 0; i < m; i++ )
- p *= temp(i, i);
- return p;
- }
-};
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return val[i];
+}
-
-template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
+template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator [](int i)
{
- double operator ()(const Matx<_Tp, 1, 1>& a) const
- {
- return a(0,0);
- }
-};
-
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return val[i];
+}
-template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
+template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
{
- double operator ()(const Matx<_Tp, 2, 2>& a) const
- {
- return a(0,0)*a(1,1) - a(0,1)*a(1,0);
- }
-};
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return val[i];
+}
+template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator ()(int i)
+{
+ CV_DbgAssert( (unsigned)i < (unsigned)cn );
+ return val[i];
+}
+
+template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
+operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
+{
+ for( int i = 0; i < cn; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
+ return a;
+}
-template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
+template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
+operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
{
- double operator ()(const Matx<_Tp, 3, 3>& a) const
- {
- return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
- a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
- a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
- }
-};
+ for( int i = 0; i < cn; i++ )
+ a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
+ return a;
+}
-template<typename _Tp, int m> static inline
-double determinant(const Matx<_Tp, m, m>& a)
+template<typename _Tp, int cn> static inline Vec<_Tp, cn>
+operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
{
- return Matx_DetOp<_Tp, m>()(a);
+ Vec<_Tp, cn> c = a;
+ return c += b;
}
-
-template<typename _Tp, int m, int n> static inline
-double trace(const Matx<_Tp, m, n>& a)
+template<typename _Tp, int cn> static inline Vec<_Tp, cn>
+operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
{
- _Tp s = 0;
- for( int i = 0; i < std::min(m, n); i++ )
- s += a(i,i);
- return s;
-}
+ Vec<_Tp, cn> c = a;
+ return c -= b;
+}
-
-template<typename _Tp, int m, int n> inline
-Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
+template<typename _Tp> static inline
+Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha)
{
- return Matx<_Tp, n, m>(*this, Matx_TOp());
+ a[0] *= alpha; a[1] *= alpha;
+ return a;
}
+template<typename _Tp> static inline
+Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha)
+{
+ a[0] *= alpha; a[1] *= alpha; a[2] *= alpha;
+ return a;
+}
-template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
+template<typename _Tp> static inline
+Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha)
{
- bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
- {
- Matx<_Tp, m, m> temp = a;
-
- // assume that b is all 0's on input => make it a unity matrix
- for( int i = 0; i < m; i++ )
- b(i, i) = (_Tp)1;
-
- if( method == DECOMP_CHOLESKY )
- return Cholesky(temp.val, m, b.val, m);
-
- return LU(temp.val, m, b.val, m) != 0;
- }
-};
+ a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha;
+ return a;
+}
-
-template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
+template<typename _Tp, int cn> static inline Vec<_Tp, cn>
+operator * (const Vec<_Tp, cn>& a, _Tp alpha)
{
- bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
- {
- _Tp d = determinant(a);
- if( d == 0 )
- return false;
- d = 1/d;
- b(1,1) = a(0,0)*d;
- b(0,0) = a(1,1)*d;
- b(0,1) = -a(0,1)*d;
- b(1,0) = -a(1,0)*d;
- return true;
- }
-};
+ Vec<_Tp, cn> c = a;
+ return c *= alpha;
+}
+template<typename _Tp, int cn> static inline Vec<_Tp, cn>
+operator * (_Tp alpha, const Vec<_Tp, cn>& a)
+{
+ return a * alpha;
+}
-template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
+
+template<typename _Tp> static inline Vec<_Tp, 4>
+operator * (const Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
{
- bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
- {
- _Tp d = determinant(a);
- if( d == 0 )
- return false;
- d = 1/d;
- b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
- b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
- b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
-
- b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
- b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
- b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
-
- b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
- b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
- b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
- return true;
- }
-};
+ 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<typename _Tp, int m, int n> inline
-Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const
+template<typename _Tp> static inline Vec<_Tp, 4>&
+operator *= (Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
{
- Matx<_Tp, n, m> b;
- bool ok;
- if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
- ok = Matx_FastInvOp<_Tp, m>()(*this, b, method);
- else
- {
- Mat A(*this, false), B(b, false);
- ok = invert(A, B, method);
- }
- return ok ? b : Matx<_Tp, n, m>::zeros();
+ a = a*b;
+ return a;
}
+
-
-template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
+template<typename _Tp, int cn> static inline Vec<_Tp, cn>
+operator - (const Vec<_Tp, cn>& a)
{
- bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
- Matx<_Tp, m, n>& x, int method) const
- {
- Matx<_Tp, m, m> temp = a;
- x = b;
- if( method == DECOMP_CHOLESKY )
- return Cholesky(temp.val, m, x.val, n);
-
- return LU(temp.val, m, x.val, n) != 0;
- }
-};
-
+ Vec<_Tp,cn> t;
+ for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
+ return t;
+}
-template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
+template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
{
- bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
- Matx<_Tp, 2, 1>& x, int method) const
- {
- _Tp d = determinant(a);
- if( d == 0 )
- return false;
- d = 1/d;
- x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
- x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
- return true;
- }
-};
+ return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
+ val[2]*v.val[0] - val[0]*v.val[2],
+ val[0]*v.val[1] - val[1]*v.val[0]);
+}
-
-template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
+template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
{
- bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
- Matx<_Tp, 3, 1>& x, int method) const
- {
- _Tp d = determinant(a);
- if( d == 0 )
- return false;
- d = 1/d;
- x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
- a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
- a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
-
- x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
- b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
- a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
-
- x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
- a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
- b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
- return true;
- }
-};
-
-
-template<typename _Tp, int m, int n> template<int l> inline
-Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
+ return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
+ val[2]*v.val[0] - val[0]*v.val[2],
+ val[0]*v.val[1] - val[1]*v.val[0]);
+}
+
+template<typename T1, typename T2> static inline
+Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
{
- Matx<_Tp, n, l> x;
- bool ok;
- if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
- ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
- else
- {
- Mat A(*this, false), B(rhs, false), X(x, false);
- ok = cv::solve(A, B, X, method);
- }
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
+ return a;
+}
- return ok ? x : Matx<_Tp, n, l>::zeros();
+template<typename T1, typename T2> static inline
+Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
+{
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
+ a[2] = saturate_cast<T1>(a[2] + b[2]);
+ return a;
}
-
-template<typename _Tp, int m, int n> inline
-Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const
+
+template<typename T1, typename T2> static inline
+Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
{
- return solve(Matx<_Tp, m, 1>(rhs), method);
+ a[0] = saturate_cast<T1>(a[0] + b[0]);
+ a[1] = saturate_cast<T1>(a[1] + b[1]);
+ a[2] = saturate_cast<T1>(a[2] + b[2]);
+ a[3] = saturate_cast<T1>(a[3] + b[3]);
+ return a;
}
-
-template<typename _Tp, typename _T2, int m, int n> static inline
-MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
+
+
+template<typename _Tp, typename _T2, int cn> static inline
+VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
{
- MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
+ VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
return (commaInitializer, val);
}
-
-template<typename _Tp, int m, int n> inline
-MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
- : VecCommaInitializer<_Tp, m*n>((Vec<_Tp,m*n>*)_mtx)
+
+template<typename _Tp, int cn> inline
+VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
+ : MatxCommaInitializer(_vec)
{}
-template<typename _Tp, int m, int n> template<typename _T2> inline
-MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
+template<typename _Tp, int cn> template<typename _T2> inline
+VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
{
- return (MatxCommaInitializer<_Tp, m, n>&)VecCommaInitializer<_Tp, m*n>::operator ,(value);
+ CV_DbgAssert( idx < cn );
+ vec->val[idx++] = saturate_cast<_Tp>(value);
+ return *this;
}
-template<typename _Tp, int m, int n> inline
-Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
+template<typename _Tp, int cn> inline
+Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
{
- CV_DbgAssert( this->idx == n*m );
- return (Matx<_Tp, m, n>&)*(this->vec);
+ CV_DbgAssert( this->idx == cn );
+ return *vec;
}
//////////////////////////////// Complex //////////////////////////////
a.val[2] != b.val[2] || a.val[3] != b.val[3];
}
-template<typename _Tp> template<typename T2> inline void Scalar_<_Tp>::convertTo(T2* buf, int cn, int unroll_to) const
-{
- int i;
- CV_Assert(cn <= 4);
- for( i = 0; i < cn; i++ )
- buf[i] = saturate_cast<T2>(this->val[i]);
- for( ; i < unroll_to; i++ )
- buf[i] = buf[i-cn];
-}
-
-static inline void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0)
-{
- int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
- switch(depth)
- {
- case CV_8U:
- s.convertTo((uchar*)buf, cn, unroll_to);
- break;
- case CV_8S:
- s.convertTo((schar*)buf, cn, unroll_to);
- break;
- case CV_16U:
- s.convertTo((ushort*)buf, cn, unroll_to);
- break;
- case CV_16S:
- s.convertTo((short*)buf, cn, unroll_to);
- break;
- case CV_32S:
- s.convertTo((int*)buf, cn, unroll_to);
- break;
- case CV_32F:
- s.convertTo((float*)buf, cn, unroll_to);
- break;
- case CV_64F:
- s.convertTo((double*)buf, cn, unroll_to);
- break;
- default:
- CV_Error(CV_StsUnsupportedFormat,"");
- }
-}
-
-
template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
{
return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]),