From c8f59bf1e0d179f3c6ee86427313b6473c117ee9 Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Thu, 20 Dec 2018 23:40:07 +0300 Subject: [PATCH 1/2] Fixed operations on Mat and Matx simultaneously --- modules/core/include/opencv2/core/mat.hpp | 60 +++++++++++++++++++ .../core/include/opencv2/core/operations.hpp | 19 ++++++ 2 files changed, 79 insertions(+) diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index c0893b398d..a5fef4415a 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -3597,6 +3597,10 @@ CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s); CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e); CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator + (const Mat& a, const Matx<_Tp, m, n>& b) { return a + Mat(b); } +template static inline +MatExpr operator + (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) + b; } CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s); @@ -3606,6 +3610,10 @@ CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s); CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e); CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator - (const Mat& a, const Matx<_Tp, m, n>& b) { return a - Mat(b); } +template static inline +MatExpr operator - (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) - b; } CV_EXPORTS MatExpr operator - (const Mat& m); CV_EXPORTS MatExpr operator - (const MatExpr& e); @@ -3618,6 +3626,10 @@ CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator * (const MatExpr& e, double s); CV_EXPORTS MatExpr operator * (double s, const MatExpr& e); CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator * (const Mat& a, const Matx<_Tp, m, n>& b) { return a + Mat(b); } +template static inline +MatExpr operator * (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) + b; } CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator / (const Mat& a, double s); @@ -3627,52 +3639,100 @@ CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e); CV_EXPORTS MatExpr operator / (const MatExpr& e, double s); CV_EXPORTS MatExpr operator / (double s, const MatExpr& e); CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator / (const Mat& a, const Matx<_Tp, m, n>& b) { return a / Mat(b); } +template static inline +MatExpr operator / (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) / b; } CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator < (const Mat& a, double s); CV_EXPORTS MatExpr operator < (double s, const Mat& a); +template static inline +MatExpr operator < (const Mat& a, const Matx<_Tp, m, n>& b) { return a < Mat(b); } +template static inline +MatExpr operator < (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) < b; } CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator <= (const Mat& a, double s); CV_EXPORTS MatExpr operator <= (double s, const Mat& a); +template static inline +MatExpr operator <= (const Mat& a, const Matx<_Tp, m, n>& b) { return a <= Mat(b); } +template static inline +MatExpr operator <= (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) <= b; } CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator == (const Mat& a, double s); CV_EXPORTS MatExpr operator == (double s, const Mat& a); +template static inline +MatExpr operator == (const Mat& a, const Matx<_Tp, m, n>& b) { return a == Mat(b); } +template static inline +MatExpr operator == (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) == b; } CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator != (const Mat& a, double s); CV_EXPORTS MatExpr operator != (double s, const Mat& a); +template static inline +MatExpr operator != (const Mat& a, const Matx<_Tp, m, n>& b) { return a != Mat(b); } +template static inline +MatExpr operator != (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) != b; } CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator >= (const Mat& a, double s); CV_EXPORTS MatExpr operator >= (double s, const Mat& a); +template static inline +MatExpr operator >= (const Mat& a, const Matx<_Tp, m, n>& b) { return a >= Mat(b); } +template static inline +MatExpr operator >= (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) >= b; } CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator > (const Mat& a, double s); CV_EXPORTS MatExpr operator > (double s, const Mat& a); +template static inline +MatExpr operator > (const Mat& a, const Matx<_Tp, m, n>& b) { return a > Mat(b); } +template static inline +MatExpr operator > (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) > b; } CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a); +template static inline +MatExpr operator & (const Mat& a, const Matx<_Tp, m, n>& b) { return a & Mat(b); } +template static inline +MatExpr operator & (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) & b; } CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a); +template static inline +MatExpr operator | (const Mat& a, const Matx<_Tp, m, n>& b) { return a | Mat(b); } +template static inline +MatExpr operator | (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) | b; } CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a); +template static inline +MatExpr operator ^ (const Mat& a, const Matx<_Tp, m, n>& b) { return a ^ Mat(b); } +template static inline +MatExpr operator ^ (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) ^ b; } CV_EXPORTS MatExpr operator ~(const Mat& m); CV_EXPORTS MatExpr min(const Mat& a, const Mat& b); CV_EXPORTS MatExpr min(const Mat& a, double s); CV_EXPORTS MatExpr min(double s, const Mat& a); +template static inline +MatExpr min (const Mat& a, const Matx<_Tp, m, n>& b) { return min(a, Mat(b)); } +template static inline +MatExpr min (const Matx<_Tp, m, n>& a, const Mat& b) { return min(Mat(a), b); } CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); CV_EXPORTS MatExpr max(const Mat& a, double s); CV_EXPORTS MatExpr max(double s, const Mat& a); +template static inline +MatExpr max (const Mat& a, const Matx<_Tp, m, n>& b) { return max(a, Mat(b)); } +template static inline +MatExpr max (const Matx<_Tp, m, n>& a, const Mat& b) { return max(Mat(a), b); } /** @brief Calculates an absolute value of each matrix element. diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index d706d9664e..082fef4440 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -252,48 +252,67 @@ Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) c template CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \ template CV_MAT_AUG_OPERATOR1(op, cvop, const A, B) +#define CV_MAT_AUG_OPERATOR_TN(op, cvop, A) \ + template static inline A& operator op (A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } \ + template static inline const A& operator op (const A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } + CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Scalar) CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Scalar) CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat) +CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Scalar) CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Scalar) CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat) +CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat) CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat_<_Tp>) CV_MAT_AUG_OPERATOR (*=, a.convertTo(a, -1, b), Mat, double) CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double) +CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat) +CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (/=, cv::divide(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat_<_Tp>) CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double) CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double) +CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Scalar) CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Scalar) CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Scalar) CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Scalar) CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat_<_Tp>) CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Mat) CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Scalar) CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat) CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Scalar) CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat_<_Tp>) +#undef CV_MAT_AUG_OPERATOR_TN #undef CV_MAT_AUG_OPERATOR_T #undef CV_MAT_AUG_OPERATOR #undef CV_MAT_AUG_OPERATOR1 From cd169941f2f9c0d38f7dce5992ae3b616d91706d Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Fri, 21 Dec 2018 18:24:50 +0300 Subject: [PATCH 2/2] Added test for addition of Mat and Matx --- modules/core/test/test_operations.cpp | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index e0a2c99991..aea6f229ac 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -69,6 +69,7 @@ protected: bool TestVec(); bool TestMatxMultiplication(); bool TestMatxElementwiseDivison(); + bool TestMatMatxCastSum(); bool TestSubMatAccess(); bool TestExp(); bool TestSVD(); @@ -885,6 +886,74 @@ bool CV_OperationsTest::TestMatxMultiplication() return true; } +bool CV_OperationsTest::TestMatMatxCastSum() +{ + try + { + Mat ref1 = (Mat_(3, 1) << 1, 2, 3); + Mat ref2 = (Mat_(3, 1) << 3, 4, 5); + Mat ref3 = Mat::ones(3, 1, CV_64FC1); + + Mat mat = Mat::zeros(3, 1, CV_64FC1); + + Mat tst1 = ref1.clone(); + Mat_ tst2 = ref2.clone(); + Matx tst3(1, 2, 3); + Vec3d tst4(3, 4, 5); + Scalar tst5(1, 2, 3); + Mat res; + + res = mat + tst1; + CHECK_DIFF_FLT(res, ref1); + res = mat + tst2; + CHECK_DIFF_FLT(res, ref2); + res = mat + tst3; + CHECK_DIFF_FLT(res, ref1); + res = mat + tst4; + CHECK_DIFF_FLT(res, ref2); + + res = mat + tst5; + CHECK_DIFF_FLT(res, ref3); + res = mat + 1; + CHECK_DIFF_FLT(res, ref3); + + cv::add(mat, tst1, res); + CHECK_DIFF_FLT(res, ref1); + cv::add(mat, tst2, res); + CHECK_DIFF_FLT(res, ref2); + cv::add(mat, tst3, res); + CHECK_DIFF_FLT(res, ref1); + cv::add(mat, tst4, res); + CHECK_DIFF_FLT(res, ref2); + + cv::add(mat, tst5, res); + CHECK_DIFF_FLT(res, ref3); + cv::add(mat, 1, res); + CHECK_DIFF_FLT(res, ref3); + + res = mat.clone(); res += tst1; + CHECK_DIFF_FLT(res, ref1); + res = mat.clone(); res += tst2; + CHECK_DIFF_FLT(res, ref2); + res = mat.clone(); res += tst3; + CHECK_DIFF_FLT(res, ref1); + res = mat.clone(); res += tst4; + CHECK_DIFF_FLT(res, ref2); + + res = mat.clone(); res += tst5; + CHECK_DIFF_FLT(res, ref3); + res = mat.clone(); res += 1; + CHECK_DIFF_FLT(res, ref3); + } + catch (const test_excep& e) + { + ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str()); + ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); + return false; + } + return true; +} + bool CV_OperationsTest::TestMatxElementwiseDivison() { try @@ -1135,6 +1204,9 @@ void CV_OperationsTest::run( int /* start_from */) if (!TestMatxElementwiseDivison()) return; + if (!TestMatMatxCastSum()) + return; + if (!TestSubMatAccess()) return;