add ocl::abs
authorSebastian Krämer <mail@kraymer.de>
Tue, 8 Oct 2013 13:16:30 +0000 (15:16 +0200)
committerSebastian Krämer <mail@kraymer.de>
Tue, 8 Oct 2013 13:23:24 +0000 (15:23 +0200)
modules/ocl/doc/operations_on_matrices.rst
modules/ocl/include/opencv2/ocl/ocl.hpp
modules/ocl/src/arithm.cpp
modules/ocl/src/opencl/arithm_add_scalar.cl
modules/ocl/test/test_arithm.cpp

index 24a4ea1dc5805e7f9e2c1917beff085bd705c241..6c6df90230f1d6f00215b97f463b9a50e1bcae99 100644 (file)
@@ -3,6 +3,18 @@ Operations on Matrics
 
 .. highlight:: cpp
 
+ocl::abs
+------------------
+Returns void
+
+.. ocv:function:: void ocl::absdiff(const oclMat& src, oclMat& dst)
+
+    :param src: input array.
+
+    :param dst: destination array, it will have the same size and same type as ``src``.
+
+Computes per-element absolute values of the input array. Supports all data types.
+
 ocl::absdiff
 ------------------
 Returns void
index 034eb0ac11ef075e36fd89914fc350d42c57289e..58719f1165db55a9589c51ad9a9aafa753634e38 100644 (file)
@@ -473,6 +473,10 @@ namespace cv
         // supports all data types
         CV_EXPORTS void transpose(const oclMat &src, oclMat &dst);
 
+        //! computes element-wise absolute values of an array (dst = abs(src))
+        // supports all data types
+        CV_EXPORTS void abs(const oclMat &src, oclMat &dst);
+
         //! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
         // supports all data types
         CV_EXPORTS void absdiff(const oclMat &src1, const oclMat &src2, oclMat &dst);
index 609e931d46ffd9f646326433d9bbca9ebd7118a2..ef89755a1bbc64ac7e9b8105e49a372117ecc7da 100644 (file)
@@ -60,7 +60,7 @@ using namespace cv::ocl;
 /////////////// add subtract multiply divide min max /////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-enum { ADD = 0, SUB, MUL, DIV, ABS_DIFF, MIN, MAX };
+enum { ADD = 0, SUB, MUL, DIV, ABS, 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)
@@ -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", "FUNC_MIN", "FUNC_MAX" };
+    const char * const funcMap[] = { "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_DIV", "FUNC_ABS", "FUNC_ABS_DIFF", "FUNC_MIN", "FUNC_MAX" };
     const char * const channelMap[] = { "", "", "2", "4", "4" };
     bool haveScalar = use_scalar || src2.empty();
 
@@ -216,9 +216,15 @@ void cv::ocl::max(const oclMat &src1, const oclMat &src2, oclMat &dst)
 }
 
 //////////////////////////////////////////////////////////////////////////////
-///////////////////////////////// Absdiff ////////////////////////////////////
+/////////////////////////////Abs, Absdiff ////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
+void cv::ocl::abs(const oclMat &src1, oclMat &dst)
+{
+    // explicitly uses use_scalar (even if zero) so that the correct kernel is used
+    arithmetic_run_generic(src1, oclMat(), Scalar(), oclMat(), dst, ABS, true);
+}
+
 void cv::ocl::absdiff(const oclMat &src1, const oclMat &src2, oclMat &dst)
 {
     arithmetic_run_generic(src1, src2, Scalar(), oclMat(), dst, ABS_DIFF);
index 4a0167fd55c1421729358d2ad0c44ae5a99d9ceb..f908b89f5a991cfd3c3e42358726c6fd054d9be7 100644 (file)
     dst[dst_index] = src1[src1_index] == zero ? zero : convertToT(scalar[0] / convertToWT(src1[src1_index]));
 #endif
 
+#if defined (FUNC_ABS)
+#define EXPRESSION \
+    T value = (src1[src1_index] > 0) ? src1[src1_index] : -src1[src1_index]; \
+    dst[dst_index] = value;
+#endif
+
 #if defined (FUNC_ABS_DIFF)
 #define EXPRESSION WT value = convertToWT(src1[src1_index]) - scalar[0]; \
     value = value > (WT)(0) ? value : -value; \
@@ -92,5 +98,6 @@ __kernel void arithm_binary_op_scalar (__global T *src1, int src1_step, int src1
         int dst_index = mad24(y, dst_step, x + dst_offset);
 
         EXPRESSION
+
     }
 }
index 3f7af66d948cbc5437508422447edba68226f78a..db05f455654ba7ef280a232829c10683cd64dcfe 100644 (file)
@@ -481,6 +481,22 @@ TEST_P(Max, Mat)
     }
 }
 
+//////////////////////////////// Abs /////////////////////////////////////////////////////
+
+typedef ArithmTestBase Abs;
+
+TEST_P(Abs, Abs)
+{
+    for (int j = 0; j < LOOP_TIMES; j++)
+    {
+        random_roi();
+
+        dst1_roi = cv::abs(src1_roi);
+        cv::ocl::abs(gsrc1, gdst1);
+        Near(0);
+    }
+}
+
 //////////////////////////////// Absdiff /////////////////////////////////////////////////
 
 typedef ArithmTestBase Absdiff;
@@ -1483,6 +1499,7 @@ INSTANTIATE_TEST_CASE_P(Arithm, Mul, Combine(testing::Range(CV_8U, CV_USRTYPE1),
 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, Abs, 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()));