mirror of
https://github.com/opencv/opencv.git
synced 2024-11-26 04:00:30 +08:00
T-API cv::log, cv::exp, cv::magnitude, cv::phase
This commit is contained in:
parent
17f53bc301
commit
14dccdf23d
@ -41,7 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include "opencl_kernels.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@ -54,6 +54,50 @@ static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
|
||||
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
|
||||
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);
|
||||
|
||||
|
||||
enum { OCL_OP_LOG=0, OCL_OP_EXP=1, OCL_OP_MAG=2, OCL_OP_PHASE_DEGREES=3, OCL_OP_PHASE_RADIANS=4 };
|
||||
|
||||
static const char* oclop2str[] = { "OP_LOG", "OP_EXP", "OP_MAG", "OP_PHASE_DEGREES", "OP_PHASE_RADIANS", 0 };
|
||||
|
||||
bool ocl_math_op(InputArray _src1, InputArray _src2, OutputArray _dst, int oclop)
|
||||
{
|
||||
int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn1 = CV_MAT_CN(type1);
|
||||
int type2 = _src2.type(), cn2 = CV_MAT_CN(type2);
|
||||
|
||||
char opts[1024];
|
||||
|
||||
bool double_support = false;
|
||||
if(ocl::Device::getDefault().doubleFPConfig() > 0)
|
||||
double_support = true;
|
||||
if(!double_support && depth1 == CV_64F)
|
||||
return false;
|
||||
|
||||
sprintf(opts, "-D %s -D %s -D dstT=%s %s", _src2.empty()?"UNARY_OP":"BINARY_OP",
|
||||
oclop2str[oclop], ocl::typeToStr(CV_MAKETYPE(depth1, 1) ), double_support ? "-D DOUBLE_SUPPORT" : "" );
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts);
|
||||
if( k.empty() )
|
||||
return false;
|
||||
|
||||
UMat src1 = _src1.getUMat();
|
||||
UMat src2 = _src2.getUMat();
|
||||
_dst.create(src1.size(), type1);
|
||||
UMat dst = _dst.getUMat();
|
||||
|
||||
ocl::KernelArg src1arg = ocl::KernelArg::ReadOnlyNoSize(src1, cn1);
|
||||
ocl::KernelArg src2arg = ocl::KernelArg::ReadOnlyNoSize(src2, cn2);
|
||||
ocl::KernelArg dstarg = ocl::KernelArg::WriteOnly(dst, cn1);
|
||||
|
||||
if(_src2.empty())
|
||||
k.args(src1arg, dstarg);
|
||||
else
|
||||
k.args(src1arg, src2arg, dstarg);
|
||||
|
||||
size_t globalsize[] = { src1.cols*cn1, src1.rows};
|
||||
|
||||
return k.run(2, globalsize, 0, false);
|
||||
}
|
||||
|
||||
float fastAtan2( float y, float x )
|
||||
{
|
||||
float ax = std::abs(x), ay = std::abs(y);
|
||||
@ -354,9 +398,16 @@ static void Sqrt_64f(const double* src, double* dst, int len)
|
||||
|
||||
void magnitude( InputArray src1, InputArray src2, OutputArray dst )
|
||||
{
|
||||
int type = src1.type(), depth = src1.depth(), cn = src1.channels();
|
||||
CV_Assert( src1.size() == src2.size() && type == src2.type() && (depth == CV_32F || depth == CV_64F));
|
||||
|
||||
bool use_opencl = dst.isUMat() && ocl::useOpenCL()
|
||||
&& src1.dims() <= 2 && src2.dims() <= 2;
|
||||
|
||||
if(use_opencl && ocl_math_op(src1, src2, dst, OCL_OP_MAG) )
|
||||
return;
|
||||
|
||||
Mat X = src1.getMat(), Y = src2.getMat();
|
||||
int type = X.type(), depth = X.depth(), cn = X.channels();
|
||||
CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F));
|
||||
dst.create(X.dims, X.size, X.type());
|
||||
Mat Mag = dst.getMat();
|
||||
|
||||
@ -385,9 +436,16 @@ void magnitude( InputArray src1, InputArray src2, OutputArray dst )
|
||||
|
||||
void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegrees )
|
||||
{
|
||||
int type = src1.type(), depth = src1.depth(), cn = src1.channels();
|
||||
CV_Assert( src1.size() == src2.size() && type == src2.type() && (depth == CV_32F || depth == CV_64F));
|
||||
|
||||
bool use_opencl = dst.isUMat() && ocl::useOpenCL()
|
||||
&& src1.dims() <= 2 && src2.dims() <= 2;
|
||||
|
||||
if(use_opencl && ocl_math_op(src1, src2, dst, angleInDegrees ? OCL_OP_PHASE_DEGREES : OCL_OP_PHASE_RADIANS) )
|
||||
return;
|
||||
|
||||
Mat X = src1.getMat(), Y = src2.getMat();
|
||||
int type = X.type(), depth = X.depth(), cn = X.channels();
|
||||
CV_Assert( X.size == Y.size && type == Y.type() && (depth == CV_32F || depth == CV_64F));
|
||||
dst.create( X.dims, X.size, type );
|
||||
Mat Angle = dst.getMat();
|
||||
|
||||
@ -1151,14 +1209,18 @@ static void Exp_64f( const double *_x, double *y, int n )
|
||||
|
||||
void exp( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
int type = src.type(), depth = src.depth(), cn = src.channels();
|
||||
int type = _src.type(), depth = _src.depth(), cn = _src.channels();
|
||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
||||
|
||||
bool use_opencl = _dst.isUMat() && ocl::useOpenCL() && _src.dims() <= 2;
|
||||
|
||||
if(use_opencl && ocl_math_op(_src, noArray(), _dst, OCL_OP_EXP) )
|
||||
return;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
_dst.create( src.dims, src.size, type );
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
||||
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
uchar* ptrs[2];
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
@ -1796,14 +1858,18 @@ static void Log_64f( const double *x, double *y, int n )
|
||||
|
||||
void log( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
int type = src.type(), depth = src.depth(), cn = src.channels();
|
||||
int type = _src.type(), depth = _src.depth(), cn = _src.channels();
|
||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
||||
|
||||
bool use_opencl = _dst.isUMat() && ocl::useOpenCL() && _src.dims() <= 2;
|
||||
|
||||
if(use_opencl && ocl_math_op(_src, noArray(), _dst, OCL_OP_LOG) )
|
||||
return;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
_dst.create( src.dims, src.size, type );
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
||||
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
uchar* ptrs[2];
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
|
@ -173,7 +173,9 @@
|
||||
#define PROCESS_ELEM dstelem = sqrt(srcelem1)
|
||||
|
||||
#elif defined OP_LOG
|
||||
#define PROCESS_ELEM dstelem = log(abs(srcelem1))
|
||||
#define PROCESS_ELEM \
|
||||
dstT v = (dstT)(srcelem1);\
|
||||
dstelem = v > (dstT)(0) ? log(v) : log(-v)
|
||||
|
||||
#elif defined OP_CMP
|
||||
#define PROCESS_ELEM dstelem = convert_uchar(srcelem1 CMP_OPERATOR srcelem2 ? 255 : 0)
|
||||
|
@ -281,11 +281,91 @@ OCL_TEST_P(Subtract, Scalar_Mask)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Log /////////////////////////////////////////
|
||||
|
||||
typedef ArithmTestBase Log;
|
||||
|
||||
OCL_TEST_P(Log, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::log(src1_roi, dst1_roi));
|
||||
OCL_ON(cv::log(usrc1_roi, udst1_roi));
|
||||
Near(1);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Exp /////////////////////////////////////////
|
||||
|
||||
typedef ArithmTestBase Exp;
|
||||
|
||||
OCL_TEST_P(Exp, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::exp(src1_roi, dst1_roi));
|
||||
OCL_ON(cv::exp(usrc1_roi, udst1_roi));
|
||||
Near(2);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Phase /////////////////////////////////////////
|
||||
|
||||
typedef ArithmTestBase Phase;
|
||||
|
||||
OCL_TEST_P(Phase, angleInDegree)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::phase(src1_roi, src2_roi, dst1_roi, true));
|
||||
OCL_ON(cv::phase(usrc1_roi, usrc2_roi, udst1_roi, true));
|
||||
Near(1e-2);
|
||||
}
|
||||
}
|
||||
|
||||
OCL_TEST_P(Phase, angleInRadians)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::phase(src1_roi, src2_roi, dst1_roi));
|
||||
OCL_ON(cv::phase(usrc1_roi, usrc2_roi, udst1_roi));
|
||||
Near(1e-2);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Magnitude /////////////////////////////////////////
|
||||
|
||||
typedef ArithmTestBase Magnitude;
|
||||
|
||||
OCL_TEST_P(Magnitude, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::magnitude(src1_roi, src2_roi, dst1_roi));
|
||||
OCL_ON(cv::magnitude(usrc1_roi, usrc2_roi, udst1_roi));
|
||||
Near(depth == CV_64F ? 1e-5 : 1e-2);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Instantiation /////////////////////////////////////////
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Lut, Combine(::testing::Values(CV_8U, CV_8S), OCL_ALL_DEPTHS, ::testing::Values(1, 2, 3, 4), Bool(), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Add, Combine(OCL_ALL_DEPTHS, ::testing::Values(1, 2, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Subtract, Combine(OCL_ALL_DEPTHS, ::testing::Values(1, 2, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Log, Combine(::testing::Values(CV_32F, CV_64F), ::testing::Values(1, 2, 3, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Exp, Combine(::testing::Values(CV_32F, CV_64F), ::testing::Values(1, 2, 3, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Phase, Combine(::testing::Values(CV_32F, CV_64F), ::testing::Values(1, 2, 3, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Magnitude, Combine(::testing::Values(CV_32F, CV_64F), ::testing::Values(1, 2, 3, 4), Bool()));
|
||||
|
||||
} } // namespace cvtest::ocl
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user