added cv::polarToCart to T-API
authorIlya Lavrenov <ilya.lavrenov@itseez.com>
Sat, 30 Nov 2013 20:17:23 +0000 (00:17 +0400)
committerIlya Lavrenov <ilya.lavrenov@itseez.com>
Tue, 3 Dec 2013 20:50:03 +0000 (00:50 +0400)
modules/core/src/mathfuncs.cpp
modules/core/src/opencl/arithm.cl

index d216589..540bb87 100644 (file)
@@ -684,12 +684,48 @@ static void SinCos_32f( const float *angle, float *sinval, float* cosval,
 }
 
 
+static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
+                             OutputArray _dst1, OutputArray _dst2, bool angleInDegrees )
+{
+    int type = _angle.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+    bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
+
+    if ( _mag.empty() || (!doubleSupport && depth == CV_64F) )
+        return false;
+
+    UMat mag = _mag.getUMat(), angle = _angle.getUMat();
+    Size size = angle.size();
+    CV_Assert(mag.size() == size);
+
+    _dst1.create(size, type);
+    _dst2.create(size, type);
+    UMat dst1 = _dst1.getUMat(), dst2 = _dst2.getUMat();
+
+    ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
+                  format("-D dstT=%s -D BINARY_OP -D OP_PTC_%s%s",
+                         ocl::typeToStr(CV_MAKE_TYPE(depth, 1)),
+                         angleInDegrees ? "AD" : "AR",
+                         doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
+
+    k.args(ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::ReadOnlyNoSize(angle),
+           ocl::KernelArg::WriteOnly(dst1, cn), ocl::KernelArg::WriteOnlyNoSize(dst2));
+
+    size_t globalsize[2] = { dst1.cols * cn, dst1.rows };
+    return k.run(2, globalsize, NULL, false);
+}
+
 void polarToCart( InputArray src1, InputArray src2,
                   OutputArray dst1, OutputArray dst2, bool angleInDegrees )
 {
+    int type = src2.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+    CV_Assert((depth == CV_32F || depth == CV_64F) && (src1.empty() || src1.type() == type));
+
+    if (ocl::useOpenCL() && dst1.isUMat() && dst2.isUMat() &&
+            ocl_polarToCart(src1, src2, dst1, dst2, angleInDegrees))
+        return;
+
     Mat Mag = src1.getMat(), Angle = src2.getMat();
-    int type = Angle.type(), depth = Angle.depth(), cn = Angle.channels();
-    CV_Assert( Mag.empty() || (Angle.size == Mag.size && type == Mag.type() && (depth == CV_32F || depth == CV_64F)));
+    CV_Assert( Mag.empty() || Angle.size == Mag.size);
     dst1.create( Angle.dims, Angle.size, type );
     dst2.create( Angle.dims, Angle.size, type );
     Mat X = dst1.getMat(), Y = dst2.getMat();
index 48d5f6f..b9f47a7 100644 (file)
@@ -215,11 +215,26 @@ dstelem = v > (dstT)(0) ? log(v) : log(-v)
     dstelem = magnitude; \
     dstelem2 = cartToPolar
 
+#elif defined OP_PTC_AD || defined OP_PTC_AR
+#ifdef OP_PTC_AD
+#define FROM_DEGREE \
+    dstT ascale = CV_PI/180.0f; \
+    dstT alpha = y * ascale
+#else
+#define FROM_DEGREE \
+    dstT alpha = y
+#endif
+#define PROCESS_ELEM \
+    dstT x = srcelem1, y = srcelem2; \
+    FROM_DEGREE; \
+    dstelem = cos(alpha) * x; \
+    dstelem2 = sin(alpha) * x
+
 #else
 #error "unknown op type"
 #endif
 
-#if defined OP_CTP_AD || defined OP_CTP_AR
+#if defined OP_CTP_AD || defined OP_CTP_AR || defined OP_PTC_AD || defined OP_PTC_AR
     #undef EXTRA_PARAMS
     #define EXTRA_PARAMS , __global uchar* dstptr2, int dststep2, int dstoffset2
     #undef EXTRA_INDEX
@@ -295,6 +310,7 @@ __kernel void KF(__global const uchar* srcptr1, int srcstep1, int srcoffset1,
     {
         int src1_index = mad24(y, srcstep1, x*(int)sizeof(srcT1) + srcoffset1);
         int dst_index  = mad24(y, dststep, x*(int)sizeof(dstT) + dstoffset);
+        EXTRA_INDEX;
 
         PROCESS_ELEM;
     }