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*/
|
//M*/
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
#include "opencl_kernels.hpp"
|
||||||
|
|
||||||
namespace cv
|
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_p5 = 0.1555786518463281f*(float)(180/CV_PI);
|
||||||
static const float atan2_p7 = -0.04432655554792128f*(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 fastAtan2( float y, float x )
|
||||||
{
|
{
|
||||||
float ax = std::abs(x), ay = std::abs(y);
|
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 )
|
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();
|
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());
|
dst.create(X.dims, X.size, X.type());
|
||||||
Mat Mag = dst.getMat();
|
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 )
|
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();
|
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 );
|
dst.create( X.dims, X.size, type );
|
||||||
Mat Angle = dst.getMat();
|
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 )
|
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 );
|
_dst.create( src.dims, src.size, type );
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
|
||||||
|
|
||||||
const Mat* arrays[] = {&src, &dst, 0};
|
const Mat* arrays[] = {&src, &dst, 0};
|
||||||
uchar* ptrs[2];
|
uchar* ptrs[2];
|
||||||
NAryMatIterator it(arrays, ptrs);
|
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 )
|
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 );
|
_dst.create( src.dims, src.size, type );
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
CV_Assert( depth == CV_32F || depth == CV_64F );
|
|
||||||
|
|
||||||
const Mat* arrays[] = {&src, &dst, 0};
|
const Mat* arrays[] = {&src, &dst, 0};
|
||||||
uchar* ptrs[2];
|
uchar* ptrs[2];
|
||||||
NAryMatIterator it(arrays, ptrs);
|
NAryMatIterator it(arrays, ptrs);
|
||||||
|
@ -173,7 +173,9 @@
|
|||||||
#define PROCESS_ELEM dstelem = sqrt(srcelem1)
|
#define PROCESS_ELEM dstelem = sqrt(srcelem1)
|
||||||
|
|
||||||
#elif defined OP_LOG
|
#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
|
#elif defined OP_CMP
|
||||||
#define PROCESS_ELEM dstelem = convert_uchar(srcelem1 CMP_OPERATOR srcelem2 ? 255 : 0)
|
#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 /////////////////////////////////////////
|
//////////////////////////////////////// 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, 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, 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, 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
|
} } // namespace cvtest::ocl
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user