Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
matop.cpp
00001 /*M/////////////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 00004 // 00005 // By downloading, copying, installing or using the software you agree to this license. 00006 // If you do not agree to this license, do not download, install, 00007 // copy or use the software. 00008 // 00009 // 00010 // License Agreement 00011 // For Open Source Computer Vision Library 00012 // 00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 00014 // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. 00015 // Third party copyrights are property of their respective owners. 00016 // 00017 // Redistribution and use in source and binary forms, with or without modification, 00018 // are permitted provided that the following conditions are met: 00019 // 00020 // * Redistribution's of source code must retain the above copyright notice, 00021 // this list of conditions and the following disclaimer. 00022 // 00023 // * Redistribution's in binary form must reproduce the above copyright notice, 00024 // this list of conditions and the following disclaimer in the documentation 00025 // and/or other materials provided with the distribution. 00026 // 00027 // * The name of the copyright holders may not be used to endorse or promote products 00028 // derived from this software without specific prior written permission. 00029 // 00030 // This software is provided by the copyright holders and contributors "as is" and 00031 // any express or implied warranties, including, but not limited to, the implied 00032 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00033 // In no event shall the Intel Corporation or contributors be liable for any direct, 00034 // indirect, incidental, special, exemplary, or consequential damages 00035 // (including, but not limited to, procurement of substitute goods or services; 00036 // loss of use, data, or profits; or business interruption) however caused 00037 // and on any theory of liability, whether in contract, strict liability, 00038 // or tort (including negligence or otherwise) arising in any way out of 00039 // the use of this software, even if advised of the possibility of such damage. 00040 // 00041 //M*/ 00042 00043 /* //////////////////////////////////////////////////////////////////// 00044 // 00045 // Mat basic operations: Copy, Set 00046 // 00047 // */ 00048 00049 #include "precomp.hpp" 00050 00051 namespace cv 00052 { 00053 00054 class MatOp_Identity : public MatOp 00055 { 00056 public: 00057 MatOp_Identity() {} 00058 virtual ~MatOp_Identity() {} 00059 00060 bool elementWise(const MatExpr& /*expr*/) const { return true; } 00061 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00062 00063 static void makeExpr(MatExpr& res, const Mat& m); 00064 }; 00065 00066 static MatOp_Identity g_MatOp_Identity; 00067 00068 class MatOp_AddEx : public MatOp 00069 { 00070 public: 00071 MatOp_AddEx() {} 00072 virtual ~MatOp_AddEx() {} 00073 00074 bool elementWise(const MatExpr& /*expr*/) const { return true; } 00075 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00076 00077 void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const; 00078 void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; 00079 void multiply(const MatExpr& e1, double s, MatExpr& res) const; 00080 void divide(double s, const MatExpr& e, MatExpr& res) const; 00081 00082 void transpose(const MatExpr& e1, MatExpr& res) const; 00083 void abs(const MatExpr& expr, MatExpr& res) const; 00084 00085 static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar()); 00086 }; 00087 00088 static MatOp_AddEx g_MatOp_AddEx; 00089 00090 class MatOp_Bin : public MatOp 00091 { 00092 public: 00093 MatOp_Bin() {} 00094 virtual ~MatOp_Bin() {} 00095 00096 bool elementWise(const MatExpr& /*expr*/) const { return true; } 00097 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00098 00099 void multiply(const MatExpr& e1, double s, MatExpr& res) const; 00100 void divide(double s, const MatExpr& e, MatExpr& res) const; 00101 00102 static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1); 00103 static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s); 00104 }; 00105 00106 static MatOp_Bin g_MatOp_Bin; 00107 00108 class MatOp_Cmp : public MatOp 00109 { 00110 public: 00111 MatOp_Cmp() {} 00112 virtual ~MatOp_Cmp() {} 00113 00114 bool elementWise(const MatExpr& /*expr*/) const { return true; } 00115 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00116 00117 static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b); 00118 static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha); 00119 }; 00120 00121 static MatOp_Cmp g_MatOp_Cmp; 00122 00123 class MatOp_GEMM : public MatOp 00124 { 00125 public: 00126 MatOp_GEMM() {} 00127 virtual ~MatOp_GEMM() {} 00128 00129 bool elementWise(const MatExpr& /*expr*/) const { return false; } 00130 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00131 00132 void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; 00133 void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; 00134 void multiply(const MatExpr& e, double s, MatExpr& res) const; 00135 00136 void transpose(const MatExpr& expr, MatExpr& res) const; 00137 00138 static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, 00139 double alpha=1, const Mat& c=Mat(), double beta=1); 00140 }; 00141 00142 static MatOp_GEMM g_MatOp_GEMM; 00143 00144 class MatOp_Invert : public MatOp 00145 { 00146 public: 00147 MatOp_Invert() {} 00148 virtual ~MatOp_Invert() {} 00149 00150 bool elementWise(const MatExpr& /*expr*/) const { return false; } 00151 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00152 00153 void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; 00154 00155 static void makeExpr(MatExpr& res, int method, const Mat& m); 00156 }; 00157 00158 static MatOp_Invert g_MatOp_Invert; 00159 00160 class MatOp_T : public MatOp 00161 { 00162 public: 00163 MatOp_T() {} 00164 virtual ~MatOp_T() {} 00165 00166 bool elementWise(const MatExpr& /*expr*/) const { return false; } 00167 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00168 00169 void multiply(const MatExpr& e1, double s, MatExpr& res) const; 00170 void transpose(const MatExpr& expr, MatExpr& res) const; 00171 00172 static void makeExpr(MatExpr& res, const Mat& a, double alpha=1); 00173 }; 00174 00175 static MatOp_T g_MatOp_T; 00176 00177 class MatOp_Solve : public MatOp 00178 { 00179 public: 00180 MatOp_Solve() {} 00181 virtual ~MatOp_Solve() {} 00182 00183 bool elementWise(const MatExpr& /*expr*/) const { return false; } 00184 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00185 00186 static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b); 00187 }; 00188 00189 static MatOp_Solve g_MatOp_Solve; 00190 00191 class MatOp_Initializer : public MatOp 00192 { 00193 public: 00194 MatOp_Initializer() {} 00195 virtual ~MatOp_Initializer() {} 00196 00197 bool elementWise(const MatExpr& /*expr*/) const { return false; } 00198 void assign(const MatExpr& expr, Mat& m, int type=-1) const; 00199 00200 void multiply(const MatExpr& e, double s, MatExpr& res) const; 00201 00202 static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1); 00203 static void makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha=1); 00204 }; 00205 00206 static MatOp_Initializer* getGlobalMatOpInitializer() 00207 { 00208 CV_SINGLETON_LAZY_INIT(MatOp_Initializer, new MatOp_Initializer()) 00209 } 00210 00211 static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; } 00212 static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; } 00213 static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); } 00214 static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; } 00215 static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; } 00216 static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); } 00217 static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; } 00218 static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; } 00219 static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; } 00220 static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; } 00221 static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); } 00222 static inline bool isInitializer(const MatExpr& e) { return e.op == getGlobalMatOpInitializer(); } 00223 00224 ///////////////////////////////////////////////////////////////////////////////////////////////////// 00225 00226 MatOp::MatOp() {} 00227 MatOp::~MatOp() {} 00228 00229 00230 bool MatOp::elementWise(const MatExpr& /*expr*/) const 00231 { 00232 return false; 00233 } 00234 00235 void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const 00236 { 00237 if( elementWise(expr) ) 00238 { 00239 e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), 00240 expr.alpha, expr.beta, expr.s); 00241 if(expr.a.data) 00242 e.a = expr.a(rowRange, colRange); 00243 if(expr.b.data) 00244 e.b = expr.b(rowRange, colRange); 00245 if(expr.c.data) 00246 e.c = expr.c(rowRange, colRange); 00247 } 00248 else 00249 { 00250 Mat m; 00251 expr.op->assign(expr, m); 00252 e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat()); 00253 } 00254 } 00255 00256 void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const 00257 { 00258 if( elementWise(expr) ) 00259 { 00260 e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), 00261 expr.alpha, expr.beta, expr.s); 00262 if(expr.a.data) 00263 e.a = expr.a.diag(d); 00264 if(expr.b.data) 00265 e.b = expr.b.diag(d); 00266 if(expr.c.data) 00267 e.c = expr.c.diag(d); 00268 } 00269 else 00270 { 00271 Mat m; 00272 expr.op->assign(expr, m); 00273 e = MatExpr(&g_MatOp_Identity, 0, m.diag(d), Mat(), Mat()); 00274 } 00275 } 00276 00277 00278 void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const 00279 { 00280 Mat temp; 00281 expr.op->assign(expr, temp); 00282 m += temp; 00283 } 00284 00285 00286 void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const 00287 { 00288 Mat temp; 00289 expr.op->assign(expr, temp); 00290 m -= temp; 00291 } 00292 00293 00294 void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const 00295 { 00296 Mat temp; 00297 expr.op->assign(expr, temp); 00298 m *= temp; 00299 } 00300 00301 00302 void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const 00303 { 00304 Mat temp; 00305 expr.op->assign(expr, temp); 00306 m /= temp; 00307 } 00308 00309 00310 void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const 00311 { 00312 Mat temp; 00313 expr.op->assign(expr, temp); 00314 m &= temp; 00315 } 00316 00317 00318 void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const 00319 { 00320 Mat temp; 00321 expr.op->assign(expr, temp); 00322 m |= temp; 00323 } 00324 00325 00326 void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const 00327 { 00328 Mat temp; 00329 expr.op->assign(expr, temp); 00330 m ^= temp; 00331 } 00332 00333 00334 void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 00335 { 00336 if( this == e2.op ) 00337 { 00338 double alpha = 1, beta = 1; 00339 Scalar s; 00340 Mat m1, m2; 00341 if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) 00342 { 00343 m1 = e1.a; 00344 alpha = e1.alpha; 00345 s = e1.s; 00346 } 00347 else 00348 e1.op->assign(e1, m1); 00349 00350 if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) 00351 { 00352 m2 = e2.a; 00353 beta = e2.alpha; 00354 s += e2.s; 00355 } 00356 else 00357 e2.op->assign(e2, m2); 00358 MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); 00359 } 00360 else 00361 e2.op->add(e1, e2, res); 00362 } 00363 00364 00365 void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const 00366 { 00367 Mat m1; 00368 expr1.op->assign(expr1, m1); 00369 MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s); 00370 } 00371 00372 00373 void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 00374 { 00375 if( this == e2.op ) 00376 { 00377 double alpha = 1, beta = -1; 00378 Scalar s; 00379 Mat m1, m2; 00380 if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) ) 00381 { 00382 m1 = e1.a; 00383 alpha = e1.alpha; 00384 s = e1.s; 00385 } 00386 else 00387 e1.op->assign(e1, m1); 00388 00389 if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) ) 00390 { 00391 m2 = e2.a; 00392 beta = -e2.alpha; 00393 s -= e2.s; 00394 } 00395 else 00396 e2.op->assign(e2, m2); 00397 MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s); 00398 } 00399 else 00400 e2.op->subtract(e1, e2, res); 00401 } 00402 00403 00404 void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const 00405 { 00406 Mat m; 00407 expr.op->assign(expr, m); 00408 MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s); 00409 } 00410 00411 00412 void MatOp::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const 00413 { 00414 if( this == e2.op ) 00415 { 00416 Mat m1, m2; 00417 00418 if( isReciprocal(e1) ) 00419 { 00420 if( isScaled(e2) ) 00421 { 00422 scale *= e2.alpha; 00423 m2 = e2.a; 00424 } 00425 else 00426 e2.op->assign(e2, m2); 00427 00428 MatOp_Bin::makeExpr(res, '/', m2, e1.a, scale/e1.alpha); 00429 } 00430 else 00431 { 00432 char op = '*'; 00433 if( isScaled(e1) ) 00434 { 00435 m1 = e1.a; 00436 scale *= e1.alpha; 00437 } 00438 else 00439 e1.op->assign(e1, m1); 00440 00441 if( isScaled(e2) ) 00442 { 00443 m2 = e2.a; 00444 scale *= e2.alpha; 00445 } 00446 else if( isReciprocal(e2) ) 00447 { 00448 op = '/'; 00449 m2 = e2.a; 00450 scale /= e2.alpha; 00451 } 00452 else 00453 e2.op->assign(e2, m2); 00454 00455 MatOp_Bin::makeExpr(res, op, m1, m2, scale); 00456 } 00457 } 00458 else 00459 e2.op->multiply(e1, e2, res, scale); 00460 } 00461 00462 00463 void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const 00464 { 00465 Mat m; 00466 expr.op->assign(expr, m); 00467 MatOp_AddEx::makeExpr(res, m, Mat(), s, 0); 00468 } 00469 00470 00471 void MatOp::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const 00472 { 00473 if( this == e2.op ) 00474 { 00475 if( isReciprocal(e1) && isReciprocal(e2) ) 00476 MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha/e2.alpha); 00477 else 00478 { 00479 Mat m1, m2; 00480 char op = '/'; 00481 00482 if( isScaled(e1) ) 00483 { 00484 m1 = e1.a; 00485 scale *= e1.alpha; 00486 } 00487 else 00488 e1.op->assign(e1, m1); 00489 00490 if( isScaled(e2) ) 00491 { 00492 m2 = e2.a; 00493 scale /= e2.alpha; 00494 } 00495 else if( isReciprocal(e2) ) 00496 { 00497 m2 = e2.a; 00498 scale /= e2.alpha; 00499 op = '*'; 00500 } 00501 else 00502 e2.op->assign(e2, m2); 00503 MatOp_Bin::makeExpr(res, op, m1, m2, scale); 00504 } 00505 } 00506 else 00507 e2.op->divide(e1, e2, res, scale); 00508 } 00509 00510 00511 void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const 00512 { 00513 Mat m; 00514 expr.op->assign(expr, m); 00515 MatOp_Bin::makeExpr(res, '/', m, Mat(), s); 00516 } 00517 00518 00519 void MatOp::abs(const MatExpr& expr, MatExpr& res) const 00520 { 00521 Mat m; 00522 expr.op->assign(expr, m); 00523 MatOp_Bin::makeExpr(res, 'a', m, Mat()); 00524 } 00525 00526 00527 void MatOp::transpose(const MatExpr& expr, MatExpr& res) const 00528 { 00529 Mat m; 00530 expr.op->assign(expr, m); 00531 MatOp_T::makeExpr(res, m, 1); 00532 } 00533 00534 00535 void MatOp::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 00536 { 00537 if( this == e2.op ) 00538 { 00539 double scale = 1; 00540 int flags = 0; 00541 Mat m1, m2; 00542 00543 if( isT(e1) ) 00544 { 00545 flags = CV_GEMM_A_T; 00546 scale = e1.alpha; 00547 m1 = e1.a; 00548 } 00549 else if( isScaled(e1) ) 00550 { 00551 scale = e1.alpha; 00552 m1 = e1.a; 00553 } 00554 else 00555 e1.op->assign(e1, m1); 00556 00557 if( isT(e2) ) 00558 { 00559 flags |= CV_GEMM_B_T; 00560 scale *= e2.alpha; 00561 m2 = e2.a; 00562 } 00563 else if( isScaled(e2) ) 00564 { 00565 scale *= e2.alpha; 00566 m2 = e2.a; 00567 } 00568 else 00569 e2.op->assign(e2, m2); 00570 00571 MatOp_GEMM::makeExpr(res, flags, m1, m2, scale); 00572 } 00573 else 00574 e2.op->matmul(e1, e2, res); 00575 } 00576 00577 00578 void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const 00579 { 00580 Mat m; 00581 expr.op->assign(expr, m); 00582 MatOp_Invert::makeExpr(res, method, m); 00583 } 00584 00585 00586 Size MatOp::size(const MatExpr& expr) const 00587 { 00588 return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size(); 00589 } 00590 00591 int MatOp::type(const MatExpr& expr) const 00592 { 00593 return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type(); 00594 } 00595 00596 ////////////////////////////////////////////////////////////////////////////////////////////////// 00597 00598 MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar()) 00599 { 00600 } 00601 00602 MatExpr MatExpr::row(int y) const 00603 { 00604 MatExpr e; 00605 op->roi(*this, Range(y, y+1), Range::all(), e); 00606 return e; 00607 } 00608 00609 MatExpr MatExpr::col(int x) const 00610 { 00611 MatExpr e; 00612 op->roi(*this, Range::all(), Range(x, x+1), e); 00613 return e; 00614 } 00615 00616 MatExpr MatExpr::diag(int d) const 00617 { 00618 MatExpr e; 00619 op->diag(*this, d, e); 00620 return e; 00621 } 00622 00623 MatExpr MatExpr::operator()( const Range& rowRange, const Range& colRange ) const 00624 { 00625 MatExpr e; 00626 op->roi(*this, rowRange, colRange, e); 00627 return e; 00628 } 00629 00630 MatExpr MatExpr::operator()( const Rect& roi ) const 00631 { 00632 MatExpr e; 00633 op->roi(*this, Range(roi.y, roi.y + roi.height), Range(roi.x, roi.x + roi.width), e); 00634 return e; 00635 } 00636 00637 Mat MatExpr::cross(const Mat& m) const 00638 { 00639 return ((Mat)*this).cross(m); 00640 } 00641 00642 double MatExpr::dot(const Mat& m) const 00643 { 00644 return ((Mat)*this).dot(m); 00645 } 00646 00647 MatExpr MatExpr::t() const 00648 { 00649 MatExpr e; 00650 op->transpose(*this, e); 00651 return e; 00652 } 00653 00654 MatExpr MatExpr::inv(int method) const 00655 { 00656 MatExpr e; 00657 op->invert(*this, method, e); 00658 return e; 00659 } 00660 00661 MatExpr MatExpr::mul(const MatExpr& e, double scale) const 00662 { 00663 MatExpr en; 00664 op->multiply(*this, e, en, scale); 00665 return en; 00666 } 00667 00668 MatExpr MatExpr::mul(const Mat& m, double scale) const 00669 { 00670 MatExpr e; 00671 op->multiply(*this, MatExpr(m), e, scale); 00672 return e; 00673 } 00674 00675 MatExpr operator + (const Mat& a, const Mat& b) 00676 { 00677 MatExpr e; 00678 MatOp_AddEx::makeExpr(e, a, b, 1, 1); 00679 return e; 00680 } 00681 00682 MatExpr operator + (const Mat& a, const Scalar& s) 00683 { 00684 MatExpr e; 00685 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); 00686 return e; 00687 } 00688 00689 MatExpr operator + (const Scalar& s, const Mat& a) 00690 { 00691 MatExpr e; 00692 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); 00693 return e; 00694 } 00695 00696 MatExpr operator + (const MatExpr& e, const Mat& m) 00697 { 00698 MatExpr en; 00699 e.op->add(e, MatExpr(m), en); 00700 return en; 00701 } 00702 00703 MatExpr operator + (const Mat& m, const MatExpr& e) 00704 { 00705 MatExpr en; 00706 e.op->add(e, MatExpr(m), en); 00707 return en; 00708 } 00709 00710 MatExpr operator + (const MatExpr& e, const Scalar& s) 00711 { 00712 MatExpr en; 00713 e.op->add(e, s, en); 00714 return en; 00715 } 00716 00717 MatExpr operator + (const Scalar& s, const MatExpr& e) 00718 { 00719 MatExpr en; 00720 e.op->add(e, s, en); 00721 return en; 00722 } 00723 00724 MatExpr operator + (const MatExpr& e1, const MatExpr& e2) 00725 { 00726 MatExpr en; 00727 e1.op->add(e1, e2, en); 00728 return en; 00729 } 00730 00731 MatExpr operator - (const Mat& a, const Mat& b) 00732 { 00733 MatExpr e; 00734 MatOp_AddEx::makeExpr(e, a, b, 1, -1); 00735 return e; 00736 } 00737 00738 MatExpr operator - (const Mat& a, const Scalar& s) 00739 { 00740 MatExpr e; 00741 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s); 00742 return e; 00743 } 00744 00745 MatExpr operator - (const Scalar& s, const Mat& a) 00746 { 00747 MatExpr e; 00748 MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s); 00749 return e; 00750 } 00751 00752 MatExpr operator - (const MatExpr& e, const Mat& m) 00753 { 00754 MatExpr en; 00755 e.op->subtract(e, MatExpr(m), en); 00756 return en; 00757 } 00758 00759 MatExpr operator - (const Mat& m, const MatExpr& e) 00760 { 00761 MatExpr en; 00762 e.op->subtract(MatExpr(m), e, en); 00763 return en; 00764 } 00765 00766 MatExpr operator - (const MatExpr& e, const Scalar& s) 00767 { 00768 MatExpr en; 00769 e.op->add(e, -s, en); 00770 return en; 00771 } 00772 00773 MatExpr operator - (const Scalar& s, const MatExpr& e) 00774 { 00775 MatExpr en; 00776 e.op->subtract(s, e, en); 00777 return en; 00778 } 00779 00780 MatExpr operator - (const MatExpr& e1, const MatExpr& e2) 00781 { 00782 MatExpr en; 00783 e1.op->subtract(e1, e2, en); 00784 return en; 00785 } 00786 00787 MatExpr operator - (const Mat& m) 00788 { 00789 MatExpr e; 00790 MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0); 00791 return e; 00792 } 00793 00794 MatExpr operator - (const MatExpr& e) 00795 { 00796 MatExpr en; 00797 e.op->subtract(Scalar(0), e, en); 00798 return en; 00799 } 00800 00801 MatExpr operator * (const Mat& a, const Mat& b) 00802 { 00803 MatExpr e; 00804 MatOp_GEMM::makeExpr(e, 0, a, b); 00805 return e; 00806 } 00807 00808 MatExpr operator * (const Mat& a, double s) 00809 { 00810 MatExpr e; 00811 MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); 00812 return e; 00813 } 00814 00815 MatExpr operator * (double s, const Mat& a) 00816 { 00817 MatExpr e; 00818 MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); 00819 return e; 00820 } 00821 00822 MatExpr operator * (const MatExpr& e, const Mat& m) 00823 { 00824 MatExpr en; 00825 e.op->matmul(e, MatExpr(m), en); 00826 return en; 00827 } 00828 00829 MatExpr operator * (const Mat& m, const MatExpr& e) 00830 { 00831 MatExpr en; 00832 e.op->matmul(MatExpr(m), e, en); 00833 return en; 00834 } 00835 00836 MatExpr operator * (const MatExpr& e, double s) 00837 { 00838 MatExpr en; 00839 e.op->multiply(e, s, en); 00840 return en; 00841 } 00842 00843 MatExpr operator * (double s, const MatExpr& e) 00844 { 00845 MatExpr en; 00846 e.op->multiply(e, s, en); 00847 return en; 00848 } 00849 00850 MatExpr operator * (const MatExpr& e1, const MatExpr& e2) 00851 { 00852 MatExpr en; 00853 e1.op->matmul(e1, e2, en); 00854 return en; 00855 } 00856 00857 MatExpr operator / (const Mat& a, const Mat& b) 00858 { 00859 MatExpr e; 00860 MatOp_Bin::makeExpr(e, '/', a, b); 00861 return e; 00862 } 00863 00864 MatExpr operator / (const Mat& a, double s) 00865 { 00866 MatExpr e; 00867 MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0); 00868 return e; 00869 } 00870 00871 MatExpr operator / (double s, const Mat& a) 00872 { 00873 MatExpr e; 00874 MatOp_Bin::makeExpr(e, '/', a, Mat(), s); 00875 return e; 00876 } 00877 00878 MatExpr operator / (const MatExpr& e, const Mat& m) 00879 { 00880 MatExpr en; 00881 e.op->divide(e, MatExpr(m), en); 00882 return en; 00883 } 00884 00885 MatExpr operator / (const Mat& m, const MatExpr& e) 00886 { 00887 MatExpr en; 00888 e.op->divide(MatExpr(m), e, en); 00889 return en; 00890 } 00891 00892 MatExpr operator / (const MatExpr& e, double s) 00893 { 00894 MatExpr en; 00895 e.op->multiply(e, 1./s, en); 00896 return en; 00897 } 00898 00899 MatExpr operator / (double s, const MatExpr& e) 00900 { 00901 MatExpr en; 00902 e.op->divide(s, e, en); 00903 return en; 00904 } 00905 00906 MatExpr operator / (const MatExpr& e1, const MatExpr& e2) 00907 { 00908 MatExpr en; 00909 e1.op->divide(e1, e2, en); 00910 return en; 00911 } 00912 00913 MatExpr operator < (const Mat& a, const Mat& b) 00914 { 00915 MatExpr e; 00916 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b); 00917 return e; 00918 } 00919 00920 MatExpr operator < (const Mat& a, double s) 00921 { 00922 MatExpr e; 00923 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); 00924 return e; 00925 } 00926 00927 MatExpr operator < (double s, const Mat& a) 00928 { 00929 MatExpr e; 00930 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); 00931 return e; 00932 } 00933 00934 MatExpr operator <= (const Mat& a, const Mat& b) 00935 { 00936 MatExpr e; 00937 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b); 00938 return e; 00939 } 00940 00941 MatExpr operator <= (const Mat& a, double s) 00942 { 00943 MatExpr e; 00944 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); 00945 return e; 00946 } 00947 00948 MatExpr operator <= (double s, const Mat& a) 00949 { 00950 MatExpr e; 00951 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); 00952 return e; 00953 } 00954 00955 MatExpr operator == (const Mat& a, const Mat& b) 00956 { 00957 MatExpr e; 00958 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b); 00959 return e; 00960 } 00961 00962 MatExpr operator == (const Mat& a, double s) 00963 { 00964 MatExpr e; 00965 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); 00966 return e; 00967 } 00968 00969 MatExpr operator == (double s, const Mat& a) 00970 { 00971 MatExpr e; 00972 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); 00973 return e; 00974 } 00975 00976 MatExpr operator != (const Mat& a, const Mat& b) 00977 { 00978 MatExpr e; 00979 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b); 00980 return e; 00981 } 00982 00983 MatExpr operator != (const Mat& a, double s) 00984 { 00985 MatExpr e; 00986 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); 00987 return e; 00988 } 00989 00990 MatExpr operator != (double s, const Mat& a) 00991 { 00992 MatExpr e; 00993 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); 00994 return e; 00995 } 00996 00997 MatExpr operator >= (const Mat& a, const Mat& b) 00998 { 00999 MatExpr e; 01000 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b); 01001 return e; 01002 } 01003 01004 MatExpr operator >= (const Mat& a, double s) 01005 { 01006 MatExpr e; 01007 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); 01008 return e; 01009 } 01010 01011 MatExpr operator >= (double s, const Mat& a) 01012 { 01013 MatExpr e; 01014 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); 01015 return e; 01016 } 01017 01018 MatExpr operator > (const Mat& a, const Mat& b) 01019 { 01020 MatExpr e; 01021 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b); 01022 return e; 01023 } 01024 01025 MatExpr operator > (const Mat& a, double s) 01026 { 01027 MatExpr e; 01028 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); 01029 return e; 01030 } 01031 01032 MatExpr operator > (double s, const Mat& a) 01033 { 01034 MatExpr e; 01035 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); 01036 return e; 01037 } 01038 01039 MatExpr min(const Mat& a, const Mat& b) 01040 { 01041 MatExpr e; 01042 MatOp_Bin::makeExpr(e, 'm', a, b); 01043 return e; 01044 } 01045 01046 MatExpr min(const Mat& a, double s) 01047 { 01048 MatExpr e; 01049 MatOp_Bin::makeExpr(e, 'n', a, s); 01050 return e; 01051 } 01052 01053 MatExpr min(double s, const Mat& a) 01054 { 01055 MatExpr e; 01056 MatOp_Bin::makeExpr(e, 'n', a, s); 01057 return e; 01058 } 01059 01060 MatExpr max(const Mat& a, const Mat& b) 01061 { 01062 MatExpr e; 01063 MatOp_Bin::makeExpr(e, 'M', a, b); 01064 return e; 01065 } 01066 01067 MatExpr max(const Mat& a, double s) 01068 { 01069 MatExpr e; 01070 MatOp_Bin::makeExpr(e, 'N', a, s); 01071 return e; 01072 } 01073 01074 MatExpr max(double s, const Mat& a) 01075 { 01076 MatExpr e; 01077 MatOp_Bin::makeExpr(e, 'N', a, s); 01078 return e; 01079 } 01080 01081 MatExpr operator & (const Mat& a, const Mat& b) 01082 { 01083 MatExpr e; 01084 MatOp_Bin::makeExpr(e, '&', a, b); 01085 return e; 01086 } 01087 01088 MatExpr operator & (const Mat& a, const Scalar& s) 01089 { 01090 MatExpr e; 01091 MatOp_Bin::makeExpr(e, '&', a, s); 01092 return e; 01093 } 01094 01095 MatExpr operator & (const Scalar& s, const Mat& a) 01096 { 01097 MatExpr e; 01098 MatOp_Bin::makeExpr(e, '&', a, s); 01099 return e; 01100 } 01101 01102 MatExpr operator | (const Mat& a, const Mat& b) 01103 { 01104 MatExpr e; 01105 MatOp_Bin::makeExpr(e, '|', a, b); 01106 return e; 01107 } 01108 01109 MatExpr operator | (const Mat& a, const Scalar& s) 01110 { 01111 MatExpr e; 01112 MatOp_Bin::makeExpr(e, '|', a, s); 01113 return e; 01114 } 01115 01116 MatExpr operator | (const Scalar& s, const Mat& a) 01117 { 01118 MatExpr e; 01119 MatOp_Bin::makeExpr(e, '|', a, s); 01120 return e; 01121 } 01122 01123 MatExpr operator ^ (const Mat& a, const Mat& b) 01124 { 01125 MatExpr e; 01126 MatOp_Bin::makeExpr(e, '^', a, b); 01127 return e; 01128 } 01129 01130 MatExpr operator ^ (const Mat& a, const Scalar& s) 01131 { 01132 MatExpr e; 01133 MatOp_Bin::makeExpr(e, '^', a, s); 01134 return e; 01135 } 01136 01137 MatExpr operator ^ (const Scalar& s, const Mat& a) 01138 { 01139 MatExpr e; 01140 MatOp_Bin::makeExpr(e, '^', a, s); 01141 return e; 01142 } 01143 01144 MatExpr operator ~(const Mat& a) 01145 { 01146 MatExpr e; 01147 MatOp_Bin::makeExpr(e, '~', a, Scalar()); 01148 return e; 01149 } 01150 01151 MatExpr abs(const Mat& a) 01152 { 01153 MatExpr e; 01154 MatOp_Bin::makeExpr(e, 'a', a, Scalar ()); 01155 return e; 01156 } 01157 01158 MatExpr abs(const MatExpr& e) 01159 { 01160 MatExpr en; 01161 e.op->abs(e, en); 01162 return en; 01163 } 01164 01165 01166 Size MatExpr::size() const 01167 { 01168 if( isT(*this) || isInv(*this) ) 01169 return Size(a.rows, a.cols); 01170 if( isGEMM(*this) ) 01171 return Size(b.cols, a.rows); 01172 if( isSolve(*this) ) 01173 return Size(b.cols, a.cols); 01174 if( isInitializer(*this) ) 01175 return a.size(); 01176 return op ? op->size(*this) : Size(); 01177 } 01178 01179 01180 int MatExpr::type() const 01181 { 01182 if( isInitializer(*this) ) 01183 return a.type(); 01184 if( isCmp(*this) ) 01185 return CV_8U; 01186 return op ? op->type(*this) : -1; 01187 } 01188 01189 01190 ///////////////////////////////////////////////////////////////////////////////////////////////////// 01191 01192 void MatOp_Identity::assign(const MatExpr& e, Mat& m, int _type) const 01193 { 01194 if( _type == -1 || _type == e.a.type() ) 01195 m = e.a; 01196 else 01197 { 01198 CV_Assert( CV_MAT_CN(_type) == e.a.channels() ); 01199 e.a.convertTo(m, _type); 01200 } 01201 } 01202 01203 inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m) 01204 { 01205 res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0); 01206 } 01207 01208 ///////////////////////////////////////////////////////////////////////////////////////////////////// 01209 01210 void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int _type) const 01211 { 01212 Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp; 01213 if( e.b.data ) 01214 { 01215 if( e.s == Scalar() || !e.s.isReal() ) 01216 { 01217 if( e.alpha == 1 ) 01218 { 01219 if( e.beta == 1 ) 01220 cv::add(e.a, e.b, dst); 01221 else if( e.beta == -1 ) 01222 cv::subtract(e.a, e.b, dst); 01223 else 01224 cv::scaleAdd(e.b, e.beta, e.a, dst); 01225 } 01226 else if( e.beta == 1 ) 01227 { 01228 if( e.alpha == -1 ) 01229 cv::subtract(e.b, e.a, dst); 01230 else 01231 cv::scaleAdd(e.a, e.alpha, e.b, dst); 01232 } 01233 else 01234 cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst); 01235 01236 if( !e.s.isReal() ) 01237 cv::add(dst, e.s, dst); 01238 } 01239 else 01240 cv::addWeighted(e.a, e.alpha, e.b, e.beta, e.s[0], dst); 01241 } 01242 else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1)) 01243 { 01244 e.a.convertTo(m, _type, e.alpha, e.s[0]); 01245 return; 01246 } 01247 else if( e.alpha == 1 ) 01248 cv::add(e.a, e.s, dst); 01249 else if( e.alpha == -1 ) 01250 cv::subtract(e.s, e.a, dst); 01251 else 01252 { 01253 e.a.convertTo(dst, e.a.type(), e.alpha); 01254 cv::add(dst, e.s, dst); 01255 } 01256 01257 if( dst.data != m.data ) 01258 dst.convertTo(m, m.type()); 01259 } 01260 01261 01262 void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const 01263 { 01264 res = e; 01265 res.s += s; 01266 } 01267 01268 01269 void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const 01270 { 01271 res = e; 01272 res.alpha = -res.alpha; 01273 res.beta = -res.beta; 01274 res.s = s - res.s; 01275 } 01276 01277 void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const 01278 { 01279 res = e; 01280 res.alpha *= s; 01281 res.beta *= s; 01282 res.s *= s; 01283 } 01284 01285 void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const 01286 { 01287 if( isScaled(e) ) 01288 MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s/e.alpha); 01289 else 01290 MatOp::divide(s, e, res); 01291 } 01292 01293 01294 void MatOp_AddEx::transpose(const MatExpr& e, MatExpr& res) const 01295 { 01296 if( isScaled(e) ) 01297 MatOp_T::makeExpr(res, e.a, e.alpha); 01298 else 01299 MatOp::transpose(e, res); 01300 } 01301 01302 void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const 01303 { 01304 if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 ) 01305 MatOp_Bin::makeExpr(res, 'a', e.a, -e.s*e.alpha); 01306 else if( e.b.data && e.alpha + e.beta == 0 && e.alpha*e.beta == -1 ) 01307 MatOp_Bin::makeExpr(res, 'a', e.a, e.b); 01308 else 01309 MatOp::abs(e, res); 01310 } 01311 01312 inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s) 01313 { 01314 res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s); 01315 } 01316 01317 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01318 01319 void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const 01320 { 01321 Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp; 01322 01323 if( e.flags == '*' ) 01324 cv::multiply(e.a, e.b, dst, e.alpha); 01325 else if( e.flags == '/' && e.b.data ) 01326 cv::divide(e.a, e.b, dst, e.alpha); 01327 else if( e.flags == '/' && !e.b.data ) 01328 cv::divide(e.alpha, e.a, dst ); 01329 else if( e.flags == '&' && e.b.data ) 01330 bitwise_and(e.a, e.b, dst); 01331 else if( e.flags == '&' && !e.b.data ) 01332 bitwise_and(e.a, e.s, dst); 01333 else if( e.flags == '|' && e.b.data ) 01334 bitwise_or(e.a, e.b, dst); 01335 else if( e.flags == '|' && !e.b.data ) 01336 bitwise_or(e.a, e.s, dst); 01337 else if( e.flags == '^' && e.b.data ) 01338 bitwise_xor(e.a, e.b, dst); 01339 else if( e.flags == '^' && !e.b.data ) 01340 bitwise_xor(e.a, e.s, dst); 01341 else if( e.flags == '~' && !e.b.data ) 01342 bitwise_not(e.a, dst); 01343 else if( e.flags == 'm' ) 01344 cv::min(e.a, e.b, dst); 01345 else if( e.flags == 'n' ) 01346 cv::min(e.a, e.s[0], dst); 01347 else if( e.flags == 'M' ) 01348 cv::max(e.a, e.b, dst); 01349 else if( e.flags == 'N' ) 01350 cv::max(e.a, e.s[0], dst); 01351 else if( e.flags == 'a' && e.b.data ) 01352 cv::absdiff(e.a, e.b, dst); 01353 else if( e.flags == 'a' && !e.b.data ) 01354 cv::absdiff(e.a, e.s, dst); 01355 else 01356 CV_Error(CV_StsError, "Unknown operation"); 01357 01358 if( dst.data != m.data ) 01359 dst.convertTo(m, _type); 01360 } 01361 01362 void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const 01363 { 01364 if( e.flags == '*' || e.flags == '/' ) 01365 { 01366 res = e; 01367 res.alpha *= s; 01368 } 01369 else 01370 MatOp::multiply(e, s, res); 01371 } 01372 01373 void MatOp_Bin::divide(double s, const MatExpr& e, MatExpr& res) const 01374 { 01375 if( e.flags == '/' && (!e.b.data || e.beta == 0) ) 01376 MatOp_AddEx::makeExpr(res, e.a, Mat(), s/e.alpha, 0); 01377 else 01378 MatOp::divide(s, e, res); 01379 } 01380 01381 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale) 01382 { 01383 res = MatExpr(&g_MatOp_Bin, op, a, b, Mat(), scale, b.data ? 1 : 0); 01384 } 01385 01386 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s) 01387 { 01388 res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s); 01389 } 01390 01391 /////////////////////////////////////////////////////////////////////////////////////////////////////// 01392 01393 void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int _type) const 01394 { 01395 Mat temp, &dst = _type == -1 || _type == CV_8U ? m : temp; 01396 01397 if( e.b.data ) 01398 cv::compare(e.a, e.b, dst, e.flags); 01399 else 01400 cv::compare(e.a, e.alpha, dst, e.flags); 01401 01402 if( dst.data != m.data ) 01403 dst.convertTo(m, _type); 01404 } 01405 01406 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b) 01407 { 01408 res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1); 01409 } 01410 01411 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha) 01412 { 01413 res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1); 01414 } 01415 01416 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 01417 01418 void MatOp_T::assign(const MatExpr& e, Mat& m, int _type) const 01419 { 01420 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; 01421 01422 cv::transpose(e.a, dst); 01423 01424 if( dst.data != m.data || e.alpha != 1 ) 01425 dst.convertTo(m, _type, e.alpha); 01426 } 01427 01428 void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const 01429 { 01430 res = e; 01431 res.alpha *= s; 01432 } 01433 01434 void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const 01435 { 01436 if( e.alpha == 1 ) 01437 MatOp_Identity::makeExpr(res, e.a); 01438 else 01439 MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0); 01440 } 01441 01442 inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha) 01443 { 01444 res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0); 01445 } 01446 01447 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 01448 01449 void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int _type) const 01450 { 01451 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; 01452 01453 cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags); 01454 if( dst.data != m.data ) 01455 dst.convertTo(m, _type); 01456 } 01457 01458 void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 01459 { 01460 bool i1 = isIdentity(e1), i2 = isIdentity(e2); 01461 double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; 01462 01463 if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) 01464 MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), 01465 e1.a, e1.b, alpha1, e2.a, alpha2); 01466 else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) 01467 MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), 01468 e2.a, e2.b, alpha2, e1.a, alpha1); 01469 else if( this == e2.op ) 01470 MatOp::add(e1, e2, res); 01471 else 01472 e2.op->add(e1, e2, res); 01473 } 01474 01475 void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 01476 { 01477 bool i1 = isIdentity(e1), i2 = isIdentity(e2); 01478 double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; 01479 01480 if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) 01481 MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), 01482 e1.a, e1.b, alpha1, e2.a, -alpha2); 01483 else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) 01484 MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), 01485 e2.a, e2.b, -alpha2, e1.a, alpha1); 01486 else if( this == e2.op ) 01487 MatOp::subtract(e1, e2, res); 01488 else 01489 e2.op->subtract(e1, e2, res); 01490 } 01491 01492 void MatOp_GEMM::multiply(const MatExpr& e, double s, MatExpr& res) const 01493 { 01494 res = e; 01495 res.alpha *= s; 01496 res.beta *= s; 01497 } 01498 01499 void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const 01500 { 01501 res = e; 01502 res.flags = (!(e.flags & CV_GEMM_A_T) ? CV_GEMM_B_T : 0) | 01503 (!(e.flags & CV_GEMM_B_T) ? CV_GEMM_A_T : 0) | 01504 (!(e.flags & CV_GEMM_C_T) ? CV_GEMM_C_T : 0); 01505 swap(res.a, res.b); 01506 } 01507 01508 inline void MatOp_GEMM::makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, 01509 double alpha, const Mat& c, double beta) 01510 { 01511 res = MatExpr(&g_MatOp_GEMM, flags, a, b, c, alpha, beta); 01512 } 01513 01514 /////////////////////////////////////////////////////////////////////////////////////////////////////// 01515 01516 void MatOp_Invert::assign(const MatExpr& e, Mat& m, int _type) const 01517 { 01518 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; 01519 01520 cv::invert(e.a, dst, e.flags); 01521 if( dst.data != m.data ) 01522 dst.convertTo(m, _type); 01523 } 01524 01525 void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const 01526 { 01527 if( isInv(e1) && isIdentity(e2) ) 01528 MatOp_Solve::makeExpr(res, e1.flags, e1.a, e2.a); 01529 else if( this == e2.op ) 01530 MatOp::matmul(e1, e2, res); 01531 else 01532 e2.op->matmul(e1, e2, res); 01533 } 01534 01535 inline void MatOp_Invert::makeExpr(MatExpr& res, int method, const Mat& m) 01536 { 01537 res = MatExpr(&g_MatOp_Invert, method, m, Mat(), Mat(), 1, 0); 01538 } 01539 01540 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 01541 01542 void MatOp_Solve::assign(const MatExpr& e, Mat& m, int _type) const 01543 { 01544 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp; 01545 01546 cv::solve(e.a, e.b, dst, e.flags); 01547 if( dst.data != m.data ) 01548 dst.convertTo(m, _type); 01549 } 01550 01551 inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b) 01552 { 01553 res = MatExpr(&g_MatOp_Solve, method, a, b, Mat(), 1, 1); 01554 } 01555 01556 ////////////////////////////////////////////////////////////////////////////////////////////////////////// 01557 01558 void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const 01559 { 01560 if( _type == -1 ) 01561 _type = e.a.type(); 01562 01563 if( e.a.dims <= 2 ) 01564 m.create(e.a.size(), _type); 01565 else 01566 m.create(e.a.dims, e.a.size, _type); 01567 01568 if( e.flags == 'I' && e.a.dims <= 2 ) 01569 setIdentity(m, Scalar(e.alpha)); 01570 else if( e.flags == '0' ) 01571 m = Scalar(); 01572 else if( e.flags == '1' ) 01573 m = Scalar(e.alpha); 01574 else 01575 CV_Error(CV_StsError, "Invalid matrix initializer type"); 01576 } 01577 01578 void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const 01579 { 01580 res = e; 01581 res.alpha *= s; 01582 } 01583 01584 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha) 01585 { 01586 res = MatExpr(getGlobalMatOpInitializer(), method, Mat(sz, type, (void*)(size_t)0xEEEEEEEE), Mat(), Mat(), alpha, 0); 01587 } 01588 01589 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha) 01590 { 01591 res = MatExpr(getGlobalMatOpInitializer(), method, Mat(ndims, sizes, type, (void*)(size_t)0xEEEEEEEE), Mat(), Mat(), alpha, 0); 01592 } 01593 01594 /////////////////////////////////////////////////////////////////////////////////////////////////////////// 01595 01596 MatExpr Mat::t() const 01597 { 01598 MatExpr e; 01599 MatOp_T::makeExpr(e, *this); 01600 return e; 01601 } 01602 01603 MatExpr Mat::inv(int method) const 01604 { 01605 MatExpr e; 01606 MatOp_Invert::makeExpr(e, method, *this); 01607 return e; 01608 } 01609 01610 01611 MatExpr Mat::mul(InputArray m, double scale) const 01612 { 01613 MatExpr e; 01614 if(m.kind() == _InputArray::EXPR) 01615 { 01616 const MatExpr& me = *(const MatExpr*)m.getObj(); 01617 me.op->multiply(MatExpr(*this), me, e, scale); 01618 } 01619 else 01620 MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale); 01621 return e; 01622 } 01623 01624 MatExpr Mat::zeros(int rows, int cols, int type) 01625 { 01626 MatExpr e; 01627 MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type); 01628 return e; 01629 } 01630 01631 MatExpr Mat::zeros(Size size, int type) 01632 { 01633 MatExpr e; 01634 MatOp_Initializer::makeExpr(e, '0', size, type); 01635 return e; 01636 } 01637 01638 MatExpr Mat::zeros(int ndims, const int* sizes, int type) 01639 { 01640 MatExpr e; 01641 MatOp_Initializer::makeExpr(e, '0', ndims, sizes, type); 01642 return e; 01643 } 01644 01645 MatExpr Mat::ones(int rows, int cols, int type) 01646 { 01647 MatExpr e; 01648 MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type); 01649 return e; 01650 } 01651 01652 MatExpr Mat::ones(Size size, int type) 01653 { 01654 MatExpr e; 01655 MatOp_Initializer::makeExpr(e, '1', size, type); 01656 return e; 01657 } 01658 01659 MatExpr Mat::ones(int ndims, const int* sizes, int type) 01660 { 01661 MatExpr e; 01662 MatOp_Initializer::makeExpr(e, '1', ndims, sizes, type); 01663 return e; 01664 } 01665 01666 MatExpr Mat::eye(int rows, int cols, int type) 01667 { 01668 MatExpr e; 01669 MatOp_Initializer::makeExpr(e, 'I', Size(cols, rows), type); 01670 return e; 01671 } 01672 01673 MatExpr Mat::eye(Size size, int type) 01674 { 01675 MatExpr e; 01676 MatOp_Initializer::makeExpr(e, 'I', size, type); 01677 return e; 01678 } 01679 01680 } 01681 01682 /* End of file. */ 01683
Generated on Tue Jul 12 2022 14:47:23 by
