mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -1965,8 +1965,8 @@ The function solveCubic finds the real roots of a cubic equation:
|
||||
|
||||
The roots are stored in the roots array.
|
||||
@param coeffs equation coefficients, an array of 3 or 4 elements.
|
||||
@param roots output array of real roots that has 1 or 3 elements.
|
||||
@return number of real roots. It can be 0, 1 or 2.
|
||||
@param roots output array of real roots that has 0, 1, 2 or 3 elements.
|
||||
@return number of real roots. It can be -1 (all real numbers), 0, 1, 2 or 3.
|
||||
*/
|
||||
CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);
|
||||
|
||||
|
||||
@@ -225,32 +225,30 @@ These operations allow to reorder or recombine elements in one or multiple vecto
|
||||
Element-wise binary and unary operations.
|
||||
|
||||
- Arithmetics:
|
||||
@ref v_add(const v_reg &a, const v_reg &b) "+",
|
||||
@ref v_sub(const v_reg &a, const v_reg &b) "-",
|
||||
@ref v_mul(const v_reg &a, const v_reg &b) "*",
|
||||
@ref v_div(const v_reg &a, const v_reg &b) "/",
|
||||
@ref v_add,
|
||||
@ref v_sub,
|
||||
@ref v_mul,
|
||||
@ref v_div,
|
||||
@ref v_mul_expand
|
||||
|
||||
- Non-saturating arithmetics: @ref v_add_wrap, @ref v_sub_wrap
|
||||
|
||||
- Bitwise shifts:
|
||||
@ref v_shl(const v_reg &a, int s) "<<",
|
||||
@ref v_shr(const v_reg &a, int s) ">>",
|
||||
@ref v_shl, @ref v_shr
|
||||
|
||||
- Bitwise logic:
|
||||
@ref v_and(const v_reg &a, const v_reg &b) "&",
|
||||
@ref v_or(const v_reg &a, const v_reg &b) "|",
|
||||
@ref v_xor(const v_reg &a, const v_reg &b) "^",
|
||||
@ref v_not(const v_reg &a) "~"
|
||||
@ref v_and,
|
||||
@ref v_or,
|
||||
@ref v_xor,
|
||||
@ref v_not
|
||||
|
||||
- Comparison:
|
||||
@ref v_gt(const v_reg &a, const v_reg &b) ">",
|
||||
@ref v_ge(const v_reg &a, const v_reg &b) ">=",
|
||||
@ref v_lt(const v_reg &a, const v_reg &b) "<",
|
||||
@ref v_le(const v_reg &a, const v_reg &b) "<=",
|
||||
@ref v_eq(const v_reg &a, const v_reg &b) "==",
|
||||
@ref v_ne(const v_reg &a, const v_reg &b) "!="
|
||||
@ref v_gt,
|
||||
@ref v_ge,
|
||||
@ref v_lt,
|
||||
@ref v_le,
|
||||
@ref v_eq,
|
||||
@ref v_ne
|
||||
|
||||
- min/max: @ref v_min, @ref v_max
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
// This file has been created for compatibility with older versions of Universal Intrinscs
|
||||
// Binary operators for vector types has been removed since version 4.11
|
||||
// Include this file manually after OpenCV headers if you need these operators
|
||||
|
||||
#ifndef OPENCV_HAL_INTRIN_LEGACY_OPS_HPP
|
||||
#define OPENCV_HAL_INTRIN_LEGACY_OPS_HPP
|
||||
|
||||
#ifdef __OPENCV_BUILD
|
||||
#error "Universal Intrinsics operators are deprecated and should not be used in OpenCV library"
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
#warning "Operators might conflict with built-in functions on RISC-V platform"
|
||||
#endif
|
||||
|
||||
#if defined(CV_VERSION) && CV_VERSION_MAJOR == 4 && CV_VERSION_MINOR < 9
|
||||
#warning "Older versions of OpenCV (<4.9) already have Universal Intrinscs operators"
|
||||
#endif
|
||||
|
||||
|
||||
namespace cv { namespace hal {
|
||||
|
||||
#define BIN_OP(OP, FUN) \
|
||||
template <typename R> R operator OP (const R & lhs, const R & rhs) { return FUN(lhs, rhs); }
|
||||
|
||||
#define BIN_A_OP(OP, FUN) \
|
||||
template <typename R> R & operator OP (R & res, const R & val) { res = FUN(res, val); return res; }
|
||||
|
||||
#define UN_OP(OP, FUN) \
|
||||
template <typename R> R operator OP (const R & val) { return FUN(val); }
|
||||
|
||||
BIN_OP(+, v_add)
|
||||
BIN_OP(-, v_sub)
|
||||
BIN_OP(*, v_mul)
|
||||
BIN_OP(/, v_div)
|
||||
BIN_OP(&, v_and)
|
||||
BIN_OP(|, v_or)
|
||||
BIN_OP(^, v_xor)
|
||||
|
||||
BIN_OP(==, v_eq)
|
||||
BIN_OP(!=, v_ne)
|
||||
BIN_OP(<, v_lt)
|
||||
BIN_OP(>, v_gt)
|
||||
BIN_OP(<=, v_le)
|
||||
BIN_OP(>=, v_ge)
|
||||
|
||||
BIN_A_OP(+=, v_add)
|
||||
BIN_A_OP(-=, v_sub)
|
||||
BIN_A_OP(*=, v_mul)
|
||||
BIN_A_OP(/=, v_div)
|
||||
BIN_A_OP(&=, v_and)
|
||||
BIN_A_OP(|=, v_or)
|
||||
BIN_A_OP(^=, v_xor)
|
||||
|
||||
UN_OP(~, v_not)
|
||||
|
||||
// TODO: shift operators?
|
||||
|
||||
}} // cv::hal::
|
||||
|
||||
//==============================================================================
|
||||
|
||||
#ifdef OPENCV_ENABLE_INLINE_INTRIN_OPERATOR_TEST
|
||||
|
||||
namespace cv { namespace hal {
|
||||
|
||||
inline static void opencv_operator_compile_test()
|
||||
{
|
||||
using namespace cv;
|
||||
v_float32 a, b, c;
|
||||
uint8_t shift = 1;
|
||||
a = b + c;
|
||||
a = b - c;
|
||||
a = b * c;
|
||||
a = b / c;
|
||||
a = b & c;
|
||||
a = b | c;
|
||||
a = b ^ c;
|
||||
// a = b >> shift;
|
||||
// a = b << shift;
|
||||
|
||||
a = (b == c);
|
||||
a = (b != c);
|
||||
a = (b < c);}}
|
||||
a = (b > c);
|
||||
a = (b <= c);
|
||||
a = (b >= c);
|
||||
|
||||
a += b;
|
||||
a -= b;
|
||||
a *= b;
|
||||
a /= b;
|
||||
a &= b;
|
||||
a |= b;
|
||||
a ^= b;
|
||||
// a <<= shift;
|
||||
// a >>= shift;
|
||||
|
||||
a = ~b;
|
||||
}
|
||||
|
||||
}} // cv::hal::
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // OPENCV_HAL_INTRIN_LEGACY_OPS_HPP
|
||||
@@ -3184,6 +3184,12 @@ Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
MatExpr Mat_<_Tp>::zeros(int _ndims, const int* _sizes)
|
||||
{
|
||||
return Mat::zeros(_ndims, _sizes, traits::Type<_Tp>::value);
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
MatExpr Mat_<_Tp>::zeros(int rows, int cols)
|
||||
{
|
||||
|
||||
@@ -147,7 +147,23 @@ namespace cv { namespace cuda
|
||||
inline explicit NppStreamHandler(cudaStream_t newStream)
|
||||
{
|
||||
nppStreamContext = {};
|
||||
nppSafeCall(nppGetStreamContext(&nppStreamContext));
|
||||
#if CUDA_VERSION < 12090
|
||||
nppSafeCall(nppGetStreamContext(&nppStreamContext));
|
||||
#else
|
||||
int device = 0;
|
||||
cudaSafeCall(cudaGetDevice(&device));
|
||||
|
||||
cudaDeviceProp prop{};
|
||||
cudaSafeCall(cudaGetDeviceProperties(&prop, device));
|
||||
|
||||
nppStreamContext.nCudaDeviceId = device;
|
||||
nppStreamContext.nMultiProcessorCount = prop.multiProcessorCount;
|
||||
nppStreamContext.nMaxThreadsPerMultiProcessor = prop.maxThreadsPerMultiProcessor;
|
||||
nppStreamContext.nMaxThreadsPerBlock = prop.maxThreadsPerBlock;
|
||||
nppStreamContext.nSharedMemPerBlock = prop.sharedMemPerBlock;
|
||||
nppStreamContext.nCudaDevAttrComputeCapabilityMajor = prop.major;
|
||||
nppStreamContext.nCudaDevAttrComputeCapabilityMinor = prop.minor;
|
||||
#endif
|
||||
nppStreamContext.hStream = newStream;
|
||||
cudaSafeCall(cudaStreamGetFlags(nppStreamContext.hStream, &nppStreamContext.nStreamFlags));
|
||||
}
|
||||
|
||||
@@ -694,7 +694,7 @@ OCL_PERF_TEST_P(PowFixture, Pow, ::testing::Combine(
|
||||
|
||||
///////////// iPow ////////////////////////
|
||||
OCL_PERF_TEST_P(PowFixture, iPow, ::testing::Combine(
|
||||
OCL_TEST_SIZES, OCL_PERF_ENUM(CV_8UC1, CV_8SC1,CV_16UC1,CV_16SC1,CV_32SC1)))
|
||||
OCL_TEST_SIZES, OCL_PERF_ENUM(CV_8UC1, CV_8UC3, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1)))
|
||||
{
|
||||
const Size_MatType_t params = GetParam();
|
||||
const Size srcSize = get<0>(params);
|
||||
@@ -706,7 +706,7 @@ OCL_PERF_TEST_P(PowFixture, iPow, ::testing::Combine(
|
||||
randu(src, 0, 100);
|
||||
declare.in(src).out(dst);
|
||||
|
||||
OCL_TEST_CYCLE() cv::pow(src, 7.0, dst);
|
||||
OCL_TEST_CYCLE() cv::pow(src, 3, dst);
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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() )
|
||||
{
|
||||
|
||||
@@ -1581,6 +1581,7 @@ NormDiffFunc getNormDiffFunc(int normType, int depth)
|
||||
0
|
||||
},
|
||||
};
|
||||
if (normType >= 3 || normType < 0) return nullptr;
|
||||
|
||||
return normDiffTab[normType][depth];
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -132,19 +132,25 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool)
|
||||
use_roi = GET_PARAM(2);
|
||||
}
|
||||
|
||||
void generateTestData(bool with_val_in_range = false)
|
||||
void generateTestData(bool with_val_in_range = false,
|
||||
double minVal1 = std::numeric_limits<double>::quiet_NaN(), double maxVal1 = std::numeric_limits<double>::quiet_NaN(),
|
||||
double minVal2 = std::numeric_limits<double>::quiet_NaN(), double maxVal2 = std::numeric_limits<double>::quiet_NaN()
|
||||
)
|
||||
{
|
||||
const int type = CV_MAKE_TYPE(depth, cn);
|
||||
|
||||
double minV = cvtest::getMinVal(type);
|
||||
double maxV = cvtest::getMaxVal(type);
|
||||
double minV1 = cvIsNaN(minVal1) ? 2 : minVal1;
|
||||
double maxV1 = cvIsNaN(maxVal1) ? 11 : maxVal1;
|
||||
|
||||
double minV2 = cvIsNaN(minVal2) ? std::max(-1540., cvtest::getMinVal(type)) : minVal2;
|
||||
double maxV2 = cvIsNaN(maxVal2) ? std::min(1740., cvtest::getMaxVal(type)) : maxVal2;
|
||||
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src1, src1_roi, roiSize, src1Border, type, 2, 11); // FIXIT: Test with minV, maxV
|
||||
randomSubMat(src1, src1_roi, roiSize, src1Border, type, minV1, maxV1); // FIXIT: Test with minV, maxV
|
||||
|
||||
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src2, src2_roi, roiSize, src2Border, type, std::max(-1540., minV), std::min(1740., maxV));
|
||||
randomSubMat(src2, src2_roi, roiSize, src2Border, type, minV2, maxV2);
|
||||
|
||||
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst1, dst1_roi, roiSize, dst1Border, type, 5, 16);
|
||||
@@ -162,8 +168,8 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool)
|
||||
|
||||
if (with_val_in_range)
|
||||
{
|
||||
val_in_range = cv::Scalar(rng.uniform(minV, maxV), rng.uniform(minV, maxV),
|
||||
rng.uniform(minV, maxV), rng.uniform(minV, maxV));
|
||||
val_in_range = cv::Scalar(rng.uniform(minV1, maxV1), rng.uniform(minV1, maxV1),
|
||||
rng.uniform(minV1, maxV1), rng.uniform(minV1, maxV1));
|
||||
}
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src1);
|
||||
@@ -844,14 +850,30 @@ OCL_TEST_P(Pow, Mat)
|
||||
for (int j = 0; j < 1/*test_loop_times*/; j++)
|
||||
for (int k = 0, size = sizeof(pows) / sizeof(double); k < size; ++k)
|
||||
{
|
||||
SCOPED_TRACE(pows[k]);
|
||||
SCOPED_TRACE(cv::format("POW=%g", pows[k]));
|
||||
|
||||
generateTestData();
|
||||
generateTestData(false, 1, 3);
|
||||
|
||||
OCL_OFF(cv::pow(src1_roi, pows[k], dst1_roi));
|
||||
OCL_ON(cv::pow(usrc1_roi, pows[k], udst1_roi));
|
||||
|
||||
OCL_EXPECT_MATS_NEAR_RELATIVE(dst1, 1e-5);
|
||||
|
||||
if (cvtest::debugLevel >= 100)
|
||||
{
|
||||
cv::Rect roi(0, 0, 4, 4);
|
||||
std::cout << src1_roi(roi) << std::endl;
|
||||
std::cout << dst1_roi(roi) << std::endl;
|
||||
std::cout << udst1_roi(roi) << std::endl;
|
||||
|
||||
Mat diff;
|
||||
cv::absdiff(dst1_roi, udst1_roi, diff);
|
||||
std::cout << std::endl << diff(roi) << std::endl;
|
||||
|
||||
std::cout << std::endl << dst1_roi << std::endl;
|
||||
std::cout << std::endl << udst1_roi << std::endl;
|
||||
std::cout << std::endl << diff << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,19 @@ void test_hal_intrin_float16();
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
#if defined (__clang__) && defined(__has_warning)
|
||||
#if __has_warning("-Wmaybe-uninitialized")
|
||||
#define CV_DISABLE_GCC_MAYBE_UNINITIALIZED_WARNINGS
|
||||
#endif
|
||||
#elif defined (__GNUC__) // in case of gcc, it does not have macro __has_warning
|
||||
#define CV_DISABLE_GCC_MAYBE_UNINITIALIZED_WARNINGS
|
||||
#endif
|
||||
|
||||
#if defined (CV_DISABLE_GCC_MAYBE_UNINITIALIZED_WARNINGS)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
template <typename R> struct Data
|
||||
{
|
||||
typedef typename VTraits<R>::lane_type LaneType;
|
||||
@@ -2597,6 +2610,10 @@ void test_hal_intrin_float16()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (CV_DISABLE_GCC_MAYBE_UNINITIALIZED_WARNINGS)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif //CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
//CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
|
||||
@@ -1323,6 +1323,13 @@ TEST(Core_Mat, copyMakeBoderUndefinedBehavior)
|
||||
EXPECT_EQ(0, cv::norm(src.col(2), dst(Rect(5,1,1,4))));
|
||||
}
|
||||
|
||||
TEST(Core_Mat, zeros)
|
||||
{
|
||||
// Should not fail during linkage.
|
||||
const int dims[] = {2, 2, 4};
|
||||
cv::Mat1f mat = cv::Mat1f::zeros(3, dims);
|
||||
}
|
||||
|
||||
TEST(Core_Matx, fromMat_)
|
||||
{
|
||||
Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
|
||||
|
||||
@@ -1734,7 +1734,7 @@ static void checkRoot(Mat& r, T re, T im)
|
||||
{
|
||||
for (int i = 0; i < r.cols*r.rows; i++)
|
||||
{
|
||||
Vec<T, 2> v = *(Vec<T, 2>*)r.ptr(i);
|
||||
Vec<T, 2>& v = *(Vec<T, 2>*)r.ptr(i);
|
||||
if (fabs(re - v[0]) < 1e-6 && fabs(im - v[1]) < 1e-6)
|
||||
{
|
||||
v[0] = std::numeric_limits<T>::quiet_NaN();
|
||||
@@ -1744,6 +1744,179 @@ static void checkRoot(Mat& r, T re, T im)
|
||||
}
|
||||
GTEST_NONFATAL_FAILURE_("Can't find root") << "(" << re << ", " << im << ")";
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubicConstant, accuracy)
|
||||
{
|
||||
{
|
||||
const std::vector<double> coeffs{0., 0., 0., 1.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 0);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{0., 0., 0., 0.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, -1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubicLinear, accuracy)
|
||||
{
|
||||
const std::vector<double> coeffs{0., 0., 2., -2.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], 1.);
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubicQuadratic, accuracy)
|
||||
{
|
||||
{
|
||||
const std::vector<double> coeffs{0., 2., -4., 4.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 0);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{0., 2., -4., 2.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], 1.);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{0., 2., -6., 4.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 2);
|
||||
EXPECT_EQ(roots[0], 2.);
|
||||
EXPECT_EQ(roots[1], 1.);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubicCubic, accuracy)
|
||||
{
|
||||
{
|
||||
const std::vector<double> coeffs{2., -6., 6., -2.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], 1.);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{2., -10., 24., -16.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{2., -10., 16., -8.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_TRUE(num_roots == 2 || num_roots == 3);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
EXPECT_NEAR(roots[1], 2., 1e-8);
|
||||
if (num_roots == 3)
|
||||
{
|
||||
EXPECT_NEAR(roots[2], 2., 1e-8);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{2., -12., 22., -12.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 3);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
EXPECT_NEAR(roots[1], 3., 1e-8);
|
||||
EXPECT_NEAR(roots[2], 2., 1e-8);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubicNormalizedCubic, accuracy)
|
||||
{
|
||||
{
|
||||
const std::vector<double> coeffs{-3., 3., -1.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], 1.);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{-5., 12., -8.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{-5., 8., -4.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_TRUE(num_roots == 2 || num_roots == 3);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
EXPECT_NEAR(roots[1], 2., 1e-8);
|
||||
if (num_roots == 3)
|
||||
{
|
||||
EXPECT_NEAR(roots[2], 2., 1e-8);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{-6., 11., -6.};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 3);
|
||||
EXPECT_NEAR(roots[0], 1., 1e-8);
|
||||
EXPECT_NEAR(roots[1], 3., 1e-8);
|
||||
EXPECT_NEAR(roots[2], 2., 1e-8);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_SolveCubic, regression_27323)
|
||||
{
|
||||
{
|
||||
const std::vector<double> coeffs{2e-13, 1, -2, 1};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], -5e12 - 2.);
|
||||
}
|
||||
|
||||
{
|
||||
const std::vector<double> coeffs{5e12, -1e13, 5e12};
|
||||
std::vector<double> roots;
|
||||
const auto num_roots = solveCubic(coeffs, roots);
|
||||
|
||||
EXPECT_EQ(num_roots, 1);
|
||||
EXPECT_EQ(roots[0], -5e12 - 2.);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_SolvePoly, regression_5599)
|
||||
{
|
||||
// x^4 - x^2 = 0, roots: 1, -1, 0, 0
|
||||
|
||||
Reference in New Issue
Block a user