Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2024-02-12 14:20:35 +03:00
131 changed files with 3446 additions and 864 deletions

View File

@@ -80,52 +80,133 @@ static bool ocl_convertFp16( InputArray _src, OutputArray _dst, int sdepth, int
size_t globalsize[2] = { (size_t)src.cols * cn / kercn, ((size_t)src.rows + rowsPerWI - 1) / rowsPerWI };
return k.run(2, globalsize, NULL, false);
}
#endif
void Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) const
static bool ocl_convertTo(InputArray src_, OutputArray dst_, int ddepth, bool noScale, double alpha, double beta)
{
CV_INSTRUMENT_REGION();
if( empty() )
CV_Assert(ddepth >= 0);
int stype = src_.type();
int sdepth = CV_MAT_DEPTH(stype);
int cn = CV_MAT_CN(stype);
int dtype = CV_MAKETYPE(ddepth, cn);
int wdepth = (sdepth == CV_64F) ? CV_64F : CV_32F;
bool needDouble = sdepth == CV_64F || ddepth == CV_64F;
bool doubleCheck = true;
if (needDouble)
{
_dst.release();
return;
doubleCheck = ocl::Device::getDefault().hasFP64();
}
bool halfCheck = true;
bool needHalf = sdepth == CV_16F || ddepth == CV_16F;
if (needHalf)
{
halfCheck = ocl::Device::getDefault().hasFP16();
}
bool noScale = fabs(alpha-1) < DBL_EPSILON && fabs(beta) < DBL_EPSILON;
if (!doubleCheck)
return false;
if (!halfCheck)
return false;
if( _type < 0 )
_type = _dst.fixedType() ? _dst.type() : type();
const int rowsPerWI = 4;
char cvt[2][50];
ocl::Kernel k("convertTo", ocl::core::convert_oclsrc,
format("-D srcT=%s -D WT=%s -D dstT=%s -D convertToWT=%s -D convertToDT=%s -D rowsPerWI=%d%s%s%s",
ocl::typeToStr(sdepth), ocl::typeToStr(wdepth), ocl::typeToStr(ddepth),
ocl::convertTypeStr(sdepth, wdepth, 1, cvt[0], sizeof(cvt[0])),
ocl::convertTypeStr(wdepth, ddepth, 1, cvt[1], sizeof(cvt[1])),
rowsPerWI,
needDouble ? " -D DOUBLE_SUPPORT" : "",
needHalf ? " -D HALF_SUPPORT" : "",
noScale ? " -D NO_SCALE" : ""
)
);
if (k.empty())
return false;
UMat src = src_.getUMat();
dst_.createSameSize(src_, dtype);
UMat dst = dst_.getUMat();
float alphaf = (float)alpha, betaf = (float)beta;
if (noScale)
k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst, cn));
else if (wdepth == CV_32F)
k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst, cn), alphaf, betaf);
else
_type = CV_MAKETYPE(CV_MAT_DEPTH(_type), channels());
k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst, cn), alpha, beta);
int sdepth = depth(), ddepth = CV_MAT_DEPTH(_type);
if( sdepth == ddepth && noScale )
size_t globalsize[2] = {
(size_t)dst.cols * cn,
divUp((size_t)dst.rows, rowsPerWI)
};
if (!k.run(2, globalsize, NULL, false))
return false;
CV_IMPL_ADD(CV_IMPL_OCL);
return true;
}
#endif
void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const
{
CV_INSTRUMENT_REGION();
if (empty())
{
copyTo(_dst);
dst.release();
return;
}
int stype = type();
int sdepth = CV_MAT_DEPTH(stype);
int ddepth = sdepth;
if (type_ >= 0)
ddepth = CV_MAT_DEPTH(type_);
else
ddepth = dst.fixedType() ? dst.depth() : sdepth;
bool noScale = std::fabs(alpha - 1) < DBL_EPSILON && std::fabs(beta) < DBL_EPSILON;
if (sdepth == ddepth && noScale)
{
copyTo(dst);
return;
}
CV_OCL_RUN(dims <= 2 && dst.isUMat(),
ocl_convertTo(*this, dst, ddepth, noScale, alpha, beta))
int cn = channels();
int dtype = CV_MAKETYPE(ddepth, cn);
Mat src = *this;
bool allowTransposed = dims == 1 ||
_dst.kind() == _InputArray::STD_VECTOR ||
(_dst.fixedSize() && _dst.dims() == 1);
_dst.create( dims, size, _type, -1, allowTransposed );
Mat dst = _dst.getMat();
dst.kind() == _InputArray::STD_VECTOR ||
(dst.fixedSize() && dst.dims() == 1);
dst.create( dims, size, dtype, -1, allowTransposed );
Mat dstMat = dst.getMat();
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta};
int cn = channels();
CV_Assert( func != 0 );
if( dims <= 2 )
{
Size sz = getContinuousSize2D(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
Size sz = getContinuousSize2D(src, dstMat, cn);
func(src.data, src.step, 0, 0, dstMat.data, dstMat.step, sz, scale);
}
else
{
const Mat* arrays[] = {&src, &dst, 0};
const Mat* arrays[] = {&src, &dstMat, 0};
uchar* ptrs[2] = {};
NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*cn), 1);
@@ -135,6 +216,44 @@ void Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) cons
}
}
void UMat::convertTo(OutputArray dst, int type_, double alpha, double beta) const
{
CV_INSTRUMENT_REGION();
if (empty())
{
dst.release();
return;
}
#ifdef HAVE_OPENCL
int stype = type();
int sdepth = CV_MAT_DEPTH(stype);
int ddepth = sdepth;
if (type_ >= 0)
ddepth = CV_MAT_DEPTH(type_);
else
ddepth = dst.fixedType() ? dst.depth() : sdepth;
bool noScale = std::fabs(alpha - 1) < DBL_EPSILON && std::fabs(beta) < DBL_EPSILON;
if (sdepth == ddepth && noScale)
{
copyTo(dst);
return;
}
CV_OCL_RUN(dims <= 2,
ocl_convertTo(*this, dst, ddepth, noScale, alpha, beta))
#endif // HAVE_OPENCL
UMat src = *this; // Fake reference to itself.
// Resolves issue 8693 in case of src == dst.
Mat m = getMat(ACCESS_READ);
m.convertTo(dst, type_, alpha, beta);
(void)src;
}
//==================================================================================================
void convertFp16(InputArray _src, OutputArray _dst)