1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2025-05-27 16:48:22 +03:00
167 changed files with 7028 additions and 4687 deletions
+15 -1
View File
@@ -1223,8 +1223,22 @@ inline int hal_ni_copyToMasked(const uchar* src_data, size_t src_step, uchar* ds
#define cv_hal_copyToMasked hal_ni_copyToMasked
//! @endcond
//! @}
/**
@ brief sum
@param src_data Source image data
@param src_step Source image step
@param src_type Source image type
@param width, height Source image dimensions
@param result Pointer to save the sum result to.
*/
inline int hal_ni_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result)
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_sum hal_ni_sum
//! @endcond
//! @}
#if defined(__clang__)
#pragma clang diagnostic pop
+44 -5
View File
@@ -938,9 +938,40 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
bool issqrt = std::abs(power - 0.5) < DBL_EPSILON;
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW";
// Note: channels are unrolled
std::string extra_opts ="";
if (is_ipower)
{
int wdepth = CV_32F;
if (depth == CV_64F)
wdepth = CV_64F;
else if (depth == CV_16F)
wdepth = CV_16F;
char cvt[2][50];
extra_opts = format(
" -D srcT1=%s -DsrcT1_C1=%s"
" -D srcT2=int -D workST=int"
" -D workT=%s -D wdepth=%d -D convertToWT1=%s"
" -D convertToDT=%s"
" -D workT1=%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)),
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)),
ocl::typeToStr(CV_MAKE_TYPE(wdepth, 1)),
wdepth,
ocl::convertTypeStr(depth, wdepth, 1, cvt[0], sizeof(cvt[0])),
ocl::convertTypeStr(wdepth, depth, 1, cvt[1], sizeof(cvt[1])),
ocl::typeToStr(wdepth)
);
}
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
ocl::typeToStr(depth), depth, rowsPerWI, op,
format("-D cn=%d -D dstT=%s -D dstT_C1=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D %s%s%s%s",
1,
ocl::typeToStr(depth), ocl::typeToStr(depth), depth, rowsPerWI, op,
" -D UNARY_OP=1",
extra_opts.empty() ? "" : extra_opts.c_str(),
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
@@ -1396,7 +1427,7 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
{
if( a1 == 0 )
{
if( a2 == 0 )
if( a2 == 0 ) // constant
n = a3 == 0 ? -1 : 0;
else
{
@@ -1430,15 +1461,23 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
}
else
{
// cubic equation
a0 = 1./a0;
a1 *= a0;
a2 *= a0;
a3 *= a0;
double Q = (a1 * a1 - 3 * a2) * (1./9);
double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54);
double R = (a1 * (2 * a1 * a1 - 9 * a2) + 27 * a3) * (1./54);
double Qcubed = Q * Q * Q;
double d = Qcubed - R * R;
/*
Here we expand expression `Qcubed - R * R` for `d` variable
to reduce common terms `a1^6 / 729` and `-a1^4 * a2 / 81`
and thus decrease rounding error (in case of quite big coefficients).
And then we additionally group terms to further reduce rounding error.
*/
double d = (a1 * a1 * (a2 * a2 - 4 * a1 * a3) + 2 * a2 * (9 * a1 * a3 - 2 * a2 * a2) - 27 * a3 * a3) * (1./108);
if( d > 0 )
{
+1 -1
View File
@@ -559,7 +559,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) );
NormDiffFunc func = getNormDiffFunc(normType >> 1, depth);
CV_Assert( func != 0 );
CV_Assert( (normType >> 1) >= 3 || func != 0 );
if( src1.isContinuous() && src2.isContinuous() && mask.empty() )
{
+1
View File
@@ -1581,6 +1581,7 @@ NormDiffFunc getNormDiffFunc(int normType, int depth)
0
},
};
if (normType >= 3 || normType < 0) return nullptr;
return normDiffTab[normType][depth];
}
+23 -4
View File
@@ -80,6 +80,10 @@
#error "Kernel configuration error: ambiguous 'depth' value is defined, use 'DEPTH_dst' instead"
#endif
#define CAT__(x, y) x ## y
#define CAT_(x, y) CAT__(x, y)
#define CAT(x, y) CAT_(x, y)
#if DEPTH_dst < 5 /* CV_32F */
#define CV_DST_TYPE_IS_INTEGER
@@ -325,9 +329,12 @@
#define PROCESS_ELEM storedst(pow(srcelem1, srcelem2))
#elif defined OP_POWN
#undef workT
#define workT int
#define PROCESS_ELEM storedst(pown(srcelem1, srcelem2))
#if cn > 1
#define PROCESS_INIT CAT(int, cn) powi = (CAT(int, cn))srcelem2;
#else // cn
#define PROCESS_INIT int powi = srcelem2;
#endif
#define PROCESS_ELEM storedst(convertToDT(pown(srcelem1, powi)))
#elif defined OP_SQRT
#if CV_DST_TYPE_FIT_32F
@@ -469,7 +476,7 @@
#define srcelem2 srcelem2_
#endif
#if cn == 3
#if !defined(PROCESS_INIT) && cn == 3
#undef srcelem2
#define srcelem2 (workT)(srcelem2_.x, srcelem2_.y, srcelem2_.z)
#endif
@@ -517,6 +524,10 @@ __kernel void KF(__global const uchar * srcptr1, int srcstep1, int srcoffset1,
int x = get_global_id(0);
int y0 = get_global_id(1) * rowsPerWI;
#ifdef PROCESS_INIT
PROCESS_INIT
#endif
if (x < cols)
{
int mask_index = mad24(y0, maskstep, x + maskoffset);
@@ -542,6 +553,10 @@ __kernel void KF(__global const uchar * srcptr1, int srcstep1, int srcoffset1,
int x = get_global_id(0);
int y0 = get_global_id(1) * rowsPerWI;
#ifdef PROCESS_INIT
PROCESS_INIT
#endif
if (x < cols)
{
int src1_index = mad24(y0, srcstep1, mad24(x, (int)sizeof(srcT1_C1) * cn, srcoffset1));
@@ -564,6 +579,10 @@ __kernel void KF(__global const uchar * srcptr1, int srcstep1, int srcoffset1,
int x = get_global_id(0);
int y0 = get_global_id(1) * rowsPerWI;
#ifdef PROCESS_INIT
PROCESS_INIT
#endif
if (x < cols)
{
int mask_index = mad24(y0, maskstep, x + maskoffset);
+17 -75
View File
@@ -10,14 +10,6 @@
#include "sum.simd.hpp"
#include "sum.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
#ifndef OPENCV_IPP_SUM
#undef HAVE_IPP
#undef CV_IPP_RUN_FAST
#define CV_IPP_RUN_FAST(f, ...)
#undef CV_IPP_RUN
#define CV_IPP_RUN(c, f, ...)
#endif // OPENCV_IPP_SUM
namespace cv
{
@@ -126,95 +118,45 @@ bool ocl_sum( InputArray _src, Scalar & res, int sum_op, InputArray _mask,
#endif
#ifdef HAVE_IPP
static bool ipp_sum(Mat &src, Scalar &_res)
{
CV_INSTRUMENT_REGION_IPP();
#if IPP_VERSION_X100 >= 700
int cn = src.channels();
if (cn > 4)
return false;
size_t total_size = src.total();
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
if( src.dims <= 2 || (src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
{
IppiSize sz = { cols, rows };
int type = src.type();
typedef IppStatus (CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
typedef IppStatus (CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *);
ippiSumFuncHint ippiSumHint =
type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R :
type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R :
type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R :
0;
ippiSumFuncNoHint ippiSum =
type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R :
type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R :
type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R :
type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R :
type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R :
type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R :
type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R :
type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R :
type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R :
0;
CV_Assert(!ippiSumHint || !ippiSum);
if( ippiSumHint || ippiSum )
{
Ipp64f res[4];
IppStatus ret = ippiSumHint ?
CV_INSTRUMENT_FUN_IPP(ippiSumHint, src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiSum, src.ptr(), (int)src.step[0], sz, res);
if( ret >= 0 )
{
for( int i = 0; i < cn; i++ )
_res[i] = res[i];
return true;
}
}
}
#else
CV_UNUSED(src); CV_UNUSED(_res);
#endif
return false;
}
#endif
Scalar sum(InputArray _src)
{
CV_INSTRUMENT_REGION();
#if defined HAVE_OPENCL || defined HAVE_IPP
Scalar _res;
#endif
#ifdef HAVE_OPENCL
CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2,
ocl_sum(_src, _res, OCL_OP_SUM),
_res)
_res);
#endif
Mat src = _src.getMat();
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_sum(src, _res), _res);
int cn = src.channels();
CV_CheckLE( cn, 4, "cv::sum does not support more than 4 channels" );
int k, cn = src.channels(), depth = src.depth();
if (_src.dims() <= 2)
{
CALL_HAL_RET2(sum, cv_hal_sum, _res, src.data, src.step, src.type(), src.cols, src.rows, &_res[0]);
}
else if (_src.isContinuous())
{
CALL_HAL_RET2(sum, cv_hal_sum, _res, src.data, 0, src.type(), (int)src.total(), 1, &_res[0]);
}
int k, depth = src.depth();
SumFunc func = getSumFunc(depth);
if (func == nullptr) {
if (depth == CV_Bool && cn == 1)
return Scalar((double)countNonZero(src));
CV_Error(Error::StsNotImplemented, "");
}
CV_Assert( cn <= 4 && func != 0 );
const Mat* arrays[] = {&src, 0};
uchar* ptrs[1] = {};
NAryMatIterator it(arrays, ptrs);
Scalar s;
int total = (int)it.size, blockSize = total, partialBlockSize = 0;
int j, count = 0;
int _buf[CV_CN_MAX];
int* buf = (int*)&s[0];
int* buf = (int*)&_res[0];
size_t esz = 0;
bool partialSumIsInt = depth < CV_32S;
bool blockSum = partialSumIsInt || depth == CV_16F || depth == CV_16BF;
@@ -241,13 +183,13 @@ Scalar sum(InputArray _src)
if (partialSumIsInt) {
for( k = 0; k < cn; k++ )
{
s[k] += buf[k];
_res[k] += buf[k];
buf[k] = 0;
}
} else {
for( k = 0; k < cn; k++ )
{
s[k] += ((float*)buf)[k];
_res[k] += ((float*)buf)[k];
buf[k] = 0;
}
}
@@ -256,7 +198,7 @@ Scalar sum(InputArray _src)
ptrs[0] += bsz*esz;
}
}
return s;
return _res;
}
} // namespace