opencv MatExpr MatOp
opencv提供了很多Mat的操作,其中涉及到两个重要的类:MatOp和MatExpr
C++: MatExpr abs(const Mat& m) C++: void absdiff(InputArray src1, InputArray src2, OutputArray dst) C = abs(A-B) is equivalent to absdiff(A, B, C) C = abs(A) is equivalent to absdiff(A, Scalar::all(0), C) C++: void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1) C++: void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, Out- putArray dst, int dtype=-1) C++: void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) C++: void bitwise_not(InputArray src, OutputArray dst, InputArray mask=noArray()) C++: void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) C++: void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray()) C++: void calcCovarMatrix(const Mat* samples, int nsamples, Mat& covar, Mat& mean, int flags, int ctype=CV_64F) C++: void cartToPolar(InputArray x, InputArray y, OutputArray magnitude, OutputArray angle, bool an- gleInDegrees=false) C++: void magnitude(InputArray x, InputArray y, OutputArray magnitude) C++: bool checkRange(InputArray a, bool quiet=true, Point* pos=0, double minVal=-DBL_MAX, double maxVal=DBL_MAX ) C++: void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop) C++: void completeSymm(InputOutputArray mtx, bool lowerToUpper=false) C++: void convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0) C++: int countNonZero(InputArray src) C++: Mat cvarrToMat(const CvArr* arr, bool copyData=false, bool allowND=true, int coiMode=0 ) C++: void dct(InputArray src, OutputArray dst, int flags=0) C++: void idct(InputArray src, OutputArray dst, int flags=0) C++: void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0) C++: void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0) C++: void divide(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1) C++: double determinant(InputArray mtx) C++: bool eigen(InputArray src, OutputArray eigenvalues, int lowindex=-1, int highindex=-1) C++: void exp(InputArray src, OutputArray dst) C++: void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1 ) C++: void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1 ) C++: void flip(InputArray src, OutputArray dst, int flipCode) C++: void gemm(InputArray src1, InputArray src2, double alpha, InputArray src3, double gamma, OutputArray dst, int flags=0 ) C++: ConvertData getConvertElem(int fromType, int toType) C++: int getOptimalDFTSize(int vecsize) C++: void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst) C++: double invert(InputArray src, OutputArray dst, int flags=DECOMP_LU) C++: void log(InputArray src, OutputArray dst) C++: void LUT(InputArray src, InputArray lut, OutputArray dst, int interpolation=0 ) C++: double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar) C++: void max(InputArray src1, InputArray src2, OutputArray dst)
MatOp负责MatExpr的运算操作
class CV_EXPORTS MatOp { public: MatOp(); virtual ~MatOp(); virtual bool elementWise(const MatExpr& expr) const; virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0; virtual void roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& res) const; virtual void diag(const MatExpr& expr, int d, MatExpr& res) const; virtual void augAssignAdd(const MatExpr& expr, Mat& m) const; virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const; virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const; virtual void augAssignDivide(const MatExpr& expr, Mat& m) const; virtual void augAssignAnd(const MatExpr& expr, Mat& m) const; virtual void augAssignOr(const MatExpr& expr, Mat& m) const; virtual void augAssignXor(const MatExpr& expr, Mat& m) const; virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const; virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const; virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; virtual void divide(double s, const MatExpr& expr, MatExpr& res) const; virtual void abs(const MatExpr& expr, MatExpr& res) const; virtual void transpose(const MatExpr& expr, MatExpr& res) const; virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; virtual void invert(const MatExpr& expr, int method, MatExpr& res) const; virtual Size size(const MatExpr& expr) const; virtual int type(const MatExpr& expr) const; };
//modules/core/src/matop.cpp 定义了很多不同的操作,每种操作会重载部分函数
class MatOp_Identity : public MatOp { public: MatOp_Identity() {} virtual ~MatOp_Identity() {} bool elementWise(const MatExpr& /*expr*/) const { return true; } void assign(const MatExpr& expr, Mat& m, int type=-1) const; static void makeExpr(MatExpr& res, const Mat& m); }; static MatOp_Identity g_MatOp_Identity; //一种默认的MatOp static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; } class MatOp_T : public MatOp { public: MatOp_T() {} virtual ~MatOp_T() {} bool elementWise(const MatExpr& /*expr*/) const { return false; } void assign(const MatExpr& expr, Mat& m, int type=-1) const; void multiply(const MatExpr& e1, double s, MatExpr& res) const; void transpose(const MatExpr& expr, MatExpr& res) const; static void makeExpr(MatExpr& res, const Mat& a, double alpha=1); }; static MatOp_T g_MatOp_T; static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; }
//其他函数的实现举例:
void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const { if( this == e2.op ) { double alpha = 1, beta = 1; Scalar s; Mat m1, m2; if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) { m1 = e1.a; alpha = e1.alpha; s = e1.s; } else e1.op->assign(e1, m1); if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) { m2 = e2.a; beta = e2.alpha; s += e2.s; } else e2.op->assign(e2, m2); MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); } else e2.op->add(e1, e2, res); } void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const { Mat m1; expr1.op->assign(expr1, m1); MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s); } void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const { if( this == e2.op ) { double alpha = 1, beta = -1; Scalar s; Mat m1, m2; if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) { m1 = e1.a; alpha = e1.alpha; s = e1.s; } else e1.op->assign(e1, m1); if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) { m2 = e2.a; beta = -e2.alpha; s -= e2.s; } else e2.op->assign(e2, m2); MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); } else e2.op->subtract(e1, e2, res); } void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const { Mat m; expr.op->assign(expr, m); MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s); }
//core/include/opencv2/core/mat.hpp
class CV_EXPORTS MatExpr { public: MatExpr(); explicit MatExpr(const Mat& m); MatExpr(const MatOp* _op, int _flags, const Mat& _a = Mat(), const Mat& _b = Mat(), const Mat& _c = Mat(), double _alpha = 1, double _beta = 1, const Scalar& _s = Scalar()); operator Mat() const; template<typename _Tp> operator Mat_<_Tp>() const; Size size() const; int type() const; MatExpr row(int y) const; MatExpr col(int x) const; MatExpr diag(int d = 0) const; MatExpr operator()( const Range& rowRange, const Range& colRange ) const; MatExpr operator()( const Rect& roi ) const; MatExpr t() const; MatExpr inv(int method = DECOMP_LU) const; MatExpr mul(const MatExpr& e, double scale=1) const; MatExpr mul(const Mat& m, double scale=1) const; Mat cross(const Mat& m) const; double dot(const Mat& m) const; const MatOp* op; int flags; Mat a, b, c; double alpha, beta; Scalar s; }; CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a); CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m); CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s); CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e); CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2); CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a); CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m); CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s); CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e); CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2); CV_EXPORTS MatExpr operator - (const Mat& m); CV_EXPORTS MatExpr operator - (const MatExpr& e); CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator * (const Mat& a, double s); CV_EXPORTS MatExpr operator * (double s, const Mat& a); CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m); CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator * (const MatExpr& e, double s); CV_EXPORTS MatExpr operator * (double s, const MatExpr& e); CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2); CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator / (const Mat& a, double s); CV_EXPORTS MatExpr operator / (double s, const Mat& a); CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m); CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator / (const MatExpr& e, double s); CV_EXPORTS MatExpr operator / (double s, const MatExpr& e); CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2); CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator < (const Mat& a, double s); CV_EXPORTS MatExpr operator < (double s, const Mat& a); CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator <= (const Mat& a, double s); CV_EXPORTS MatExpr operator <= (double s, const Mat& a); CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator == (const Mat& a, double s); CV_EXPORTS MatExpr operator == (double s, const Mat& a); CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator != (const Mat& a, double s); CV_EXPORTS MatExpr operator != (double s, const Mat& a); CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator >= (const Mat& a, double s); CV_EXPORTS MatExpr operator >= (double s, const Mat& a); CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator > (const Mat& a, double s); CV_EXPORTS MatExpr operator > (double s, const Mat& a); CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a); CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a); CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a); CV_EXPORTS MatExpr operator ~(const Mat& m); CV_EXPORTS MatExpr min(const Mat& a, const Mat& b); CV_EXPORTS MatExpr min(const Mat& a, double s); CV_EXPORTS MatExpr min(double s, const Mat& a); CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); CV_EXPORTS MatExpr max(const Mat& a, double s); CV_EXPORTS MatExpr max(double s, const Mat& a); CV_EXPORTS MatExpr abs(const Mat& m); CV_EXPORTS MatExpr abs(const MatExpr& e); } // cv
MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar()) {
//默认使用的是g_MatOp_Identity } MatExpr MatExpr::diag(int d) const { MatExpr e; op->diag(*this, d, e); return e; } MatExpr MatExpr::t() const { MatExpr e; op->transpose(*this, e); return e; } MatExpr operator + (const Mat& a, const Mat& b) { MatExpr e; MatOp_AddEx::makeExpr(e, a, b, 1, 1); return e; }
class MatOp_AddEx : public MatOp { public: MatOp_AddEx() {} virtual ~MatOp_AddEx() {} bool elementWise(const MatExpr& /*expr*/) const { return true; } void assign(const MatExpr& expr, Mat& m, int type=-1) const; void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const; void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; void multiply(const MatExpr& e1, double s, MatExpr& res) const; void divide(double s, const MatExpr& e, MatExpr& res) const; void transpose(const MatExpr& e1, MatExpr& res) const; void abs(const MatExpr& expr, MatExpr& res) const; static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar()); }; static MatOp_AddEx g_MatOp_AddEx;
inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s)
{
res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s);
}