#ifdef HAVE_OPENCL
template <typename T>
-void getMinMaxRes(const Mat & db, double* minVal, double* maxVal,
+void getMinMaxRes(const Mat & db, double * minVal, double * maxVal,
int* minLoc, int* maxLoc,
- int groupnum, int cols)
+ int groupnum, int cols, double * maxVal2)
{
uint index_max = std::numeric_limits<uint>::max();
T minval = std::numeric_limits<T>::max();
- T maxval = std::numeric_limits<T>::min() > 0 ? -std::numeric_limits<T>::max() : std::numeric_limits<T>::min();
+ T maxval = std::numeric_limits<T>::min() > 0 ? -std::numeric_limits<T>::max() : std::numeric_limits<T>::min(), maxval2 = maxval;
uint minloc = index_max, maxloc = index_max;
int index = 0;
- const T * minptr = NULL, * maxptr = NULL;
+ const T * minptr = NULL, * maxptr = NULL, * maxptr2 = NULL;
const uint * minlocptr = NULL, * maxlocptr = NULL;
if (minVal || minLoc)
{
index += sizeof(uint) * groupnum;
}
if (maxLoc)
+ {
maxlocptr = (uint *)(db.data + index);
+ index += sizeof(uint) * groupnum;
+ }
+ if (maxVal2)
+ maxptr2 = (const T *)(db.data + index);
for (int i = 0; i < groupnum; i++)
{
maxval = maxptr[i];
}
}
+ if (maxptr2 && maxptr2[i] > maxval2)
+ maxval2 = maxptr2[i];
}
bool zero_mask = (minLoc && minloc == index_max) ||
(maxLoc && maxloc == index_max);
*minVal = zero_mask ? 0 : (double)minval;
if (maxVal)
*maxVal = zero_mask ? 0 : (double)maxval;
+ if (maxVal2)
+ *maxVal2 = zero_mask ? 0 : (double)maxval2;
if (minLoc)
{
}
}
-typedef void (*getMinMaxResFunc)(const Mat & db, double *minVal, double *maxVal,
- int *minLoc, int *maxLoc, int gropunum, int cols);
+typedef void (*getMinMaxResFunc)(const Mat & db, double * minVal, double * maxVal,
+ int * minLoc, int *maxLoc, int gropunum, int cols, double * maxVal2);
static bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minLoc, int* maxLoc, InputArray _mask,
- int ddepth = -1, bool absValues = false, InputArray _src2 = noArray(), bool calc2 = false)
+ int ddepth = -1, bool absValues = false, InputArray _src2 = noArray(), double * maxVal2 = NULL)
{
- CV_Assert( (_src.channels() == 1 && (_mask.empty() || _mask.type() == CV_8U)) ||
- (_src.channels() >= 1 && _mask.empty() && !minLoc && !maxLoc) );
-
const ocl::Device & dev = ocl::Device::getDefault();
bool doubleSupport = dev.doubleFPConfig() > 0, haveMask = !_mask.empty(),
haveSrc2 = _src2.kind() != _InputArray::NONE;
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type),
kercn = haveMask ? 1 : std::min(4, ocl::predictOptimalVectorWidth(_src));
+
+ CV_Assert( (cn == 1 && (_mask.empty() || _mask.type() == CV_8U)) ||
+ (cn >= 1 && _mask.empty() && !minLoc && !maxLoc) );
+
if (ddepth < 0)
ddepth = depth;
needMinLoc ? " -D NEED_MINLOC" : "", needMaxLoc ? " -D NEED_MAXLOC" : "",
ocl::typeToStr(ddepth), ocl::typeToStr(CV_MAKE_TYPE(ddepth, kercn)),
ocl::convertTypeStr(depth, ddepth, kercn, cvt), absValues ? " -D OP_ABS" : "",
- haveSrc2 ? " -D HAVE_SRC2" : "", calc2 ? " -D OP_CALC2" : "",
+ haveSrc2 ? " -D HAVE_SRC2" : "", maxVal2 ? " -D OP_CALC2" : "",
haveSrc2 && _src2.isContinuous() ? " -D HAVE_SRC2_CONT" : "");
ocl::Kernel k("minmaxloc", ocl::core::minmaxloc_oclsrc, opts);
int esz = CV_ELEM_SIZE(ddepth), esz32s = CV_ELEM_SIZE1(CV_32S),
dbsize = groupnum * ((needMinVal ? esz : 0) + (needMaxVal ? esz : 0) +
(needMinLoc ? esz32s : 0) + (needMaxLoc ? esz32s : 0) +
- (calc2 ? esz : 0));
+ (maxVal2 ? esz : 0));
UMat src = _src.getUMat(), src2 = _src2.getUMat(), db(1, dbsize, CV_8UC1), mask = _mask.getUMat();
if (cn > 1)
getMinMaxRes<double>
};
- getMinMaxResFunc func = functab[depth];
+ getMinMaxResFunc func = functab[ddepth];
int locTemp[2];
func(db.getMat(ACCESS_READ), minVal, maxVal,
needMinLoc ? minLoc ? minLoc : locTemp : minLoc,
- needMaxLoc ? maxLoc ? maxLoc : locTemp : maxLoc, groupnum, src.cols);
+ needMaxLoc ? maxLoc ? maxLoc : locTemp : maxLoc,
+ groupnum, src.cols, maxVal2);
return true;
}
}
else
{
- if (!ocl_minMaxIdx(_src1, NULL, &result, NULL, NULL, _mask, std::max(CV_32S, depth),
- false, _src2, relative))
+ if (!ocl_minMaxIdx(_src1, NULL, &sc1[0], NULL, NULL, _mask, std::max(CV_32S, depth),
+ false, _src2, relative ? &sc2[0] : NULL))
return false;
+ cn = 1;
}
double s2 = 0;