add ocl::min and ocl::max (includes accuracy tests update)
authorSebastian Krämer <mail@kraymer.de>
Mon, 7 Oct 2013 13:41:50 +0000 (15:41 +0200)
committerSebastian Krämer <mail@kraymer.de>
Tue, 8 Oct 2013 13:23:13 +0000 (15:23 +0200)
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/src/arithm.cpp
modules/ocl/src/haar.cpp
modules/ocl/src/opencl/arithm_add.cl
modules/ocl/test/test_arithm.cpp

index 84e0372..034eb0a 100644 (file)
@@ -457,6 +457,14 @@ namespace cv
         // supports all data types
         CV_EXPORTS void divide(double scale, const oclMat &src1, oclMat &dst);
 
+        //! computes element-wise minimum of the two arrays (dst = min(src1, src2))
+        // supports all data types
+        CV_EXPORTS void min(const oclMat &src1, const oclMat &src2, oclMat &dst);
+
+        //! computes element-wise maximum of the two arrays (dst = max(src1, src2))
+        // supports all data types
+        CV_EXPORTS void max(const oclMat &src1, const oclMat &src2, oclMat &dst);
+
         //! compares elements of two arrays (dst = src1 <cmpop> src2)
         // supports all data types
         CV_EXPORTS void compare(const oclMat &src1, const oclMat &src2, oclMat &dst, int cmpop);
index 341f65c..609e931 100644 (file)
@@ -57,10 +57,10 @@ using namespace cv;
 using namespace cv::ocl;
 
 //////////////////////////////////////////////////////////////////////////////
-/////////////////////// add subtract multiply divide /////////////////////////
+/////////////// add subtract multiply divide min max /////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-enum { ADD = 0, SUB, MUL, DIV, ABS_DIFF };
+enum { ADD = 0, SUB, MUL, DIV, ABS_DIFF, MIN, MAX };
 
 static void arithmetic_run_generic(const oclMat &src1, const oclMat &src2, const Scalar & scalar, const oclMat & mask,
                             oclMat &dst, int op_type, bool use_scalar = false)
@@ -75,7 +75,7 @@ static void arithmetic_run_generic(const oclMat &src1, const oclMat &src2, const
 
     CV_Assert(src2.empty() || (!src2.empty() && src1.type() == src2.type() && src1.size() == src2.size()));
     CV_Assert(mask.empty() || (!mask.empty() && mask.type() == CV_8UC1 && mask.size() == src1.size()));
-    CV_Assert(op_type >= ADD && op_type <= ABS_DIFF);
+    CV_Assert(op_type >= ADD && op_type <= MAX);
 
     dst.create(src1.size(), src1.type());
 
@@ -93,7 +93,7 @@ static void arithmetic_run_generic(const oclMat &src1, const oclMat &src2, const
 
     const char * const typeMap[] = { "uchar", "char", "ushort", "short", "int", "float", "double" };
     const char * const WTypeMap[] = { "short", "short", "int", "int", "int", "float", "double" };
-    const char * const funcMap[] = { "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_DIV", "FUNC_ABS_DIFF" };
+    const char * const funcMap[] = { "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_DIV", "FUNC_ABS_DIFF", "FUNC_MIN", "FUNC_MAX" };
     const char * const channelMap[] = { "", "", "2", "4", "4" };
     bool haveScalar = use_scalar || src2.empty();
 
@@ -205,6 +205,16 @@ void cv::ocl::divide(double scalar, const oclMat &src, oclMat &dst)
     arithmetic_run_generic(src, oclMat(), Scalar::all(scalar), oclMat(), dst, DIV);
 }
 
+void cv::ocl::min(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    arithmetic_run_generic(src1, src2, Scalar::all(0), oclMat(), dst, MIN);
+}
+
+void cv::ocl::max(const oclMat &src1, const oclMat &src2, oclMat &dst)
+{
+    arithmetic_run_generic(src1, src2, Scalar::all(0), oclMat(), dst, MAX);
+}
+
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////// Absdiff ////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
index 05a76aa..71777f1 100644 (file)
@@ -926,7 +926,7 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
             loopcount = 1;
             n_factors = 1;
             sizev.push_back(minSize);
-            scalev.push_back( min(cvRound(minSize.width / winsize0.width), cvRound(minSize.height / winsize0.height)) );
+            scalev.push_back( std::min(cvRound(minSize.width / winsize0.width), cvRound(minSize.height / winsize0.height)) );
 
         }
         detect_piramid_info *scaleinfo = (detect_piramid_info *)malloc(sizeof(detect_piramid_info) * loopcount);
@@ -1555,7 +1555,7 @@ void cv::ocl::OclCascadeClassifierBuf::CreateFactorRelatedBufs(
         {
             loopcount = 1;
             sizev.push_back(minSize);
-            scalev.push_back( min(cvRound(minSize.width / winSize0.width), cvRound(minSize.height / winSize0.height)) );
+            scalev.push_back( std::min(cvRound(minSize.width / winSize0.width), cvRound(minSize.height / winSize0.height)) );
         }
 
         ((OclBuffers *)buffers)->pbuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY,
index 40caba5..cd9fae6 100644 (file)
     dst[dst_index] = convertToT(value);
 #endif
 
+#if defined (FUNC_MIN)
+#define EXPRESSION dst[dst_index] = min( src1[src1_index], src2[src2_index] );
+#endif
+
+#if defined (FUNC_MAX)
+#define EXPRESSION dst[dst_index] = max( src1[src1_index], src2[src2_index] );
+#endif
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////// ADD ////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////
index 59565a8..3f7af66 100644 (file)
@@ -453,6 +453,36 @@ TEST_P(Div, Mat_Scalar)
 
 //////////////////////////////// Absdiff /////////////////////////////////////////////////
 
+typedef ArithmTestBase Min;
+
+TEST_P(Min, Mat)
+{
+    for (int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        dst1_roi = cv::min(src1_roi, src2_roi);
+        cv::ocl::min(gsrc1, gsrc2, gdst1);
+        Near(0);
+    }
+}
+
+typedef ArithmTestBase Max;
+
+TEST_P(Max, Mat)
+{
+    for (int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        dst1_roi = cv::min(src1_roi, src2_roi);
+        cv::ocl::min(gsrc1, gsrc2, gdst1);
+        Near(0);
+    }
+}
+
+//////////////////////////////// Absdiff /////////////////////////////////////////////////
+
 typedef ArithmTestBase Absdiff;
 
 TEST_P(Absdiff, Mat)
@@ -1451,6 +1481,8 @@ INSTANTIATE_TEST_CASE_P(Arithm, Add, Combine(testing::Range(CV_8U, CV_USRTYPE1),
 INSTANTIATE_TEST_CASE_P(Arithm, Sub, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
 INSTANTIATE_TEST_CASE_P(Arithm, Mul, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
 INSTANTIATE_TEST_CASE_P(Arithm, Div, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
+INSTANTIATE_TEST_CASE_P(Arithm, Min, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
+INSTANTIATE_TEST_CASE_P(Arithm, Max, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
 INSTANTIATE_TEST_CASE_P(Arithm, Absdiff, Combine(testing::Range(CV_8U, CV_USRTYPE1), testing::Range(1, 5), Bool()));
 INSTANTIATE_TEST_CASE_P(Arithm, CartToPolar, Combine(Values(CV_32F, CV_64F), testing::Range(1, 5), Bool()));
 INSTANTIATE_TEST_CASE_P(Arithm, PolarToCart, Combine(Values(CV_32F, CV_64F), testing::Range(1, 5), Bool()));