1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
22 //
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
26 //
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 /* ////////////////////////////////////////////////////////////////////
44 //
45 // Mat basic operations: Copy, Set
46 //
47 // */
48
49 #include "precomp.hpp"
50
51 namespace cv
52 {
53
54 class MatOp_Identity : public MatOp
55 {
56 public:
MatOp_Identity()57 MatOp_Identity() {}
~MatOp_Identity()58 virtual ~MatOp_Identity() {}
59
elementWise(const MatExpr &) const60 bool elementWise(const MatExpr& /*expr*/) const { return true; }
61 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
62
63 static void makeExpr(MatExpr& res, const Mat& m);
64 };
65
66 static MatOp_Identity g_MatOp_Identity;
67
68 class MatOp_AddEx : public MatOp
69 {
70 public:
MatOp_AddEx()71 MatOp_AddEx() {}
~MatOp_AddEx()72 virtual ~MatOp_AddEx() {}
73
elementWise(const MatExpr &) const74 bool elementWise(const MatExpr& /*expr*/) const { return true; }
75 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
76
77 void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const;
78 void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
79 void multiply(const MatExpr& e1, double s, MatExpr& res) const;
80 void divide(double s, const MatExpr& e, MatExpr& res) const;
81
82 void transpose(const MatExpr& e1, MatExpr& res) const;
83 void abs(const MatExpr& expr, MatExpr& res) const;
84
85 static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar());
86 };
87
88 static MatOp_AddEx g_MatOp_AddEx;
89
90 class MatOp_Bin : public MatOp
91 {
92 public:
MatOp_Bin()93 MatOp_Bin() {}
~MatOp_Bin()94 virtual ~MatOp_Bin() {}
95
elementWise(const MatExpr &) const96 bool elementWise(const MatExpr& /*expr*/) const { return true; }
97 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
98
99 void multiply(const MatExpr& e1, double s, MatExpr& res) const;
100 void divide(double s, const MatExpr& e, MatExpr& res) const;
101
102 static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1);
103 static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s);
104 };
105
106 static MatOp_Bin g_MatOp_Bin;
107
108 class MatOp_Cmp : public MatOp
109 {
110 public:
MatOp_Cmp()111 MatOp_Cmp() {}
~MatOp_Cmp()112 virtual ~MatOp_Cmp() {}
113
elementWise(const MatExpr &) const114 bool elementWise(const MatExpr& /*expr*/) const { return true; }
115 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
116
117 static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b);
118 static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha);
119 };
120
121 static MatOp_Cmp g_MatOp_Cmp;
122
123 class MatOp_GEMM : public MatOp
124 {
125 public:
MatOp_GEMM()126 MatOp_GEMM() {}
~MatOp_GEMM()127 virtual ~MatOp_GEMM() {}
128
elementWise(const MatExpr &) const129 bool elementWise(const MatExpr& /*expr*/) const { return false; }
130 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
131
132 void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
133 void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
134 void multiply(const MatExpr& e, double s, MatExpr& res) const;
135
136 void transpose(const MatExpr& expr, MatExpr& res) const;
137
138 static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b,
139 double alpha=1, const Mat& c=Mat(), double beta=1);
140 };
141
142 static MatOp_GEMM g_MatOp_GEMM;
143
144 class MatOp_Invert : public MatOp
145 {
146 public:
MatOp_Invert()147 MatOp_Invert() {}
~MatOp_Invert()148 virtual ~MatOp_Invert() {}
149
elementWise(const MatExpr &) const150 bool elementWise(const MatExpr& /*expr*/) const { return false; }
151 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
152
153 void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
154
155 static void makeExpr(MatExpr& res, int method, const Mat& m);
156 };
157
158 static MatOp_Invert g_MatOp_Invert;
159
160 class MatOp_T : public MatOp
161 {
162 public:
MatOp_T()163 MatOp_T() {}
~MatOp_T()164 virtual ~MatOp_T() {}
165
elementWise(const MatExpr &) const166 bool elementWise(const MatExpr& /*expr*/) const { return false; }
167 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
168
169 void multiply(const MatExpr& e1, double s, MatExpr& res) const;
170 void transpose(const MatExpr& expr, MatExpr& res) const;
171
172 static void makeExpr(MatExpr& res, const Mat& a, double alpha=1);
173 };
174
175 static MatOp_T g_MatOp_T;
176
177 class MatOp_Solve : public MatOp
178 {
179 public:
MatOp_Solve()180 MatOp_Solve() {}
~MatOp_Solve()181 virtual ~MatOp_Solve() {}
182
elementWise(const MatExpr &) const183 bool elementWise(const MatExpr& /*expr*/) const { return false; }
184 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
185
186 static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b);
187 };
188
189 static MatOp_Solve g_MatOp_Solve;
190
191 class MatOp_Initializer : public MatOp
192 {
193 public:
MatOp_Initializer()194 MatOp_Initializer() {}
~MatOp_Initializer()195 virtual ~MatOp_Initializer() {}
196
elementWise(const MatExpr &) const197 bool elementWise(const MatExpr& /*expr*/) const { return false; }
198 void assign(const MatExpr& expr, Mat& m, int type=-1) const;
199
200 void multiply(const MatExpr& e, double s, MatExpr& res) const;
201
202 static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1);
203 static void makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha=1);
204 };
205
getGlobalMatOpInitializer()206 static MatOp_Initializer* getGlobalMatOpInitializer()
207 {
208 static MatOp_Initializer initializer;
209 return &initializer;
210 }
211
isIdentity(const MatExpr & e)212 static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; }
isAddEx(const MatExpr & e)213 static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; }
isScaled(const MatExpr & e)214 static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); }
isBin(const MatExpr & e,char c)215 static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; }
isCmp(const MatExpr & e)216 static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; }
isReciprocal(const MatExpr & e)217 static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); }
isT(const MatExpr & e)218 static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; }
isInv(const MatExpr & e)219 static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; }
isSolve(const MatExpr & e)220 static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; }
isGEMM(const MatExpr & e)221 static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; }
isMatProd(const MatExpr & e)222 static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); }
isInitializer(const MatExpr & e)223 static inline bool isInitializer(const MatExpr& e) { return e.op == getGlobalMatOpInitializer(); }
224
225 /////////////////////////////////////////////////////////////////////////////////////////////////////
226
MatOp()227 MatOp::MatOp() {}
~MatOp()228 MatOp::~MatOp() {}
229
230
elementWise(const MatExpr &) const231 bool MatOp::elementWise(const MatExpr& /*expr*/) const
232 {
233 return false;
234 }
235
roi(const MatExpr & expr,const Range & rowRange,const Range & colRange,MatExpr & e) const236 void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const
237 {
238 if( elementWise(expr) )
239 {
240 e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(),
241 expr.alpha, expr.beta, expr.s);
242 if(expr.a.data)
243 e.a = expr.a(rowRange, colRange);
244 if(expr.b.data)
245 e.b = expr.b(rowRange, colRange);
246 if(expr.c.data)
247 e.c = expr.c(rowRange, colRange);
248 }
249 else
250 {
251 Mat m;
252 expr.op->assign(expr, m);
253 e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat());
254 }
255 }
256
diag(const MatExpr & expr,int d,MatExpr & e) const257 void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const
258 {
259 if( elementWise(expr) )
260 {
261 e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(),
262 expr.alpha, expr.beta, expr.s);
263 if(expr.a.data)
264 e.a = expr.a.diag(d);
265 if(expr.b.data)
266 e.b = expr.b.diag(d);
267 if(expr.c.data)
268 e.c = expr.c.diag(d);
269 }
270 else
271 {
272 Mat m;
273 expr.op->assign(expr, m);
274 e = MatExpr(&g_MatOp_Identity, 0, m.diag(d), Mat(), Mat());
275 }
276 }
277
278
augAssignAdd(const MatExpr & expr,Mat & m) const279 void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const
280 {
281 Mat temp;
282 expr.op->assign(expr, temp);
283 m += temp;
284 }
285
286
augAssignSubtract(const MatExpr & expr,Mat & m) const287 void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const
288 {
289 Mat temp;
290 expr.op->assign(expr, temp);
291 m -= temp;
292 }
293
294
augAssignMultiply(const MatExpr & expr,Mat & m) const295 void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const
296 {
297 Mat temp;
298 expr.op->assign(expr, temp);
299 m *= temp;
300 }
301
302
augAssignDivide(const MatExpr & expr,Mat & m) const303 void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const
304 {
305 Mat temp;
306 expr.op->assign(expr, temp);
307 m /= temp;
308 }
309
310
augAssignAnd(const MatExpr & expr,Mat & m) const311 void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const
312 {
313 Mat temp;
314 expr.op->assign(expr, temp);
315 m &= temp;
316 }
317
318
augAssignOr(const MatExpr & expr,Mat & m) const319 void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const
320 {
321 Mat temp;
322 expr.op->assign(expr, temp);
323 m |= temp;
324 }
325
326
augAssignXor(const MatExpr & expr,Mat & m) const327 void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const
328 {
329 Mat temp;
330 expr.op->assign(expr, temp);
331 m ^= temp;
332 }
333
334
add(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const335 void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
336 {
337 if( this == e2.op )
338 {
339 double alpha = 1, beta = 1;
340 Scalar s;
341 Mat m1, m2;
342 if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) )
343 {
344 m1 = e1.a;
345 alpha = e1.alpha;
346 s = e1.s;
347 }
348 else
349 e1.op->assign(e1, m1);
350
351 if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
352 {
353 m2 = e2.a;
354 beta = e2.alpha;
355 s += e2.s;
356 }
357 else
358 e2.op->assign(e2, m2);
359 MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
360 }
361 else
362 e2.op->add(e1, e2, res);
363 }
364
365
add(const MatExpr & expr1,const Scalar & s,MatExpr & res) const366 void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const
367 {
368 Mat m1;
369 expr1.op->assign(expr1, m1);
370 MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s);
371 }
372
373
subtract(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const374 void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
375 {
376 if( this == e2.op )
377 {
378 double alpha = 1, beta = -1;
379 Scalar s;
380 Mat m1, m2;
381 if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) )
382 {
383 m1 = e1.a;
384 alpha = e1.alpha;
385 s = e1.s;
386 }
387 else
388 e1.op->assign(e1, m1);
389
390 if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
391 {
392 m2 = e2.a;
393 beta = -e2.alpha;
394 s -= e2.s;
395 }
396 else
397 e2.op->assign(e2, m2);
398 MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
399 }
400 else
401 e2.op->subtract(e1, e2, res);
402 }
403
404
subtract(const Scalar & s,const MatExpr & expr,MatExpr & res) const405 void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const
406 {
407 Mat m;
408 expr.op->assign(expr, m);
409 MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s);
410 }
411
412
multiply(const MatExpr & e1,const MatExpr & e2,MatExpr & res,double scale) const413 void MatOp::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
414 {
415 if( this == e2.op )
416 {
417 Mat m1, m2;
418
419 if( isReciprocal(e1) )
420 {
421 if( isScaled(e2) )
422 {
423 scale *= e2.alpha;
424 m2 = e2.a;
425 }
426 else
427 e2.op->assign(e2, m2);
428
429 MatOp_Bin::makeExpr(res, '/', m2, e1.a, scale/e1.alpha);
430 }
431 else
432 {
433 char op = '*';
434 if( isScaled(e1) )
435 {
436 m1 = e1.a;
437 scale *= e1.alpha;
438 }
439 else
440 e1.op->assign(e1, m1);
441
442 if( isScaled(e2) )
443 {
444 m2 = e2.a;
445 scale *= e2.alpha;
446 }
447 else if( isReciprocal(e2) )
448 {
449 op = '/';
450 m2 = e2.a;
451 scale /= e2.alpha;
452 }
453 else
454 e2.op->assign(e2, m2);
455
456 MatOp_Bin::makeExpr(res, op, m1, m2, scale);
457 }
458 }
459 else
460 e2.op->multiply(e1, e2, res, scale);
461 }
462
463
multiply(const MatExpr & expr,double s,MatExpr & res) const464 void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const
465 {
466 Mat m;
467 expr.op->assign(expr, m);
468 MatOp_AddEx::makeExpr(res, m, Mat(), s, 0);
469 }
470
471
divide(const MatExpr & e1,const MatExpr & e2,MatExpr & res,double scale) const472 void MatOp::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
473 {
474 if( this == e2.op )
475 {
476 if( isReciprocal(e1) && isReciprocal(e2) )
477 MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha/e2.alpha);
478 else
479 {
480 Mat m1, m2;
481 char op = '/';
482
483 if( isScaled(e1) )
484 {
485 m1 = e1.a;
486 scale *= e1.alpha;
487 }
488 else
489 e1.op->assign(e1, m1);
490
491 if( isScaled(e2) )
492 {
493 m2 = e2.a;
494 scale /= e2.alpha;
495 }
496 else if( isReciprocal(e2) )
497 {
498 m2 = e2.a;
499 scale /= e2.alpha;
500 op = '*';
501 }
502 else
503 e2.op->assign(e2, m2);
504 MatOp_Bin::makeExpr(res, op, m1, m2, scale);
505 }
506 }
507 else
508 e2.op->divide(e1, e2, res, scale);
509 }
510
511
divide(double s,const MatExpr & expr,MatExpr & res) const512 void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const
513 {
514 Mat m;
515 expr.op->assign(expr, m);
516 MatOp_Bin::makeExpr(res, '/', m, Mat(), s);
517 }
518
519
abs(const MatExpr & expr,MatExpr & res) const520 void MatOp::abs(const MatExpr& expr, MatExpr& res) const
521 {
522 Mat m;
523 expr.op->assign(expr, m);
524 MatOp_Bin::makeExpr(res, 'a', m, Mat());
525 }
526
527
transpose(const MatExpr & expr,MatExpr & res) const528 void MatOp::transpose(const MatExpr& expr, MatExpr& res) const
529 {
530 Mat m;
531 expr.op->assign(expr, m);
532 MatOp_T::makeExpr(res, m, 1);
533 }
534
535
matmul(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const536 void MatOp::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
537 {
538 if( this == e2.op )
539 {
540 double scale = 1;
541 int flags = 0;
542 Mat m1, m2;
543
544 if( isT(e1) )
545 {
546 flags = CV_GEMM_A_T;
547 scale = e1.alpha;
548 m1 = e1.a;
549 }
550 else if( isScaled(e1) )
551 {
552 scale = e1.alpha;
553 m1 = e1.a;
554 }
555 else
556 e1.op->assign(e1, m1);
557
558 if( isT(e2) )
559 {
560 flags |= CV_GEMM_B_T;
561 scale *= e2.alpha;
562 m2 = e2.a;
563 }
564 else if( isScaled(e2) )
565 {
566 scale *= e2.alpha;
567 m2 = e2.a;
568 }
569 else
570 e2.op->assign(e2, m2);
571
572 MatOp_GEMM::makeExpr(res, flags, m1, m2, scale);
573 }
574 else
575 e2.op->matmul(e1, e2, res);
576 }
577
578
invert(const MatExpr & expr,int method,MatExpr & res) const579 void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const
580 {
581 Mat m;
582 expr.op->assign(expr, m);
583 MatOp_Invert::makeExpr(res, method, m);
584 }
585
586
size(const MatExpr & expr) const587 Size MatOp::size(const MatExpr& expr) const
588 {
589 return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size();
590 }
591
type(const MatExpr & expr) const592 int MatOp::type(const MatExpr& expr) const
593 {
594 return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type();
595 }
596
597 //////////////////////////////////////////////////////////////////////////////////////////////////
598
MatExpr(const Mat & m)599 MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar())
600 {
601 }
602
row(int y) const603 MatExpr MatExpr::row(int y) const
604 {
605 MatExpr e;
606 op->roi(*this, Range(y, y+1), Range::all(), e);
607 return e;
608 }
609
col(int x) const610 MatExpr MatExpr::col(int x) const
611 {
612 MatExpr e;
613 op->roi(*this, Range::all(), Range(x, x+1), e);
614 return e;
615 }
616
diag(int d) const617 MatExpr MatExpr::diag(int d) const
618 {
619 MatExpr e;
620 op->diag(*this, d, e);
621 return e;
622 }
623
operator ()(const Range & rowRange,const Range & colRange) const624 MatExpr MatExpr::operator()( const Range& rowRange, const Range& colRange ) const
625 {
626 MatExpr e;
627 op->roi(*this, rowRange, colRange, e);
628 return e;
629 }
630
operator ()(const Rect & roi) const631 MatExpr MatExpr::operator()( const Rect& roi ) const
632 {
633 MatExpr e;
634 op->roi(*this, Range(roi.y, roi.y + roi.height), Range(roi.x, roi.x + roi.width), e);
635 return e;
636 }
637
cross(const Mat & m) const638 Mat MatExpr::cross(const Mat& m) const
639 {
640 return ((Mat)*this).cross(m);
641 }
642
dot(const Mat & m) const643 double MatExpr::dot(const Mat& m) const
644 {
645 return ((Mat)*this).dot(m);
646 }
647
t() const648 MatExpr MatExpr::t() const
649 {
650 MatExpr e;
651 op->transpose(*this, e);
652 return e;
653 }
654
inv(int method) const655 MatExpr MatExpr::inv(int method) const
656 {
657 MatExpr e;
658 op->invert(*this, method, e);
659 return e;
660 }
661
mul(const MatExpr & e,double scale) const662 MatExpr MatExpr::mul(const MatExpr& e, double scale) const
663 {
664 MatExpr en;
665 op->multiply(*this, e, en, scale);
666 return en;
667 }
668
mul(const Mat & m,double scale) const669 MatExpr MatExpr::mul(const Mat& m, double scale) const
670 {
671 MatExpr e;
672 op->multiply(*this, MatExpr(m), e, scale);
673 return e;
674 }
675
operator +(const Mat & a,const Mat & b)676 MatExpr operator + (const Mat& a, const Mat& b)
677 {
678 MatExpr e;
679 MatOp_AddEx::makeExpr(e, a, b, 1, 1);
680 return e;
681 }
682
operator +(const Mat & a,const Scalar & s)683 MatExpr operator + (const Mat& a, const Scalar& s)
684 {
685 MatExpr e;
686 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
687 return e;
688 }
689
operator +(const Scalar & s,const Mat & a)690 MatExpr operator + (const Scalar& s, const Mat& a)
691 {
692 MatExpr e;
693 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
694 return e;
695 }
696
operator +(const MatExpr & e,const Mat & m)697 MatExpr operator + (const MatExpr& e, const Mat& m)
698 {
699 MatExpr en;
700 e.op->add(e, MatExpr(m), en);
701 return en;
702 }
703
operator +(const Mat & m,const MatExpr & e)704 MatExpr operator + (const Mat& m, const MatExpr& e)
705 {
706 MatExpr en;
707 e.op->add(e, MatExpr(m), en);
708 return en;
709 }
710
operator +(const MatExpr & e,const Scalar & s)711 MatExpr operator + (const MatExpr& e, const Scalar& s)
712 {
713 MatExpr en;
714 e.op->add(e, s, en);
715 return en;
716 }
717
operator +(const Scalar & s,const MatExpr & e)718 MatExpr operator + (const Scalar& s, const MatExpr& e)
719 {
720 MatExpr en;
721 e.op->add(e, s, en);
722 return en;
723 }
724
operator +(const MatExpr & e1,const MatExpr & e2)725 MatExpr operator + (const MatExpr& e1, const MatExpr& e2)
726 {
727 MatExpr en;
728 e1.op->add(e1, e2, en);
729 return en;
730 }
731
operator -(const Mat & a,const Mat & b)732 MatExpr operator - (const Mat& a, const Mat& b)
733 {
734 MatExpr e;
735 MatOp_AddEx::makeExpr(e, a, b, 1, -1);
736 return e;
737 }
738
operator -(const Mat & a,const Scalar & s)739 MatExpr operator - (const Mat& a, const Scalar& s)
740 {
741 MatExpr e;
742 MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s);
743 return e;
744 }
745
operator -(const Scalar & s,const Mat & a)746 MatExpr operator - (const Scalar& s, const Mat& a)
747 {
748 MatExpr e;
749 MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s);
750 return e;
751 }
752
operator -(const MatExpr & e,const Mat & m)753 MatExpr operator - (const MatExpr& e, const Mat& m)
754 {
755 MatExpr en;
756 e.op->subtract(e, MatExpr(m), en);
757 return en;
758 }
759
operator -(const Mat & m,const MatExpr & e)760 MatExpr operator - (const Mat& m, const MatExpr& e)
761 {
762 MatExpr en;
763 e.op->subtract(MatExpr(m), e, en);
764 return en;
765 }
766
operator -(const MatExpr & e,const Scalar & s)767 MatExpr operator - (const MatExpr& e, const Scalar& s)
768 {
769 MatExpr en;
770 e.op->add(e, -s, en);
771 return en;
772 }
773
operator -(const Scalar & s,const MatExpr & e)774 MatExpr operator - (const Scalar& s, const MatExpr& e)
775 {
776 MatExpr en;
777 e.op->subtract(s, e, en);
778 return en;
779 }
780
operator -(const MatExpr & e1,const MatExpr & e2)781 MatExpr operator - (const MatExpr& e1, const MatExpr& e2)
782 {
783 MatExpr en;
784 e1.op->subtract(e1, e2, en);
785 return en;
786 }
787
operator -(const Mat & m)788 MatExpr operator - (const Mat& m)
789 {
790 MatExpr e;
791 MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0);
792 return e;
793 }
794
operator -(const MatExpr & e)795 MatExpr operator - (const MatExpr& e)
796 {
797 MatExpr en;
798 e.op->subtract(Scalar(0), e, en);
799 return en;
800 }
801
operator *(const Mat & a,const Mat & b)802 MatExpr operator * (const Mat& a, const Mat& b)
803 {
804 MatExpr e;
805 MatOp_GEMM::makeExpr(e, 0, a, b);
806 return e;
807 }
808
operator *(const Mat & a,double s)809 MatExpr operator * (const Mat& a, double s)
810 {
811 MatExpr e;
812 MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
813 return e;
814 }
815
operator *(double s,const Mat & a)816 MatExpr operator * (double s, const Mat& a)
817 {
818 MatExpr e;
819 MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
820 return e;
821 }
822
operator *(const MatExpr & e,const Mat & m)823 MatExpr operator * (const MatExpr& e, const Mat& m)
824 {
825 MatExpr en;
826 e.op->matmul(e, MatExpr(m), en);
827 return en;
828 }
829
operator *(const Mat & m,const MatExpr & e)830 MatExpr operator * (const Mat& m, const MatExpr& e)
831 {
832 MatExpr en;
833 e.op->matmul(MatExpr(m), e, en);
834 return en;
835 }
836
operator *(const MatExpr & e,double s)837 MatExpr operator * (const MatExpr& e, double s)
838 {
839 MatExpr en;
840 e.op->multiply(e, s, en);
841 return en;
842 }
843
operator *(double s,const MatExpr & e)844 MatExpr operator * (double s, const MatExpr& e)
845 {
846 MatExpr en;
847 e.op->multiply(e, s, en);
848 return en;
849 }
850
operator *(const MatExpr & e1,const MatExpr & e2)851 MatExpr operator * (const MatExpr& e1, const MatExpr& e2)
852 {
853 MatExpr en;
854 e1.op->matmul(e1, e2, en);
855 return en;
856 }
857
operator /(const Mat & a,const Mat & b)858 MatExpr operator / (const Mat& a, const Mat& b)
859 {
860 MatExpr e;
861 MatOp_Bin::makeExpr(e, '/', a, b);
862 return e;
863 }
864
operator /(const Mat & a,double s)865 MatExpr operator / (const Mat& a, double s)
866 {
867 MatExpr e;
868 MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0);
869 return e;
870 }
871
operator /(double s,const Mat & a)872 MatExpr operator / (double s, const Mat& a)
873 {
874 MatExpr e;
875 MatOp_Bin::makeExpr(e, '/', a, Mat(), s);
876 return e;
877 }
878
operator /(const MatExpr & e,const Mat & m)879 MatExpr operator / (const MatExpr& e, const Mat& m)
880 {
881 MatExpr en;
882 e.op->divide(e, MatExpr(m), en);
883 return en;
884 }
885
operator /(const Mat & m,const MatExpr & e)886 MatExpr operator / (const Mat& m, const MatExpr& e)
887 {
888 MatExpr en;
889 e.op->divide(MatExpr(m), e, en);
890 return en;
891 }
892
operator /(const MatExpr & e,double s)893 MatExpr operator / (const MatExpr& e, double s)
894 {
895 MatExpr en;
896 e.op->multiply(e, 1./s, en);
897 return en;
898 }
899
operator /(double s,const MatExpr & e)900 MatExpr operator / (double s, const MatExpr& e)
901 {
902 MatExpr en;
903 e.op->divide(s, e, en);
904 return en;
905 }
906
operator /(const MatExpr & e1,const MatExpr & e2)907 MatExpr operator / (const MatExpr& e1, const MatExpr& e2)
908 {
909 MatExpr en;
910 e1.op->divide(e1, e2, en);
911 return en;
912 }
913
operator <(const Mat & a,const Mat & b)914 MatExpr operator < (const Mat& a, const Mat& b)
915 {
916 MatExpr e;
917 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b);
918 return e;
919 }
920
operator <(const Mat & a,double s)921 MatExpr operator < (const Mat& a, double s)
922 {
923 MatExpr e;
924 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
925 return e;
926 }
927
operator <(double s,const Mat & a)928 MatExpr operator < (double s, const Mat& a)
929 {
930 MatExpr e;
931 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
932 return e;
933 }
934
operator <=(const Mat & a,const Mat & b)935 MatExpr operator <= (const Mat& a, const Mat& b)
936 {
937 MatExpr e;
938 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b);
939 return e;
940 }
941
operator <=(const Mat & a,double s)942 MatExpr operator <= (const Mat& a, double s)
943 {
944 MatExpr e;
945 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
946 return e;
947 }
948
operator <=(double s,const Mat & a)949 MatExpr operator <= (double s, const Mat& a)
950 {
951 MatExpr e;
952 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
953 return e;
954 }
955
operator ==(const Mat & a,const Mat & b)956 MatExpr operator == (const Mat& a, const Mat& b)
957 {
958 MatExpr e;
959 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b);
960 return e;
961 }
962
operator ==(const Mat & a,double s)963 MatExpr operator == (const Mat& a, double s)
964 {
965 MatExpr e;
966 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
967 return e;
968 }
969
operator ==(double s,const Mat & a)970 MatExpr operator == (double s, const Mat& a)
971 {
972 MatExpr e;
973 MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
974 return e;
975 }
976
operator !=(const Mat & a,const Mat & b)977 MatExpr operator != (const Mat& a, const Mat& b)
978 {
979 MatExpr e;
980 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b);
981 return e;
982 }
983
operator !=(const Mat & a,double s)984 MatExpr operator != (const Mat& a, double s)
985 {
986 MatExpr e;
987 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
988 return e;
989 }
990
operator !=(double s,const Mat & a)991 MatExpr operator != (double s, const Mat& a)
992 {
993 MatExpr e;
994 MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
995 return e;
996 }
997
operator >=(const Mat & a,const Mat & b)998 MatExpr operator >= (const Mat& a, const Mat& b)
999 {
1000 MatExpr e;
1001 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b);
1002 return e;
1003 }
1004
operator >=(const Mat & a,double s)1005 MatExpr operator >= (const Mat& a, double s)
1006 {
1007 MatExpr e;
1008 MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
1009 return e;
1010 }
1011
operator >=(double s,const Mat & a)1012 MatExpr operator >= (double s, const Mat& a)
1013 {
1014 MatExpr e;
1015 MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
1016 return e;
1017 }
1018
operator >(const Mat & a,const Mat & b)1019 MatExpr operator > (const Mat& a, const Mat& b)
1020 {
1021 MatExpr e;
1022 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b);
1023 return e;
1024 }
1025
operator >(const Mat & a,double s)1026 MatExpr operator > (const Mat& a, double s)
1027 {
1028 MatExpr e;
1029 MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
1030 return e;
1031 }
1032
operator >(double s,const Mat & a)1033 MatExpr operator > (double s, const Mat& a)
1034 {
1035 MatExpr e;
1036 MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
1037 return e;
1038 }
1039
min(const Mat & a,const Mat & b)1040 MatExpr min(const Mat& a, const Mat& b)
1041 {
1042 MatExpr e;
1043 MatOp_Bin::makeExpr(e, 'm', a, b);
1044 return e;
1045 }
1046
min(const Mat & a,double s)1047 MatExpr min(const Mat& a, double s)
1048 {
1049 MatExpr e;
1050 MatOp_Bin::makeExpr(e, 'n', a, s);
1051 return e;
1052 }
1053
min(double s,const Mat & a)1054 MatExpr min(double s, const Mat& a)
1055 {
1056 MatExpr e;
1057 MatOp_Bin::makeExpr(e, 'n', a, s);
1058 return e;
1059 }
1060
max(const Mat & a,const Mat & b)1061 MatExpr max(const Mat& a, const Mat& b)
1062 {
1063 MatExpr e;
1064 MatOp_Bin::makeExpr(e, 'M', a, b);
1065 return e;
1066 }
1067
max(const Mat & a,double s)1068 MatExpr max(const Mat& a, double s)
1069 {
1070 MatExpr e;
1071 MatOp_Bin::makeExpr(e, 'N', a, s);
1072 return e;
1073 }
1074
max(double s,const Mat & a)1075 MatExpr max(double s, const Mat& a)
1076 {
1077 MatExpr e;
1078 MatOp_Bin::makeExpr(e, 'N', a, s);
1079 return e;
1080 }
1081
operator &(const Mat & a,const Mat & b)1082 MatExpr operator & (const Mat& a, const Mat& b)
1083 {
1084 MatExpr e;
1085 MatOp_Bin::makeExpr(e, '&', a, b);
1086 return e;
1087 }
1088
operator &(const Mat & a,const Scalar & s)1089 MatExpr operator & (const Mat& a, const Scalar& s)
1090 {
1091 MatExpr e;
1092 MatOp_Bin::makeExpr(e, '&', a, s);
1093 return e;
1094 }
1095
operator &(const Scalar & s,const Mat & a)1096 MatExpr operator & (const Scalar& s, const Mat& a)
1097 {
1098 MatExpr e;
1099 MatOp_Bin::makeExpr(e, '&', a, s);
1100 return e;
1101 }
1102
operator |(const Mat & a,const Mat & b)1103 MatExpr operator | (const Mat& a, const Mat& b)
1104 {
1105 MatExpr e;
1106 MatOp_Bin::makeExpr(e, '|', a, b);
1107 return e;
1108 }
1109
operator |(const Mat & a,const Scalar & s)1110 MatExpr operator | (const Mat& a, const Scalar& s)
1111 {
1112 MatExpr e;
1113 MatOp_Bin::makeExpr(e, '|', a, s);
1114 return e;
1115 }
1116
operator |(const Scalar & s,const Mat & a)1117 MatExpr operator | (const Scalar& s, const Mat& a)
1118 {
1119 MatExpr e;
1120 MatOp_Bin::makeExpr(e, '|', a, s);
1121 return e;
1122 }
1123
operator ^(const Mat & a,const Mat & b)1124 MatExpr operator ^ (const Mat& a, const Mat& b)
1125 {
1126 MatExpr e;
1127 MatOp_Bin::makeExpr(e, '^', a, b);
1128 return e;
1129 }
1130
operator ^(const Mat & a,const Scalar & s)1131 MatExpr operator ^ (const Mat& a, const Scalar& s)
1132 {
1133 MatExpr e;
1134 MatOp_Bin::makeExpr(e, '^', a, s);
1135 return e;
1136 }
1137
operator ^(const Scalar & s,const Mat & a)1138 MatExpr operator ^ (const Scalar& s, const Mat& a)
1139 {
1140 MatExpr e;
1141 MatOp_Bin::makeExpr(e, '^', a, s);
1142 return e;
1143 }
1144
operator ~(const Mat & a)1145 MatExpr operator ~(const Mat& a)
1146 {
1147 MatExpr e;
1148 MatOp_Bin::makeExpr(e, '~', a, Scalar());
1149 return e;
1150 }
1151
abs(const Mat & a)1152 MatExpr abs(const Mat& a)
1153 {
1154 MatExpr e;
1155 MatOp_Bin::makeExpr(e, 'a', a, Scalar());
1156 return e;
1157 }
1158
abs(const MatExpr & e)1159 MatExpr abs(const MatExpr& e)
1160 {
1161 MatExpr en;
1162 e.op->abs(e, en);
1163 return en;
1164 }
1165
1166
size() const1167 Size MatExpr::size() const
1168 {
1169 if( isT(*this) || isInv(*this) )
1170 return Size(a.rows, a.cols);
1171 if( isGEMM(*this) )
1172 return Size(b.cols, a.rows);
1173 if( isSolve(*this) )
1174 return Size(b.cols, a.cols);
1175 if( isInitializer(*this) )
1176 return a.size();
1177 return op ? op->size(*this) : Size();
1178 }
1179
1180
type() const1181 int MatExpr::type() const
1182 {
1183 if( isInitializer(*this) )
1184 return a.type();
1185 if( isCmp(*this) )
1186 return CV_8U;
1187 return op ? op->type(*this) : -1;
1188 }
1189
1190
1191 /////////////////////////////////////////////////////////////////////////////////////////////////////
1192
assign(const MatExpr & e,Mat & m,int _type) const1193 void MatOp_Identity::assign(const MatExpr& e, Mat& m, int _type) const
1194 {
1195 if( _type == -1 || _type == e.a.type() )
1196 m = e.a;
1197 else
1198 {
1199 CV_Assert( CV_MAT_CN(_type) == e.a.channels() );
1200 e.a.convertTo(m, _type);
1201 }
1202 }
1203
makeExpr(MatExpr & res,const Mat & m)1204 inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m)
1205 {
1206 res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0);
1207 }
1208
1209 /////////////////////////////////////////////////////////////////////////////////////////////////////
1210
assign(const MatExpr & e,Mat & m,int _type) const1211 void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int _type) const
1212 {
1213 Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
1214 if( e.b.data )
1215 {
1216 if( e.s == Scalar() || !e.s.isReal() )
1217 {
1218 if( e.alpha == 1 )
1219 {
1220 if( e.beta == 1 )
1221 cv::add(e.a, e.b, dst);
1222 else if( e.beta == -1 )
1223 cv::subtract(e.a, e.b, dst);
1224 else
1225 cv::scaleAdd(e.b, e.beta, e.a, dst);
1226 }
1227 else if( e.beta == 1 )
1228 {
1229 if( e.alpha == -1 )
1230 cv::subtract(e.b, e.a, dst);
1231 else
1232 cv::scaleAdd(e.a, e.alpha, e.b, dst);
1233 }
1234 else
1235 cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst);
1236
1237 if( !e.s.isReal() )
1238 cv::add(dst, e.s, dst);
1239 }
1240 else
1241 cv::addWeighted(e.a, e.alpha, e.b, e.beta, e.s[0], dst);
1242 }
1243 else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1))
1244 {
1245 e.a.convertTo(m, _type, e.alpha, e.s[0]);
1246 return;
1247 }
1248 else if( e.alpha == 1 )
1249 cv::add(e.a, e.s, dst);
1250 else if( e.alpha == -1 )
1251 cv::subtract(e.s, e.a, dst);
1252 else
1253 {
1254 e.a.convertTo(dst, e.a.type(), e.alpha);
1255 cv::add(dst, e.s, dst);
1256 }
1257
1258 if( dst.data != m.data )
1259 dst.convertTo(m, m.type());
1260 }
1261
1262
add(const MatExpr & e,const Scalar & s,MatExpr & res) const1263 void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const
1264 {
1265 res = e;
1266 res.s += s;
1267 }
1268
1269
subtract(const Scalar & s,const MatExpr & e,MatExpr & res) const1270 void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const
1271 {
1272 res = e;
1273 res.alpha = -res.alpha;
1274 res.beta = -res.beta;
1275 res.s = s - res.s;
1276 }
1277
multiply(const MatExpr & e,double s,MatExpr & res) const1278 void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const
1279 {
1280 res = e;
1281 res.alpha *= s;
1282 res.beta *= s;
1283 res.s *= s;
1284 }
1285
divide(double s,const MatExpr & e,MatExpr & res) const1286 void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const
1287 {
1288 if( isScaled(e) )
1289 MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s/e.alpha);
1290 else
1291 MatOp::divide(s, e, res);
1292 }
1293
1294
transpose(const MatExpr & e,MatExpr & res) const1295 void MatOp_AddEx::transpose(const MatExpr& e, MatExpr& res) const
1296 {
1297 if( isScaled(e) )
1298 MatOp_T::makeExpr(res, e.a, e.alpha);
1299 else
1300 MatOp::transpose(e, res);
1301 }
1302
abs(const MatExpr & e,MatExpr & res) const1303 void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const
1304 {
1305 if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 )
1306 MatOp_Bin::makeExpr(res, 'a', e.a, -e.s*e.alpha);
1307 else if( e.b.data && e.alpha + e.beta == 0 && e.alpha*e.beta == -1 )
1308 MatOp_Bin::makeExpr(res, 'a', e.a, e.b);
1309 else
1310 MatOp::abs(e, res);
1311 }
1312
makeExpr(MatExpr & res,const Mat & a,const Mat & b,double alpha,double beta,const Scalar & s)1313 inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s)
1314 {
1315 res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s);
1316 }
1317
1318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1319
assign(const MatExpr & e,Mat & m,int _type) const1320 void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const
1321 {
1322 Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
1323
1324 if( e.flags == '*' )
1325 cv::multiply(e.a, e.b, dst, e.alpha);
1326 else if( e.flags == '/' && e.b.data )
1327 cv::divide(e.a, e.b, dst, e.alpha);
1328 else if( e.flags == '/' && !e.b.data )
1329 cv::divide(e.alpha, e.a, dst );
1330 else if( e.flags == '&' && e.b.data )
1331 bitwise_and(e.a, e.b, dst);
1332 else if( e.flags == '&' && !e.b.data )
1333 bitwise_and(e.a, e.s, dst);
1334 else if( e.flags == '|' && e.b.data )
1335 bitwise_or(e.a, e.b, dst);
1336 else if( e.flags == '|' && !e.b.data )
1337 bitwise_or(e.a, e.s, dst);
1338 else if( e.flags == '^' && e.b.data )
1339 bitwise_xor(e.a, e.b, dst);
1340 else if( e.flags == '^' && !e.b.data )
1341 bitwise_xor(e.a, e.s, dst);
1342 else if( e.flags == '~' && !e.b.data )
1343 bitwise_not(e.a, dst);
1344 else if( e.flags == 'm' )
1345 cv::min(e.a, e.b, dst);
1346 else if( e.flags == 'n' )
1347 cv::min(e.a, e.s[0], dst);
1348 else if( e.flags == 'M' )
1349 cv::max(e.a, e.b, dst);
1350 else if( e.flags == 'N' )
1351 cv::max(e.a, e.s[0], dst);
1352 else if( e.flags == 'a' && e.b.data )
1353 cv::absdiff(e.a, e.b, dst);
1354 else if( e.flags == 'a' && !e.b.data )
1355 cv::absdiff(e.a, e.s, dst);
1356 else
1357 CV_Error(CV_StsError, "Unknown operation");
1358
1359 if( dst.data != m.data )
1360 dst.convertTo(m, _type);
1361 }
1362
multiply(const MatExpr & e,double s,MatExpr & res) const1363 void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const
1364 {
1365 if( e.flags == '*' || e.flags == '/' )
1366 {
1367 res = e;
1368 res.alpha *= s;
1369 }
1370 else
1371 MatOp::multiply(e, s, res);
1372 }
1373
divide(double s,const MatExpr & e,MatExpr & res) const1374 void MatOp_Bin::divide(double s, const MatExpr& e, MatExpr& res) const
1375 {
1376 if( e.flags == '/' && (!e.b.data || e.beta == 0) )
1377 MatOp_AddEx::makeExpr(res, e.a, Mat(), s/e.alpha, 0);
1378 else
1379 MatOp::divide(s, e, res);
1380 }
1381
makeExpr(MatExpr & res,char op,const Mat & a,const Mat & b,double scale)1382 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale)
1383 {
1384 res = MatExpr(&g_MatOp_Bin, op, a, b, Mat(), scale, b.data ? 1 : 0);
1385 }
1386
makeExpr(MatExpr & res,char op,const Mat & a,const Scalar & s)1387 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s)
1388 {
1389 res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s);
1390 }
1391
1392 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1393
assign(const MatExpr & e,Mat & m,int _type) const1394 void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int _type) const
1395 {
1396 Mat temp, &dst = _type == -1 || _type == CV_8U ? m : temp;
1397
1398 if( e.b.data )
1399 cv::compare(e.a, e.b, dst, e.flags);
1400 else
1401 cv::compare(e.a, e.alpha, dst, e.flags);
1402
1403 if( dst.data != m.data )
1404 dst.convertTo(m, _type);
1405 }
1406
makeExpr(MatExpr & res,int cmpop,const Mat & a,const Mat & b)1407 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b)
1408 {
1409 res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1);
1410 }
1411
makeExpr(MatExpr & res,int cmpop,const Mat & a,double alpha)1412 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha)
1413 {
1414 res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1);
1415 }
1416
1417 /////////////////////////////////////////////////////////////////////////////////////////////////////////
1418
assign(const MatExpr & e,Mat & m,int _type) const1419 void MatOp_T::assign(const MatExpr& e, Mat& m, int _type) const
1420 {
1421 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
1422
1423 cv::transpose(e.a, dst);
1424
1425 if( dst.data != m.data || e.alpha != 1 )
1426 dst.convertTo(m, _type, e.alpha);
1427 }
1428
multiply(const MatExpr & e,double s,MatExpr & res) const1429 void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const
1430 {
1431 res = e;
1432 res.alpha *= s;
1433 }
1434
transpose(const MatExpr & e,MatExpr & res) const1435 void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const
1436 {
1437 if( e.alpha == 1 )
1438 MatOp_Identity::makeExpr(res, e.a);
1439 else
1440 MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0);
1441 }
1442
makeExpr(MatExpr & res,const Mat & a,double alpha)1443 inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha)
1444 {
1445 res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0);
1446 }
1447
1448 /////////////////////////////////////////////////////////////////////////////////////////////////////////
1449
assign(const MatExpr & e,Mat & m,int _type) const1450 void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int _type) const
1451 {
1452 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
1453
1454 cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags);
1455 if( dst.data != m.data )
1456 dst.convertTo(m, _type);
1457 }
1458
add(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const1459 void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
1460 {
1461 bool i1 = isIdentity(e1), i2 = isIdentity(e2);
1462 double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
1463
1464 if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
1465 MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
1466 e1.a, e1.b, alpha1, e2.a, alpha2);
1467 else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) )
1468 MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0),
1469 e2.a, e2.b, alpha2, e1.a, alpha1);
1470 else if( this == e2.op )
1471 MatOp::add(e1, e2, res);
1472 else
1473 e2.op->add(e1, e2, res);
1474 }
1475
subtract(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const1476 void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
1477 {
1478 bool i1 = isIdentity(e1), i2 = isIdentity(e2);
1479 double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
1480
1481 if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
1482 MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
1483 e1.a, e1.b, alpha1, e2.a, -alpha2);
1484 else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) )
1485 MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0),
1486 e2.a, e2.b, -alpha2, e1.a, alpha1);
1487 else if( this == e2.op )
1488 MatOp::subtract(e1, e2, res);
1489 else
1490 e2.op->subtract(e1, e2, res);
1491 }
1492
multiply(const MatExpr & e,double s,MatExpr & res) const1493 void MatOp_GEMM::multiply(const MatExpr& e, double s, MatExpr& res) const
1494 {
1495 res = e;
1496 res.alpha *= s;
1497 res.beta *= s;
1498 }
1499
transpose(const MatExpr & e,MatExpr & res) const1500 void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const
1501 {
1502 res = e;
1503 res.flags = (!(e.flags & CV_GEMM_A_T) ? CV_GEMM_B_T : 0) |
1504 (!(e.flags & CV_GEMM_B_T) ? CV_GEMM_A_T : 0) |
1505 (!(e.flags & CV_GEMM_C_T) ? CV_GEMM_C_T : 0);
1506 swap(res.a, res.b);
1507 }
1508
makeExpr(MatExpr & res,int flags,const Mat & a,const Mat & b,double alpha,const Mat & c,double beta)1509 inline void MatOp_GEMM::makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b,
1510 double alpha, const Mat& c, double beta)
1511 {
1512 res = MatExpr(&g_MatOp_GEMM, flags, a, b, c, alpha, beta);
1513 }
1514
1515 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1516
assign(const MatExpr & e,Mat & m,int _type) const1517 void MatOp_Invert::assign(const MatExpr& e, Mat& m, int _type) const
1518 {
1519 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
1520
1521 cv::invert(e.a, dst, e.flags);
1522 if( dst.data != m.data )
1523 dst.convertTo(m, _type);
1524 }
1525
matmul(const MatExpr & e1,const MatExpr & e2,MatExpr & res) const1526 void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
1527 {
1528 if( isInv(e1) && isIdentity(e2) )
1529 MatOp_Solve::makeExpr(res, e1.flags, e1.a, e2.a);
1530 else if( this == e2.op )
1531 MatOp::matmul(e1, e2, res);
1532 else
1533 e2.op->matmul(e1, e2, res);
1534 }
1535
makeExpr(MatExpr & res,int method,const Mat & m)1536 inline void MatOp_Invert::makeExpr(MatExpr& res, int method, const Mat& m)
1537 {
1538 res = MatExpr(&g_MatOp_Invert, method, m, Mat(), Mat(), 1, 0);
1539 }
1540
1541 /////////////////////////////////////////////////////////////////////////////////////////////////////////
1542
assign(const MatExpr & e,Mat & m,int _type) const1543 void MatOp_Solve::assign(const MatExpr& e, Mat& m, int _type) const
1544 {
1545 Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
1546
1547 cv::solve(e.a, e.b, dst, e.flags);
1548 if( dst.data != m.data )
1549 dst.convertTo(m, _type);
1550 }
1551
makeExpr(MatExpr & res,int method,const Mat & a,const Mat & b)1552 inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b)
1553 {
1554 res = MatExpr(&g_MatOp_Solve, method, a, b, Mat(), 1, 1);
1555 }
1556
1557 //////////////////////////////////////////////////////////////////////////////////////////////////////////
1558
assign(const MatExpr & e,Mat & m,int _type) const1559 void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const
1560 {
1561 if( _type == -1 )
1562 _type = e.a.type();
1563
1564 if( e.a.dims <= 2 )
1565 m.create(e.a.size(), _type);
1566 else
1567 m.create(e.a.dims, e.a.size, _type);
1568
1569 if( e.flags == 'I' && e.a.dims <= 2 )
1570 setIdentity(m, Scalar(e.alpha));
1571 else if( e.flags == '0' )
1572 m = Scalar();
1573 else if( e.flags == '1' )
1574 m = Scalar(e.alpha);
1575 else
1576 CV_Error(CV_StsError, "Invalid matrix initializer type");
1577 }
1578
multiply(const MatExpr & e,double s,MatExpr & res) const1579 void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const
1580 {
1581 res = e;
1582 res.alpha *= s;
1583 }
1584
makeExpr(MatExpr & res,int method,Size sz,int type,double alpha)1585 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha)
1586 {
1587 res = MatExpr(getGlobalMatOpInitializer(), method, Mat(sz, type, (void*)0), Mat(), Mat(), alpha, 0);
1588 }
1589
makeExpr(MatExpr & res,int method,int ndims,const int * sizes,int type,double alpha)1590 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha)
1591 {
1592 res = MatExpr(getGlobalMatOpInitializer(), method, Mat(ndims, sizes, type, (void*)0), Mat(), Mat(), alpha, 0);
1593 }
1594
1595 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
1596
t() const1597 MatExpr Mat::t() const
1598 {
1599 MatExpr e;
1600 MatOp_T::makeExpr(e, *this);
1601 return e;
1602 }
1603
inv(int method) const1604 MatExpr Mat::inv(int method) const
1605 {
1606 MatExpr e;
1607 MatOp_Invert::makeExpr(e, method, *this);
1608 return e;
1609 }
1610
1611
mul(InputArray m,double scale) const1612 MatExpr Mat::mul(InputArray m, double scale) const
1613 {
1614 MatExpr e;
1615 if(m.kind() == _InputArray::EXPR)
1616 {
1617 const MatExpr& me = *(const MatExpr*)m.getObj();
1618 me.op->multiply(MatExpr(*this), me, e, scale);
1619 }
1620 else
1621 MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale);
1622 return e;
1623 }
1624
zeros(int rows,int cols,int type)1625 MatExpr Mat::zeros(int rows, int cols, int type)
1626 {
1627 MatExpr e;
1628 MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type);
1629 return e;
1630 }
1631
zeros(Size size,int type)1632 MatExpr Mat::zeros(Size size, int type)
1633 {
1634 MatExpr e;
1635 MatOp_Initializer::makeExpr(e, '0', size, type);
1636 return e;
1637 }
1638
zeros(int ndims,const int * sizes,int type)1639 MatExpr Mat::zeros(int ndims, const int* sizes, int type)
1640 {
1641 MatExpr e;
1642 MatOp_Initializer::makeExpr(e, '0', ndims, sizes, type);
1643 return e;
1644 }
1645
ones(int rows,int cols,int type)1646 MatExpr Mat::ones(int rows, int cols, int type)
1647 {
1648 MatExpr e;
1649 MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type);
1650 return e;
1651 }
1652
ones(Size size,int type)1653 MatExpr Mat::ones(Size size, int type)
1654 {
1655 MatExpr e;
1656 MatOp_Initializer::makeExpr(e, '1', size, type);
1657 return e;
1658 }
1659
ones(int ndims,const int * sizes,int type)1660 MatExpr Mat::ones(int ndims, const int* sizes, int type)
1661 {
1662 MatExpr e;
1663 MatOp_Initializer::makeExpr(e, '1', ndims, sizes, type);
1664 return e;
1665 }
1666
eye(int rows,int cols,int type)1667 MatExpr Mat::eye(int rows, int cols, int type)
1668 {
1669 MatExpr e;
1670 MatOp_Initializer::makeExpr(e, 'I', Size(cols, rows), type);
1671 return e;
1672 }
1673
eye(Size size,int type)1674 MatExpr Mat::eye(Size size, int type)
1675 {
1676 MatExpr e;
1677 MatOp_Initializer::makeExpr(e, 'I', size, type);
1678 return e;
1679 }
1680
1681 }
1682
1683 /* End of file. */
1684