diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index d216589e70..540bb87f52 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -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(); diff --git a/modules/core/src/opencl/arithm.cl b/modules/core/src/opencl/arithm.cl index 48d5f6fb43..b9f47a7953 100644 --- a/modules/core/src/opencl/arithm.cl +++ b/modules/core/src/opencl/arithm.cl @@ -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; }