|
|
|
@ -466,7 +466,7 @@ template <typename T> Scalar ocl_part_sum(Mat m) |
|
|
|
|
|
|
|
|
|
enum { OCL_OP_SUM = 0, OCL_OP_SUM_ABS = 1, OCL_OP_SUM_SQR = 2 }; |
|
|
|
|
|
|
|
|
|
static bool ocl_sum( InputArray _src, Scalar & res, int sum_op ) |
|
|
|
|
static bool ocl_sum( InputArray _src, Scalar & res, int sum_op, InputArray _mask = noArray() ) |
|
|
|
|
{ |
|
|
|
|
CV_Assert(sum_op == OCL_OP_SUM || sum_op == OCL_OP_SUM_ABS || sum_op == OCL_OP_SUM_SQR); |
|
|
|
|
|
|
|
|
@ -479,7 +479,10 @@ static bool ocl_sum( InputArray _src, Scalar & res, int sum_op ) |
|
|
|
|
int dbsize = ocl::Device::getDefault().maxComputeUnits(); |
|
|
|
|
size_t wgs = ocl::Device::getDefault().maxWorkGroupSize(); |
|
|
|
|
|
|
|
|
|
int ddepth = std::max(CV_32S, depth), dtype = CV_MAKE_TYPE(ddepth, cn); |
|
|
|
|
int ddepth = std::max(sum_op == OCL_OP_SUM_SQR ? CV_32F : CV_32S, depth), |
|
|
|
|
dtype = CV_MAKE_TYPE(ddepth, cn); |
|
|
|
|
bool haveMask = _mask.kind() != _InputArray::NONE; |
|
|
|
|
CV_Assert(!haveMask || _mask.type() == CV_8UC1); |
|
|
|
|
|
|
|
|
|
int wgs2_aligned = 1; |
|
|
|
|
while (wgs2_aligned < (int)wgs) |
|
|
|
@ -489,19 +492,27 @@ static bool ocl_sum( InputArray _src, Scalar & res, int sum_op ) |
|
|
|
|
static const char * const opMap[3] = { "OP_SUM", "OP_SUM_ABS", "OP_SUM_SQR" }; |
|
|
|
|
char cvt[40]; |
|
|
|
|
ocl::Kernel k("reduce", ocl::core::reduce_oclsrc, |
|
|
|
|
format("-D srcT=%s -D dstT=%s -D convertToDT=%s -D %s -D WGS=%d -D WGS2_ALIGNED=%d%s", |
|
|
|
|
format("-D srcT=%s -D dstT=%s -D convertToDT=%s -D %s -D WGS=%d -D WGS2_ALIGNED=%d%s%s", |
|
|
|
|
ocl::typeToStr(type), ocl::typeToStr(dtype), ocl::convertTypeStr(depth, ddepth, cn, cvt), |
|
|
|
|
opMap[sum_op], (int)wgs, wgs2_aligned, |
|
|
|
|
doubleSupport ? " -D DOUBLE_SUPPORT" : "")); |
|
|
|
|
doubleSupport ? " -D DOUBLE_SUPPORT" : "", |
|
|
|
|
haveMask ? " -D HAVE_MASK" : "")); |
|
|
|
|
if (k.empty()) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
UMat src = _src.getUMat(), db(1, dbsize, dtype); |
|
|
|
|
k.args(ocl::KernelArg::ReadOnlyNoSize(src), src.cols, (int)src.total(), |
|
|
|
|
dbsize, ocl::KernelArg::PtrWriteOnly(db)); |
|
|
|
|
UMat src = _src.getUMat(), db(1, dbsize, dtype), mask = _mask.getUMat(); |
|
|
|
|
|
|
|
|
|
ocl::KernelArg srcarg = ocl::KernelArg::ReadOnlyNoSize(src), |
|
|
|
|
dbarg = ocl::KernelArg::PtrWriteOnly(db), |
|
|
|
|
maskarg = ocl::KernelArg::ReadOnlyNoSize(mask); |
|
|
|
|
|
|
|
|
|
if (haveMask) |
|
|
|
|
k.args(srcarg, src.cols, (int)src.total(), dbsize, dbarg, maskarg); |
|
|
|
|
else |
|
|
|
|
k.args(srcarg, src.cols, (int)src.total(), dbsize, dbarg); |
|
|
|
|
|
|
|
|
|
size_t globalsize = dbsize * wgs; |
|
|
|
|
if (k.run(1, &globalsize, &wgs, true)) |
|
|
|
|
if (k.run(1, &globalsize, &wgs, false)) |
|
|
|
|
{ |
|
|
|
|
typedef Scalar (*part_sum)(Mat m); |
|
|
|
|
part_sum funcs[3] = { ocl_part_sum<int>, ocl_part_sum<float>, ocl_part_sum<double> }, |
|
|
|
@ -806,15 +817,18 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask ) |
|
|
|
|
|
|
|
|
|
namespace cv { |
|
|
|
|
|
|
|
|
|
static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv ) |
|
|
|
|
static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) |
|
|
|
|
{ |
|
|
|
|
bool haveMask = _mask.kind() != _InputArray::NONE; |
|
|
|
|
|
|
|
|
|
Scalar mean, stddev; |
|
|
|
|
if (!ocl_sum(_src, mean, OCL_OP_SUM)) |
|
|
|
|
if (!ocl_sum(_src, mean, OCL_OP_SUM, _mask)) |
|
|
|
|
return false; |
|
|
|
|
if (!ocl_sum(_src, stddev, OCL_OP_SUM_SQR)) |
|
|
|
|
if (!ocl_sum(_src, stddev, OCL_OP_SUM_SQR, _mask)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
double total = 1.0 / _src.total(); |
|
|
|
|
int nz = haveMask ? countNonZero(_mask) : (int)_src.total(); |
|
|
|
|
double total = nz != 0 ? 1.0 / nz : 0; |
|
|
|
|
int k, j, cn = _src.channels(); |
|
|
|
|
for (int i = 0; i < cn; ++i) |
|
|
|
|
{ |
|
|
|
@ -849,7 +863,7 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv |
|
|
|
|
|
|
|
|
|
void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) |
|
|
|
|
{ |
|
|
|
|
if (ocl::useOpenCL() && _src.isUMat() && _mask.empty() && ocl_meanStdDev(_src, _mean, _sdv)) |
|
|
|
|
if (ocl::useOpenCL() && _src.isUMat() && ocl_meanStdDev(_src, _mean, _sdv, _mask)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
Mat src = _src.getMat(), mask = _mask.getMat(); |
|
|
|
@ -1882,13 +1896,14 @@ static NormDiffFunc getNormDiffFunc(int normType, int depth) |
|
|
|
|
|
|
|
|
|
namespace cv { |
|
|
|
|
|
|
|
|
|
static bool ocl_norm( InputArray _src, int normType, double & result ) |
|
|
|
|
static bool ocl_norm( InputArray _src, int normType, InputArray _mask, double & result ) |
|
|
|
|
{ |
|
|
|
|
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); |
|
|
|
|
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0; |
|
|
|
|
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0, |
|
|
|
|
haveMask = _mask.kind() != _InputArray::NONE; |
|
|
|
|
|
|
|
|
|
if ( !(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2) || |
|
|
|
|
(!doubleSupport && depth == CV_64F)) |
|
|
|
|
(!doubleSupport && depth == CV_64F) || (normType == NORM_INF && haveMask && cn != 1)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
UMat src = _src.getUMat(); |
|
|
|
@ -1920,16 +1935,25 @@ static bool ocl_norm( InputArray _src, int normType, double & result ) |
|
|
|
|
else |
|
|
|
|
abssrc = src; |
|
|
|
|
|
|
|
|
|
cv::minMaxIdx(abssrc.reshape(1), NULL, &result); |
|
|
|
|
cv::minMaxIdx(haveMask ? abssrc : abssrc.reshape(1), NULL, &result, NULL, NULL, _mask); |
|
|
|
|
} |
|
|
|
|
else if (normType == NORM_L1 || normType == NORM_L2) |
|
|
|
|
{ |
|
|
|
|
Scalar s; |
|
|
|
|
Scalar sc; |
|
|
|
|
bool unstype = depth == CV_8U || depth == CV_16U; |
|
|
|
|
|
|
|
|
|
ocl_sum(src.reshape(1), s, normType == NORM_L2 ? |
|
|
|
|
OCL_OP_SUM_SQR : (unstype ? OCL_OP_SUM : OCL_OP_SUM_ABS) ); |
|
|
|
|
result = normType == NORM_L1 ? s[0] : std::sqrt(s[0]); |
|
|
|
|
if ( !ocl_sum(haveMask ? src : src.reshape(1), sc, normType == NORM_L2 ? |
|
|
|
|
OCL_OP_SUM_SQR : (unstype ? OCL_OP_SUM : OCL_OP_SUM_ABS), _mask) ) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
if (!haveMask) |
|
|
|
|
cn = 1; |
|
|
|
|
|
|
|
|
|
double s = 0.0; |
|
|
|
|
for (int i = 0; i < cn; ++i) |
|
|
|
|
s += sc[i]; |
|
|
|
|
|
|
|
|
|
result = normType == NORM_L1 ? s : std::sqrt(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
@ -1945,7 +1969,7 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) |
|
|
|
|
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && _src.type() == CV_8U) ); |
|
|
|
|
|
|
|
|
|
double _result = 0; |
|
|
|
|
if (ocl::useOpenCL() && _mask.empty() && _src.isUMat() && _src.dims() <= 2 && ocl_norm(_src, normType, _result)) |
|
|
|
|
if (ocl::useOpenCL() && _src.isUMat() && _src.dims() <= 2 && ocl_norm(_src, normType, _mask, _result)) |
|
|
|
|
return _result; |
|
|
|
|
|
|
|
|
|
Mat src = _src.getMat(), mask = _mask.getMat(); |
|
|
|
|