core(test): zero values divide test (3.x)
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Sun, 14 Oct 2018 02:21:13 +0000 (02:21 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Sun, 14 Oct 2018 02:23:17 +0000 (02:23 +0000)
modules/core/test/test_arithm.cpp

index 8b84436..256493c 100644 (file)
@@ -2201,4 +2201,101 @@ TEST(Core_MeanStdDev, regression_multichannel)
     }
 }
 
+template <typename T> static inline
+void testDivideInitData(Mat& src1, Mat& src2)
+{
+    CV_StaticAssert(std::numeric_limits<T>::is_integer, "");
+    const static T src1_[] = {
+         0,  0,  0,  0,
+         8,  8,  8,  8,
+        -8, -8, -8, -8
+    };
+    Mat(3, 4, traits::Type<T>::value, (void*)src1_).copyTo(src1);
+    const static T src2_[] = {
+        1, 2, 0, std::numeric_limits<T>::max(),
+        1, 2, 0, std::numeric_limits<T>::max(),
+        1, 2, 0, std::numeric_limits<T>::max(),
+    };
+    Mat(3, 4, traits::Type<T>::value, (void*)src2_).copyTo(src2);
+}
+
+template <typename T> static inline
+void testDivideInitDataFloat(Mat& src1, Mat& src2)
+{
+    CV_StaticAssert(!std::numeric_limits<T>::is_integer, "");
+    const static T src1_[] = {
+         0,  0,  0,  0,
+         8,  8,  8,  8,
+        -8, -8, -8, -8
+    };
+    Mat(3, 4, traits::Type<T>::value, (void*)src1_).copyTo(src1);
+    const static T src2_[] = {
+        1, 2, 0, std::numeric_limits<T>::infinity(),
+        1, 2, 0, std::numeric_limits<T>::infinity(),
+        1, 2, 0, std::numeric_limits<T>::infinity(),
+    };
+    Mat(3, 4, traits::Type<T>::value, (void*)src2_).copyTo(src2);
+}
+
+template <> inline void testDivideInitData<float>(Mat& src1, Mat& src2) { testDivideInitDataFloat<float>(src1, src2); }
+template <> inline void testDivideInitData<double>(Mat& src1, Mat& src2) { testDivideInitDataFloat<double>(src1, src2); }
+
+
+template <typename T> static inline
+void testDivideChecks(const Mat& dst)
+{
+    ASSERT_FALSE(dst.empty());
+    for (int y = 0; y < dst.rows; y++)
+    {
+        for (int x = 0; x < dst.cols; x++)
+        {
+            if (x == 2)
+            {
+                EXPECT_EQ(0, dst.at<T>(y, x)) << "dst(" << y << ", " << x << ") = " << dst.at<T>(y, x);
+            }
+        }
+    }
+}
+
+
+template <typename T, bool isUMat> static inline
+void testDivide()
+{
+    Mat src1, src2;
+    testDivideInitData<T>(src1, src2);
+    ASSERT_FALSE(src1.empty()); ASSERT_FALSE(src2.empty());
+
+    Mat dst;
+    if (!isUMat)
+    {
+        cv::divide(src1, src2, dst);
+    }
+    else
+    {
+        UMat usrc1, usrc2, udst;
+        src1.copyTo(usrc1);
+        src2.copyTo(usrc2);
+        cv::divide(usrc1, usrc2, udst);
+        udst.copyTo(dst);
+    }
+
+    testDivideChecks<T>(dst);
+
+    if (::testing::Test::HasFailure())
+    {
+        std::cout << "src1 = " << std::endl << src1 << std::endl;
+        std::cout << "src2 = " << std::endl << src2 << std::endl;
+        std::cout << "dst = " << std::endl << dst << std::endl;
+    }
+}
+
+TEST(Core_DivideRules, type_32s) { testDivide<int, false>(); }
+TEST(UMat_Core_DivideRules, type_32s) { testDivide<int, true>(); }
+TEST(Core_DivideRules, type_16s) { testDivide<short, false>(); }
+TEST(UMat_Core_DivideRules, type_16s) { testDivide<short, true>(); }
+TEST(Core_DivideRules, type_32f) { testDivide<float, false>(); }
+TEST(UMat_Core_DivideRules, type_32f) { testDivide<float, true>(); }
+TEST(Core_DivideRules, type_64f) { testDivide<double, false>(); }
+TEST(UMat_Core_DivideRules, type_64f) { testDivide<double, true>(); }
+
 }} // namespace