added "small matrix" class Matx<T, m, n>

This commit is contained in:
Vadim Pisarevsky 2010-06-29 14:52:43 +00:00
parent bed63cc7c2
commit 10b5a51731
7 changed files with 1180 additions and 91 deletions

View File

@ -78,15 +78,51 @@ using std::string;
template<typename _Tp> class CV_EXPORTS Size_; template<typename _Tp> class CV_EXPORTS Size_;
template<typename _Tp> class CV_EXPORTS Point_; template<typename _Tp> class CV_EXPORTS Point_;
template<typename _Tp> class CV_EXPORTS Rect_; template<typename _Tp> class CV_EXPORTS Rect_;
template<typename _Tp, int cn> class CV_EXPORTS Vec;
template<typename _Tp, int m, int n> class CV_EXPORTS Matx;
typedef std::string String; typedef std::string String;
typedef std::basic_string<wchar_t> WString; typedef std::basic_string<wchar_t> WString;
class Mat;
class MatND;
template<typename M> class CV_EXPORTS MatExpr_Base_;
typedef MatExpr_Base_<Mat> MatExpr_Base;
template<typename E, typename M> class MatExpr_;
template<typename A1, typename M, typename Op> class MatExpr_Op1_;
template<typename A1, typename A2, typename M, typename Op> class MatExpr_Op2_;
template<typename A1, typename A2, typename A3, typename M, typename Op> class MatExpr_Op3_;
template<typename A1, typename A2, typename A3, typename A4,
typename M, typename Op> class MatExpr_Op4_;
template<typename A1, typename A2, typename A3, typename A4,
typename A5, typename M, typename Op> class MatExpr_Op5_;
template<typename M> class CV_EXPORTS MatOp_DivRS_;
template<typename M> class CV_EXPORTS MatOp_Inv_;
template<typename M> class CV_EXPORTS MatOp_MulDiv_;
template<typename M> class CV_EXPORTS MatOp_Repeat_;
template<typename M> class CV_EXPORTS MatOp_Set_;
template<typename M> class CV_EXPORTS MatOp_Scale_;
template<typename M> class CV_EXPORTS MatOp_T_;
template<typename _Tp> class CV_EXPORTS MatIterator_;
template<typename _Tp> class CV_EXPORTS MatConstIterator_;
template<typename _Tp> class CV_EXPORTS MatCommaInitializer_;
CV_EXPORTS string fromUtf16(const WString& str); CV_EXPORTS string fromUtf16(const WString& str);
CV_EXPORTS WString toUtf16(const string& str); CV_EXPORTS WString toUtf16(const string& str);
CV_EXPORTS string format( const char* fmt, ... ); CV_EXPORTS string format( const char* fmt, ... );
// matrix decomposition types
enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 };
enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_TYPE_MASK=7, NORM_RELATIVE=8, NORM_MINMAX=32};
enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 };
enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 };
enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32,
DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS };
/*! /*!
The standard OpenCV exception class. The standard OpenCV exception class.
Instances of the class are thrown by various functions and methods in the case of critical errors. Instances of the class are thrown by various functions and methods in the case of critical errors.
@ -404,6 +440,7 @@ public:
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
explicit Vec(const _Tp* values);
Vec(const Vec<_Tp, cn>& v); Vec(const Vec<_Tp, cn>& v);
static Vec all(_Tp alpha); static Vec all(_Tp alpha);
@ -422,9 +459,13 @@ public:
//! conversion to 4-element CvScalar. //! conversion to 4-element CvScalar.
operator CvScalar() const; operator CvScalar() const;
Matx<_Tp, 1, cn> t() const;
/*! element access */ /*! element access */
const _Tp& operator [](int i) const; const _Tp& operator [](int i) const;
_Tp& operator[](int i); _Tp& operator[](int i);
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
_Tp val[cn]; //< vector elements _Tp val[cn]; //< vector elements
}; };
@ -461,6 +502,158 @@ typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d; typedef Vec<double, 6> Vec6d;
////////////////////////////// Small Matrix ///////////////////////////
/*!
A short numerical vector.
This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
which elements are dynamically allocated in the heap.
The template takes 2 parameters:
-# _Tp element type
-# cn the number of elements
In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
*/
struct CV_EXPORTS Matx_AddOp {};
struct CV_EXPORTS Matx_SubOp {};
struct CV_EXPORTS Matx_ScaleOp {};
struct CV_EXPORTS Matx_MulOp {};
struct CV_EXPORTS Matx_MatMulOp {};
struct CV_EXPORTS Matx_TOp {};
template<typename _Tp, int m, int n> class CV_EXPORTS Matx : public Vec<_Tp, m*n>
{
public:
typedef _Tp value_type;
typedef Vec<_Tp, m*n> base_type;
typedef Vec<_Tp, MIN(m, n)> diag_type;
typedef Matx<_Tp, m, n> mat_type;
enum { depth = DataDepth<_Tp>::value, rows = m, cols = n, channels = rows*cols,
type = CV_MAKETYPE(depth, channels) };
//! default constructor
Matx();
Matx(_Tp v0); //!< 1x1 matrix
Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
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); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
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); //!< 1x16, 4x4 or 16x1 matrix
explicit Matx(const _Tp* vals); //!< initialize from a plain array
Matx(const base_type& v);
static Matx all(_Tp alpha);
static Matx zeros();
static Matx ones();
static Matx eye();
static Matx diag(const Vec<_Tp, MIN(m,n)>& d);
static Matx randu(_Tp a, _Tp b);
static Matx randn(_Tp m, _Tp sigma);
//! convertion to another data type
template<typename T2> operator Matx<T2, m, n>() const;
//! change the matrix shape
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
//! extract part of the matrix
template<int m1, int n1> Matx<_Tp, m1, n1> minor(int i, int j) const;
//! extract the matrix row
Matx<_Tp, 1, n> row(int i) const;
//! extract the matrix column
Vec<_Tp, m> col(int i) const;
//! extract the matrix diagonal
Vec<_Tp, MIN(m,n)> diag() const;
//! transpose the matrix
Matx<_Tp, n, m> t() const;
//! invert matrix the matrix
Matx<_Tp, n, m> inv(int method=DECOMP_LU) const;
//! solve linear system
template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
//! multiply two matrices element-wise
Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
//! element access
const _Tp& operator ()(int i, int j) const;
_Tp& operator ()(int i, int j);
//! 1D element access
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
};
typedef Matx<float, 1, 2> Matx12f;
typedef Matx<double, 1, 2> Matx12d;
typedef Matx<float, 1, 3> Matx13f;
typedef Matx<double, 1, 3> Matx13d;
typedef Matx<float, 1, 4> Matx14f;
typedef Matx<double, 1, 4> Matx14d;
typedef Matx<float, 1, 6> Matx16f;
typedef Matx<double, 1, 6> Matx16d;
typedef Matx<float, 2, 1> Matx21f;
typedef Matx<double, 2, 1> Matx21d;
typedef Matx<float, 3, 1> Matx31f;
typedef Matx<double, 3, 1> Matx31d;
typedef Matx<float, 4, 1> Matx41f;
typedef Matx<double, 4, 1> Matx41d;
typedef Matx<float, 6, 1> Matx61f;
typedef Matx<double, 6, 1> Matx61d;
typedef Matx<float, 2, 2> Matx22f;
typedef Matx<double, 2, 2> Matx22d;
typedef Matx<float, 2, 3> Matx23f;
typedef Matx<double, 2, 3> Matx23d;
typedef Matx<float, 3, 2> Matx32f;
typedef Matx<double, 3, 2> Matx32d;
typedef Matx<float, 3, 3> Matx33f;
typedef Matx<double, 3, 3> Matx33d;
typedef Matx<float, 3, 4> Matx34f;
typedef Matx<double, 3, 4> Matx34d;
typedef Matx<float, 4, 3> Matx43f;
typedef Matx<double, 4, 3> Matx43d;
typedef Matx<float, 4, 4> Matx44f;
typedef Matx<double, 4, 4> Matx44d;
typedef Matx<float, 6, 6> Matx66f;
typedef Matx<double, 6, 6> Matx66d;
//////////////////////////////// Complex ////////////////////////////// //////////////////////////////// Complex //////////////////////////////
/*! /*!
@ -767,7 +960,7 @@ public:
is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented
by the depth id (CV_8U ... CV_64F) and the number of channels. by the depth id (CV_8U ... CV_64F) and the number of channels.
OpenCV matrices, 2D or nD, dense or sparse, can store "scalars", OpenCV matrices, 2D or nD, dense or sparse, can store "scalars",
as long as the number of channels does not exceed CV_MAX_CN (currently set to 32). as long as the number of channels does not exceed CV_CN_MAX.
*/ */
template<typename _Tp> class DataType template<typename _Tp> class DataType
{ {
@ -1046,45 +1239,13 @@ protected:
//////////////////////////////// Mat //////////////////////////////// //////////////////////////////// Mat ////////////////////////////////
class Mat;
class MatND;
template<typename M> class CV_EXPORTS MatExpr_Base_;
typedef MatExpr_Base_<Mat> MatExpr_Base;
template<typename E, typename M> class MatExpr_;
template<typename A1, typename M, typename Op> class MatExpr_Op1_;
template<typename A1, typename A2, typename M, typename Op> class MatExpr_Op2_;
template<typename A1, typename A2, typename A3, typename M, typename Op> class MatExpr_Op3_;
template<typename A1, typename A2, typename A3, typename A4,
typename M, typename Op> class MatExpr_Op4_;
template<typename A1, typename A2, typename A3, typename A4,
typename A5, typename M, typename Op> class MatExpr_Op5_;
template<typename M> class CV_EXPORTS MatOp_DivRS_;
template<typename M> class CV_EXPORTS MatOp_Inv_;
template<typename M> class CV_EXPORTS MatOp_MulDiv_;
template<typename M> class CV_EXPORTS MatOp_Repeat_;
template<typename M> class CV_EXPORTS MatOp_Set_;
template<typename M> class CV_EXPORTS MatOp_Scale_;
template<typename M> class CV_EXPORTS MatOp_T_;
typedef MatExpr_<MatExpr_Op4_<Size, int, Scalar, typedef MatExpr_<MatExpr_Op4_<Size, int, Scalar,
int, Mat, MatOp_Set_<Mat> >, Mat> MatExpr_Initializer; int, Mat, MatOp_Set_<Mat> >, Mat> MatExpr_Initializer;
template<typename _Tp> class CV_EXPORTS MatIterator_;
template<typename _Tp> class CV_EXPORTS MatConstIterator_;
template<typename _Tp> class CV_EXPORTS MatCommaInitializer_;
enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 }; enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); } static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
// matrix decomposition types
enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 };
enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_TYPE_MASK=7, NORM_RELATIVE=8, NORM_MINMAX=32};
enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 };
enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 };
enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32,
DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS };
/*! /*!
The matrix class. The matrix class.
@ -1322,8 +1483,12 @@ public:
Mat(const IplImage* img, bool copyData=false); Mat(const IplImage* img, bool copyData=false);
//! builds matrix from std::vector with or without copying the data //! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false); template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
//! builds matrix from cv::Vec; the data is copied //! builds matrix from cv::Vec; the data is copied by default
template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec); template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec,
bool copyData=true);
//! builds matrix from cv::Matx; the data is copied by default
template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx,
bool copyData=true);
//! builds matrix from a 2D point //! builds matrix from a 2D point
template<typename _Tp> explicit Mat(const Point_<_Tp>& pt); template<typename _Tp> explicit Mat(const Point_<_Tp>& pt);
//! builds matrix from a 3D point //! builds matrix from a 3D point
@ -2116,7 +2281,8 @@ public:
Mat_(const MatExpr_Base& expr); Mat_(const MatExpr_Base& expr);
//! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
explicit Mat_(const vector<_Tp>& vec, bool copyData=false); explicit Mat_(const vector<_Tp>& vec, bool copyData=false);
template<int n> explicit Mat_(const Vec<_Tp, n>& vec); template<int n> explicit Mat_(const Vec<_Tp, n>& vec, bool copyData=true);
template<int m, int n> explicit Mat_(const Matx<_Tp, m, n>& mtx, bool copyData=true);
explicit Mat_(const Point_<_Tp>& pt); explicit Mat_(const Point_<_Tp>& pt);
explicit Mat_(const Point3_<_Tp>& pt); explicit Mat_(const Point3_<_Tp>& pt);
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
@ -2359,19 +2525,28 @@ public:
void assignTo(Mat& m, int type=-1) const; void assignTo(Mat& m, int type=-1) const;
}; };
#if 0
template<typename _Tp> class VectorCommaInitializer_ template<typename _Tp, int n> class CV_EXPORTS VecCommaInitializer
{ {
public: public:
VectorCommaInitializer_(vector<_Tp>* _vec); VecCommaInitializer(Vec<_Tp, n>* _vec);
template<typename T2> VectorCommaInitializer_<_Tp>& operator , (T2 val); template<typename T2> VecCommaInitializer<_Tp, n>& operator , (T2 val);
operator vector<_Tp>() const; Vec<_Tp, n> operator *() const;
vector<_Tp> operator *() const;
vector<_Tp>* vec; Vec<_Tp, n>* vec;
int idx; int idx;
}; };
#endif
template<typename _Tp, int m, int n> class CV_EXPORTS MatxCommaInitializer :
public VecCommaInitializer<_Tp, m*n>
{
public:
MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
Matx<_Tp, m, n> operator *() const;
};
/*! /*!
Automatically Allocated Buffer Class Automatically Allocated Buffer Class
@ -3917,7 +4092,7 @@ public:
SeqIterator<_Tp> end() const; SeqIterator<_Tp> end() const;
//! returns the number of elements in the sequence //! returns the number of elements in the sequence
size_t size() const; size_t size() const;
//! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_MAX_CN) ...) //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...)
int type() const; int type() const;
//! returns the depth of sequence elements (CV_8U ... CV_64F) //! returns the depth of sequence elements (CV_8U ... CV_64F)
int depth() const; int depth() const;

View File

@ -663,7 +663,7 @@ CvFuncTable;
typedef struct CvBigFuncTable typedef struct CvBigFuncTable
{ {
void* fn_2d[CV_DEPTH_MAX*CV_CN_MAX]; void* fn_2d[CV_DEPTH_MAX*4];
} }
CvBigFuncTable; CvBigFuncTable;

View File

@ -231,13 +231,39 @@ template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
} }
template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec) template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
rows(0), cols(0), step(0), data(0), refcount(0), rows(0), cols(0), step(0), data(0), refcount(0),
datastart(0), dataend(0) datastart(0), dataend(0)
{ {
create(n, 1, DataType<_Tp>::type); if( !copyData )
memcpy(data, &vec[0], n*sizeof(_Tp)); {
rows = n;
cols = 1;
step = sizeof(_Tp);
data = datastart = (uchar*)vec.val;
dataend = datastart + rows*step;
}
else
Mat(n, 1, DataType<_Tp>::type, vec.val).copyTo(*this);
}
template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
rows(0), cols(0), step(0), data(0), refcount(0),
datastart(0), dataend(0)
{
if( !copyData )
{
rows = m;
cols = n;
step = sizeof(_Tp);
data = datastart = (uchar*)M.val;
dataend = datastart + rows*step;
}
else
Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
} }
@ -619,12 +645,16 @@ template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRan
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi) template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
: Mat(m, roi) {} : Mat(m, roi) {}
template<typename _Tp> template<int n> inline Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec) template<typename _Tp> template<int n> inline
: Mat(n, 1, DataType<_Tp>::type) Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec, bool copyData)
: Mat(vec, copyData)
{
}
template<typename _Tp> template<int m, int n> inline
Mat_<_Tp>::Mat_(const Matx<_Tp,m,n>& M, bool copyData)
: Mat(M, copyData)
{ {
_Tp* d = (_Tp*)data;
for( int i = 0; i < n; i++ )
d[i] = vec[i];
} }
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<_Tp>& pt) template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<_Tp>& pt)

View File

@ -101,6 +101,8 @@
#endif #endif
#include <limits>
namespace cv namespace cv
{ {
@ -285,6 +287,12 @@ template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2,
} }
template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
{
for( int i = 0; i < cn; i++ ) val[i] = values[i];
}
template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v) template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
{ {
for( int i = 0; i < cn; i++ ) val[i] = v.val[i]; for( int i = 0; i < cn; i++ ) val[i] = v.val[i];
@ -304,6 +312,7 @@ template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::dot(const Vec<_Tp, cn>&
return s; return s;
} }
template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, cn>& v) const template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, cn>& v) const
{ {
double s = 0; double s = 0;
@ -311,11 +320,20 @@ template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, c
return s; return s;
} }
template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
{ {
return Vec<_Tp, cn>(); // for arbitrary-size vector there is no cross-product defined CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
return Vec<_Tp, cn>();
} }
template<typename _Tp, int cn> inline Matx<_Tp, 1, cn> Vec<_Tp, cn>::t() const
{
return (const Matx<_Tp, 1, cn>&)*this;
}
template<typename _Tp, int cn> template<typename T2> template<typename _Tp, int cn> template<typename T2>
inline Vec<_Tp, cn>::operator Vec<T2, cn>() const inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
{ {
@ -333,8 +351,29 @@ template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
return s; return s;
} }
template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const { return val[i]; } template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator[](int i) { return val[i]; } {
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 _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
{
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>& template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
@ -439,6 +478,7 @@ Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
return a; return a;
} }
template<typename T1, typename T2> static inline template<typename T1, typename T2> static inline
Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b) Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
{ {
@ -449,6 +489,7 @@ Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
return a; return a;
} }
template<typename T1, int n> static inline template<typename T1, int n> static inline
double norm(const Vec<T1, n>& a) double norm(const Vec<T1, n>& a)
{ {
@ -458,6 +499,31 @@ double norm(const Vec<T1, n>& a)
return std::sqrt(s); return std::sqrt(s);
} }
template<typename T1, int n> static inline
double norm(const Vec<T1, n>& a, int normType)
{
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);
}
template<typename T1, int n> static inline template<typename T1, int n> static inline
bool operator == (const Vec<T1, n>& a, const Vec<T1, n>& b) bool operator == (const Vec<T1, n>& a, const Vec<T1, n>& b)
{ {
@ -472,6 +538,698 @@ bool operator != (const Vec<T1, n>& a, const Vec<T1, n>& b)
return !(a == b); return !(a == b);
} }
template<typename _Tp, typename _T2, int n> static inline
VecCommaInitializer<_Tp, n> operator << (const Vec<_Tp, n>& vec, _T2 val)
{
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)
{}
template<typename _Tp, int n> template<typename _T2> inline
VecCommaInitializer<_Tp, n>& VecCommaInitializer<_Tp, n>::operator , (_T2 value)
{
CV_DbgAssert( idx < n );
vec->val[idx++] = saturate_cast<_Tp>(value);
return *this;
}
template<typename _Tp, int n> inline
Vec<_Tp, n> VecCommaInitializer<_Tp, n>::operator *() const
{
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)
{}
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>
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>
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)
{
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;
}
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)
{
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)
{}
template<typename _Tp, int m, int n>
inline Matx<_Tp,m,n>::Matx(const Matx<_Tp,m,n>::base_type& v)
: base_type(v)
{
}
template<typename _Tp, int m, int n> inline
Matx<_Tp,m,n> Matx<_Tp,m,n>::all(_Tp alpha)
{
base_type v = base_type::all(alpha);
return (Matx<_Tp,m,n>&)v;
}
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 m, int n> inline
Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Vec<_Tp,MIN(m,n)>& d)
{
Matx<_Tp,m,n> M;
for(int i = 0; i < MIN(m,n); i++)
M(i,i) = d[i];
}
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)
{
Matx<_Tp,m,n> M;
Mat matM(M, false);
cv::randn(matM, Scalar(a), Scalar(b));
return M;
}
template<typename _Tp, int m, int n> template<typename T2>
inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
{
Vec<T2, m*n> v = *this;
return (Matx<T2, m, n>&)v;
}
template<typename _Tp, int m, int n> template<int m1, int n1> inline
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
{
CV_DbgAssert(m1*n1 == m*n);
return (const Matx<_Tp, m1, n1>&)*this;
}
template<typename _Tp, int m, int n>
template<int m1, int n1> inline
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::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;
}
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)m);
return (Matx<_Tp, 1, n>&)(*this)(i,0);
}
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
{
diag_type d;
for( int i = 0; i < MIN(m, n); i++ )
d[i] = (*this)(i,i);
return d;
}
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)
{
CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
return this->val[i*n + j];
}
template<typename _Tp, int m, int n> inline
const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
{
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)
{
CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
return this->val[i];
}
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 _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)
{
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> 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)
{
for( int i = 0; i < m*n; i++ )
this->val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
}
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)
{
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<int l> inline
Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
{
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;
}
}
template<typename _Tp, int m, int n> inline
Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
{
for( int i = 0; i < m; i++ )
for( int j = 0; j < n; j++ )
this->val[i*n + j] = a(j, i);
}
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)
{
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)
{
return Matx<_Tp, m, n>(a, b, Matx_SubOp());
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
{
for( int i = 0; i < m*n; i++ )
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
{
for( int i = 0; i < m*n; i++ )
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
}
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);
}
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)
{
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, 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)
{
return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
}
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> static inline
Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
{
return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
}
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 Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
}
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
Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
{
return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
}
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> struct CV_EXPORTS Matx_DetOp
{
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> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
{
double operator ()(const Matx<_Tp, 1, 1>& a) const
{
return a(0,0);
}
};
template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
{
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> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
{
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)
{
return Matx_DetOp<_Tp, m>()(a);
}
template<typename _Tp, int m, int n> static inline
double trace(const Matx<_Tp, m, n>& a)
{
_Tp s = 0;
for( int i = 0; i < std::min(m, n); i++ )
s += a(i,i);
return s;
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
{
return Matx<_Tp, n, m>(*this, Matx_TOp());
}
template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
{
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> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
{
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> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
{
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, n, m> Matx<_Tp, m, n>::inv(int method) const
{
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> struct CV_EXPORTS Matx_FastSolveOp
{
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>
{
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> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
{
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
{
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);
}
return ok ? x : Matx<_Tp, n, l>::zeros();
}
template<typename _Tp, int m, int n> inline
Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const
{
return solve(Matx<_Tp, m, 1>(rhs), method);
}
template<typename _Tp, typename _T2, int m, int n> static inline
MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
{
MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
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 m, int n> template<typename _T2> inline
MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
{
return (MatxCommaInitializer<_Tp, m, n>&)VecCommaInitializer<_Tp, m*n>::operator ,(value);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
{
CV_DbgAssert( this->idx == n*m );
return (Matx<_Tp, m, n>&)*(this->vec);
}
//////////////////////////////// Complex ////////////////////////////// //////////////////////////////// Complex //////////////////////////////
template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {} template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {}
@ -1482,35 +2240,6 @@ inline Point LineIterator::pos() const
return p; return p;
} }
#if 0
template<typename _Tp> inline VectorCommaInitializer_<_Tp>::
VectorCommaInitializer_(vector<_Tp>* _vec) : vec(_vec), idx(0) {}
template<typename _Tp> template<typename T2> inline VectorCommaInitializer_<_Tp>&
VectorCommaInitializer_<_Tp>::operator , (T2 val)
{
if( (size_t)idx < vec->size() )
(*vec)[idx] = _Tp(val);
else
vec->push_back(_Tp(val));
idx++;
return *this;
}
template<typename _Tp> inline VectorCommaInitializer_<_Tp>::operator vector<_Tp>() const
{ return *vec; }
template<typename _Tp> inline vector<_Tp> VectorCommaInitializer_<_Tp>::operator *() const
{ return *vec; }
template<typename _Tp, typename T2> static inline VectorCommaInitializer_<_Tp>
operator << (const vector<_Tp>& vec, T2 val)
{
VectorCommaInitializer_<_Tp> commaInitializer((vector<_Tp>*)&vec);
return (commaInitializer, val);
}
#endif
/////////////////////////////// AutoBuffer //////////////////////////////////////// /////////////////////////////// AutoBuffer ////////////////////////////////////////
template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer() template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()

View File

@ -518,7 +518,7 @@ IplConvKernelFP;
* Matrix type (CvMat) * * Matrix type (CvMat) *
\****************************************************************************************/ \****************************************************************************************/
#define CV_CN_MAX 64 #define CV_CN_MAX 1024
#define CV_CN_SHIFT 3 #define CV_CN_SHIFT 3
#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) #define CV_DEPTH_MAX (1 << CV_CN_SHIFT)

View File

@ -58,6 +58,161 @@
namespace cv namespace cv
{ {
/****************************************************************************************\
* LU & Cholesky implementation for small matrices *
\****************************************************************************************/
template<typename _Tp> static inline int LUImpl(_Tp* A, int m, _Tp* b, int n)
{
int i, j, k, p = 1;
for( i = 0; i < m; i++ )
{
k = i;
for( j = i+1; j < m; j++ )
if( std::abs(A[j*m + i]) > std::abs(A[k*m + i]) )
k = j;
if( std::abs(A[k*m + i]) < std::numeric_limits<_Tp>::epsilon() )
return 0;
if( k != i )
{
for( j = i; j < m; j++ )
std::swap(A[i*m + j], A[k*m + j]);
if( b )
for( j = 0; j < n; j++ )
std::swap(b[i*n + j], b[k*n + j]);
p = -p;
}
_Tp d = -1/A[i*m + i];
for( j = i+1; j < m; j++ )
{
_Tp alpha = A[j*m + i]*d;
for( k = i+1; k < m; k++ )
A[j*m + k] += alpha*A[i*m + k];
if( b )
for( k = 0; k < n; k++ )
b[j*n + k] += alpha*b[i*n + k];
}
A[i*m + i] = -d;
}
if( b )
{
for( i = m-1; i >= 0; i-- )
for( j = 0; j < n; j++ )
{
_Tp s = b[i*n + j];
for( k = i+1; k < m; k++ )
s -= A[i*m + k]*b[k*n + j];
b[i*n + j] = s*A[i*m + i];
}
}
return p;
}
int LU(float* A, int m, float* b, int n)
{
return LUImpl(A, m, b, n);
}
int LU(double* A, int m, double* b, int n)
{
return LUImpl(A, m, b, n);
}
template<typename _Tp> static inline bool CholImpl(_Tp* A, int m, _Tp* b, int n)
{
_Tp* L = A;
int i, j, k;
double s;
for( i = 0; i < m; i++ )
{
for( j = 0; j < i; j++ )
{
s = A[i*m + j];
for( k = 0; k < j; k++ )
s -= L[i*m + k]*L[j*m + k];
L[i*m + j] = (_Tp)(s*L[j*m + j]);
}
s = A[i*m + i];
for( k = 0; k < j; k++ )
{
double t = L[i*m + k];
s -= t*t;
}
if( s < std::numeric_limits<_Tp>::epsilon() )
return 0;
L[i*m + i] = (_Tp)(1./std::sqrt(s));
}
if( !b )
return false;
// LLt x = b
// 1: L y = b
// 2. Lt x = y
/*
[ L00 ] y0 b0
[ L10 L11 ] y1 = b1
[ L20 L21 L22 ] y2 b2
[ L30 L31 L32 L33 ] y3 b3
[ L00 L10 L20 L30 ] x0 y0
[ L11 L21 L31 ] x1 = y1
[ L22 L32 ] x2 y2
[ L33 ] x3 y3
*/
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ )
{
s = b[i*n + j];
for( k = 0; k < i; k++ )
s -= L[i*m + k]*b[k*n + j];
b[i*n + j] = (_Tp)(s*L[i*m + i]);
}
}
for( i = m-1; i >= 0; i-- )
{
for( j = 0; j < n; j++ )
{
s = b[i*n + j];
for( k = m-1; k > i; k-- )
s -= L[k*m + i]*b[k*n + j];
b[i*n + j] = (_Tp)(s*L[i*m + i]);
}
}
return true;
}
bool Cholesky(float* A, int m, float* b, int n)
{
return CholImpl(A, m, b, n);
}
bool Cholesky(double* A, int m, double* b, int n)
{
return CholImpl(A, m, b, n);
}
/****************************************************************************************\ /****************************************************************************************\
* Determinant of the matrix * * Determinant of the matrix *
\****************************************************************************************/ \****************************************************************************************/

View File

@ -2344,7 +2344,7 @@ SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type )
dims = _dims; dims = _dims;
valueOffset = (int)alignSize(sizeof(SparseMat::Node) + valueOffset = (int)alignSize(sizeof(SparseMat::Node) +
sizeof(int)*(dims - CV_MAX_DIM), CV_ELEM_SIZE1(_type)); sizeof(int)*std::max(dims - CV_MAX_DIM, 0), CV_ELEM_SIZE1(_type));
nodeSize = alignSize(valueOffset + nodeSize = alignSize(valueOffset +
CV_ELEM_SIZE(_type), (int)sizeof(size_t)); CV_ELEM_SIZE(_type), (int)sizeof(size_t));