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

Merge branch 4.x

This commit is contained in:
Alexander Alekhin
2021-12-30 16:23:27 +00:00
951 changed files with 158314 additions and 152668 deletions
+78
View File
@@ -0,0 +1,78 @@
// 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.
#ifndef OPENCV_TEST_REF_REDUCE_ARG_HPP
#define OPENCV_TEST_REF_REDUCE_ARG_HPP
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
#include <algorithm>
#include <numeric>
namespace cvtest {
template <class Cmp, typename T>
struct reduceMinMaxImpl
{
void operator()(const cv::Mat& src, cv::Mat& dst, const int axis) const
{
Cmp cmp;
std::vector<int> sizes(src.dims);
std::copy(src.size.p, src.size.p + src.dims, sizes.begin());
std::vector<cv::Range> idx(sizes.size(), cv::Range(0, 1));
idx[axis] = cv::Range::all();
const int n = std::accumulate(begin(sizes), end(sizes), 1, std::multiplies<int>());
const std::vector<int> newShape{1, src.size[axis]};
for (int i = 0; i < n ; ++i)
{
cv::Mat sub = src(idx);
auto begin = sub.begin<T>();
auto it = std::min_element(begin, sub.end<T>(), cmp);
*dst(idx).ptr<int32_t>() = static_cast<int32_t>(std::distance(begin, it));
for (int j = static_cast<int>(idx.size()) - 1; j >= 0; --j)
{
if (j == axis)
{
continue;
}
const int old_s = idx[j].start;
const int new_s = (old_s + 1) % sizes[j];
if (new_s > old_s)
{
idx[j] = cv::Range(new_s, new_s + 1);
break;
}
idx[j] = cv::Range(0, 1);
}
}
}
};
template<template<class> class Cmp>
struct MinMaxReducer{
template <typename T>
using Impl = reduceMinMaxImpl<Cmp<T>, T>;
static void reduce(const Mat& src, Mat& dst, int axis)
{
axis = (axis + src.dims) % src.dims;
CV_Assert(src.channels() == 1 && axis >= 0 && axis < src.dims);
std::vector<int> sizes(src.dims);
std::copy(src.size.p, src.size.p + src.dims, sizes.begin());
sizes[axis] = 1;
dst.create(sizes, CV_32SC1); // indices
dst.setTo(cv::Scalar::all(0));
cv::detail::depthDispatch<Impl>(src.depth(), src, dst, axis);
}
};
}
#endif //OPENCV_TEST_REF_REDUCE_ARG_HPP
+70
View File
@@ -2,6 +2,7 @@
// 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.
#include "test_precomp.hpp"
#include "ref_reduce_arg.impl.hpp"
namespace opencv_test { namespace {
@@ -1387,6 +1388,74 @@ struct MinMaxLocOp : public BaseElemWiseOp
}
};
struct reduceArgMinMaxOp : public BaseElemWiseOp
{
reduceArgMinMaxOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA, 1, 1, Scalar::all(0)),
isLast(false), isMax(false), axis(0)
{
context = ARITHM_MAX_NDIMS*2 + 2;
};
int getRandomType(RNG& rng) override
{
return cvtest::randomType(rng, _OutputArray::DEPTH_MASK_ALL_BUT_8S, 1, 1);
}
void getRandomSize(RNG& rng, vector<int>& size) override
{
cvtest::randomSize(rng, 2, ARITHM_MAX_NDIMS, 6, size);
}
void generateScalars(int depth, RNG& rng) override
{
BaseElemWiseOp::generateScalars(depth, rng);
isLast = (randInt(rng) % 2 == 0);
isMax = (randInt(rng) % 2 == 0);
axis = randInt(rng);
}
int getAxis(const Mat& src) const
{
int dims = src.dims;
return static_cast<int>(axis % (2 * dims)) - dims; // [-dims; dims - 1]
}
void op(const vector<Mat>& src, Mat& dst, const Mat&) override
{
const Mat& inp = src[0];
const int axis_ = getAxis(inp);
if (isMax)
{
cv::reduceArgMax(inp, dst, axis_, isLast);
}
else
{
cv::reduceArgMin(inp, dst, axis_, isLast);
}
}
void refop(const vector<Mat>& src, Mat& dst, const Mat&) override
{
const Mat& inp = src[0];
const int axis_ = getAxis(inp);
if (!isLast && !isMax)
{
cvtest::MinMaxReducer<std::less>::reduce(inp, dst, axis_);
}
else if (!isLast && isMax)
{
cvtest::MinMaxReducer<std::greater>::reduce(inp, dst, axis_);
}
else if (isLast && !isMax)
{
cvtest::MinMaxReducer<std::less_equal>::reduce(inp, dst, axis_);
}
else
{
cvtest::MinMaxReducer<std::greater_equal>::reduce(inp, dst, axis_);
}
}
bool isLast;
bool isMax;
uint32_t axis;
};
typedef Ptr<BaseElemWiseOp> ElemWiseOpPtr;
class ElemWiseTest : public ::testing::TestWithParam<ElemWiseOpPtr> {};
@@ -1492,6 +1561,7 @@ INSTANTIATE_TEST_CASE_P(Core_MeanStdDev, ElemWiseTest, ::testing::Values(ElemWis
INSTANTIATE_TEST_CASE_P(Core_Sum, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new SumOp)));
INSTANTIATE_TEST_CASE_P(Core_Norm, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new NormOp)));
INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new MinMaxLocOp)));
INSTANTIATE_TEST_CASE_P(Core_reduceArgMinMax, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new reduceArgMinMaxOp)));
INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new CartToPolarToCartOp)));
+25 -21
View File
@@ -33,7 +33,7 @@ static void cvTsReleaseSimpleSeq( CvTsSimpleSeq** seq )
static schar* cvTsSimpleSeqElem( CvTsSimpleSeq* seq, int index )
{
assert( 0 <= index && index < seq->count );
CV_Assert( 0 <= index && index < seq->count );
return seq->array + index * seq->elem_size;
}
@@ -50,7 +50,11 @@ static void cvTsSimpleSeqShiftAndCopy( CvTsSimpleSeq* seq, int from_idx, int to_
if( from_idx == to_idx )
return;
assert( (from_idx > to_idx && !elem) || (from_idx < to_idx && elem) );
if (elem)
CV_Assert(from_idx < to_idx);
else
CV_Assert(from_idx > to_idx);
if( from_idx < seq->count )
{
@@ -128,7 +132,7 @@ static void cvTsReleaseSimpleSet( CvTsSimpleSet** set_header )
static schar* cvTsSimpleSetFind( CvTsSimpleSet* set_header, int index )
{
int idx = index * set_header->elem_size;
assert( 0 <= index && index < set_header->max_count );
CV_Assert( 0 <= index && index < set_header->max_count );
return set_header->array[idx] ? set_header->array + idx + 1 : 0;
}
@@ -136,11 +140,11 @@ static schar* cvTsSimpleSetFind( CvTsSimpleSet* set_header, int index )
static int cvTsSimpleSetAdd( CvTsSimpleSet* set_header, void* elem )
{
int idx, idx2;
assert( set_header->free_count > 0 );
CV_Assert( set_header->free_count > 0 );
idx = set_header->free_stack[--set_header->free_count];
idx2 = idx * set_header->elem_size;
assert( set_header->array[idx2] == 0 );
CV_Assert( set_header->array[idx2] == 0 );
set_header->array[idx2] = 1;
if( set_header->elem_size > 1 )
memcpy( set_header->array + idx2 + 1, elem, set_header->elem_size - 1 );
@@ -152,9 +156,9 @@ static int cvTsSimpleSetAdd( CvTsSimpleSet* set_header, void* elem )
static void cvTsSimpleSetRemove( CvTsSimpleSet* set_header, int index )
{
assert( set_header->free_count < set_header->max_count &&
0 <= index && index < set_header->max_count );
assert( set_header->array[index * set_header->elem_size] == 1 );
CV_Assert( set_header->free_count < set_header->max_count &&
0 <= index && index < set_header->max_count );
CV_Assert( set_header->array[index * set_header->elem_size] == 1 );
set_header->free_stack[set_header->free_count++] = index;
set_header->array[index * set_header->elem_size] = 0;
@@ -187,7 +191,7 @@ static CvTsSimpleGraph* cvTsCreateSimpleGraph( int max_vtx_count, int vtx_size,
{
CvTsSimpleGraph* graph;
assert( max_vtx_count > 1 && vtx_size >= 0 && edge_size >= 0 );
CV_Assert( max_vtx_count > 1 && vtx_size >= 0 && edge_size >= 0 );
graph = (CvTsSimpleGraph*)cvAlloc( sizeof(*graph) +
max_vtx_count * max_vtx_count * (edge_size + 1));
graph->vtx = cvTsCreateSimpleSet( max_vtx_count, vtx_size );
@@ -235,13 +239,13 @@ static void cvTsSimpleGraphAddEdge( CvTsSimpleGraph* graph, int idx1, int idx2,
{
int i, t, n = graph->oriented ? 1 : 2;
assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
cvTsSimpleSetFind( graph->vtx, idx2 ));
CV_Assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
cvTsSimpleSetFind( graph->vtx, idx2 ));
for( i = 0; i < n; i++ )
{
int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size;
assert( graph->matrix[ofs] == 0 );
CV_Assert( graph->matrix[ofs] == 0 );
graph->matrix[ofs] = 1;
if( graph->edge_size > 1 )
memcpy( graph->matrix + ofs + 1, edge, graph->edge_size - 1 );
@@ -255,13 +259,13 @@ static void cvTsSimpleGraphRemoveEdge( CvTsSimpleGraph* graph, int idx1, int id
{
int i, t, n = graph->oriented ? 1 : 2;
assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
CV_Assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
cvTsSimpleSetFind( graph->vtx, idx2 ));
for( i = 0; i < n; i++ )
{
int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size;
assert( graph->matrix[ofs] == 1 );
CV_Assert( graph->matrix[ofs] == 1 );
graph->matrix[ofs] = 0;
CV_SWAP( idx1, idx2, t );
}
@@ -291,7 +295,7 @@ static int cvTsSimpleGraphVertexDegree( CvTsSimpleGraph* graph, int index )
int i, count = 0;
int edge_size = graph->edge_size;
int max_vtx_count = graph->vtx->max_count;
assert( cvTsSimpleGraphFindVertex( graph, index ) != 0 );
CV_Assert( cvTsSimpleGraphFindVertex( graph, index ) != 0 );
for( i = 0; i < max_vtx_count; i++ )
{
@@ -301,7 +305,7 @@ static int cvTsSimpleGraphVertexDegree( CvTsSimpleGraph* graph, int index )
if( !graph->oriented )
{
assert( count % 2 == 0 );
CV_Assert( count % 2 == 0 );
count /= 2;
}
return count;
@@ -609,7 +613,7 @@ int Core_SeqBaseTest::test_get_seq_elem( int _struct_idx, int iters )
CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[_struct_idx];
struct_idx = _struct_idx;
assert( seq->total == sseq->count );
CV_Assert( seq->total == sseq->count );
if( sseq->count == 0 )
return 0;
@@ -656,7 +660,7 @@ int Core_SeqBaseTest::test_get_seq_reading( int _struct_idx, int iters )
vector<schar> _elem(sseq->elem_size);
schar* elem = &_elem[0];
assert( total == sseq->count );
CV_Assert( total == sseq->count );
this->struct_idx = _struct_idx;
int pos = cvtest::randInt(rng) % 2;
@@ -964,7 +968,7 @@ int Core_SeqBaseTest::test_seq_ops( int iters )
"The sequence doesn't become empty after clear" );
break;
default:
assert(0);
CV_Assert(0);
return -1;
}
@@ -1903,7 +1907,7 @@ int Core_GraphScanTest::create_random_graph( int _struct_idx )
for( i = 0; i < vtx_count; i++ )
cvGraphAddVtx( graph );
assert( graph->active_count == vtx_count );
CV_Assert( graph->active_count == vtx_count );
for( i = 0; i < edge_count; i++ )
{
@@ -1914,7 +1918,7 @@ int Core_GraphScanTest::create_random_graph( int _struct_idx )
cvGraphAddEdge( graph, j, k );
}
assert( graph->active_count == vtx_count && graph->edges->active_count <= edge_count );
CV_Assert( graph->active_count == vtx_count && graph->edges->active_count <= edge_count );
return 0;
}
+1 -1
View File
@@ -204,7 +204,7 @@ static void DCT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat(
}
}
else
assert(0);
CV_Assert(0);
}
+17
View File
@@ -373,6 +373,23 @@ template<typename R> struct TheTest
EXPECT_EQ((LaneType)12, vx_setall_res2_[i]);
}
#if CV_SIMD_WIDTH == 16
{
uint64 a = CV_BIG_INT(0x7fffffffffffffff);
uint64 b = (uint64)CV_BIG_INT(0xcfffffffffffffff);
v_uint64x2 uint64_vec(a, b);
EXPECT_EQ(a, uint64_vec.get0());
EXPECT_EQ(b, v_extract_n<1>(uint64_vec));
}
{
int64 a = CV_BIG_INT(0x7fffffffffffffff);
int64 b = CV_BIG_INT(-1);
v_int64x2 int64_vec(a, b);
EXPECT_EQ(a, int64_vec.get0());
EXPECT_EQ(b, v_extract_n<1>(int64_vec));
}
#endif
return *this;
}
+3 -3
View File
@@ -28,7 +28,7 @@ protected:
template<class Type>
void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
{
assert( src.channels() == 1 );
CV_Assert( src.channels() == 1 );
if( dim == 0 ) // row
{
sum.create( 1, src.cols, CV_64FC1 );
@@ -138,7 +138,7 @@ int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat
eps = 0.6;
}
assert( opRes.type() == CV_64FC1 );
CV_Assert( opRes.type() == CV_64FC1 );
Mat _dst, dst, diff;
cv::reduce( src, _dst, dim, opType, dstType );
_dst.convertTo( dst, CV_64FC1 );
@@ -192,7 +192,7 @@ int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
else if( srcType == CV_64FC1 )
testReduce<double>( src, sum, avg, max, min, dim );
else
assert( 0 );
CV_Assert( 0 );
// 1. sum
tempCode = checkOp( src, dstType, CV_REDUCE_SUM, sum, dim );
+7 -7
View File
@@ -1044,7 +1044,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
}
else
{
assert( mat_depth == CV_64F );
CV_Assert( mat_depth == CV_64F );
for( i = 0; i < transmat->rows; i++ )
for( j = 0; j < cols; j++ )
mat[i*cols + j] = ((double*)(transmat->data.ptr + transmat->step*i))[j];
@@ -1070,7 +1070,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
buf[j] = ((double*)src)[j];
break;
default:
assert(0);
CV_Assert(0);
}
switch( cn )
@@ -1100,7 +1100,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
}
break;
default:
assert(0);
CV_Assert(0);
}
switch( depth )
@@ -1114,7 +1114,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
((double*)dst)[j] = buf[j];
break;
default:
assert(0);
CV_Assert(0);
}
}
}
@@ -1463,8 +1463,8 @@ static double cvTsLU( CvMat* a, CvMat* b=NULL, CvMat* x=NULL, int* rank=0 )
double *a0 = a->data.db, *b0 = b ? b->data.db : 0;
double *x0 = x ? x->data.db : 0;
double t, det = 1.;
assert( CV_MAT_TYPE(a->type) == CV_64FC1 &&
(!b || CV_ARE_TYPES_EQ(a,b)) && (!x || CV_ARE_TYPES_EQ(a,x)));
CV_Assert( CV_MAT_TYPE(a->type) == CV_64FC1 &&
(!b || CV_ARE_TYPES_EQ(a,b)) && (!x || CV_ARE_TYPES_EQ(a,x)));
for( i = 0; i < Nm; i++ )
{
@@ -1519,7 +1519,7 @@ static double cvTsLU( CvMat* a, CvMat* b=NULL, CvMat* x=NULL, int* rank=0 )
if( x )
{
assert( b );
CV_Assert( b );
for( i = N-1; i >= 0; i-- )
{
+32
View File
@@ -821,4 +821,36 @@ TEST(Core_Types, trivially_copyable_extra)
}
#endif
template <typename T> class Rect_Test : public testing::Test {};
TYPED_TEST_CASE_P(Rect_Test);
// Reimplement C++11 std::numeric_limits<>::lowest.
template<typename T> T cv_numeric_limits_lowest();
template<> int cv_numeric_limits_lowest<int>() { return INT_MIN; }
template<> float cv_numeric_limits_lowest<float>() { return -FLT_MAX; }
template<> double cv_numeric_limits_lowest<double>() { return -DBL_MAX; }
TYPED_TEST_P(Rect_Test, Overflows) {
typedef Rect_<TypeParam> R;
TypeParam num_max = std::numeric_limits<TypeParam>::max();
TypeParam num_lowest = cv_numeric_limits_lowest<TypeParam>();
EXPECT_EQ(R(0, 0, 10, 10), R(0, 0, 10, 10) & R(0, 0, 10, 10));
EXPECT_EQ(R(5, 6, 4, 3), R(0, 0, 10, 10) & R(5, 6, 4, 3));
EXPECT_EQ(R(5, 6, 3, 2), R(0, 0, 8, 8) & R(5, 6, 4, 3));
// Test with overflowing dimenions.
EXPECT_EQ(R(5, 0, 5, 10), R(0, 0, 10, 10) & R(5, 0, num_max, num_max));
// Test with overflowing dimensions for floats/doubles.
EXPECT_EQ(R(num_max, 0, num_max / 4, 10), R(num_max, 0, num_max / 2, 10) & R(num_max, 0, num_max / 4, 10));
// Test with overflowing coordinates.
EXPECT_EQ(R(), R(20, 0, 10, 10) & R(num_lowest, 0, 10, 10));
EXPECT_EQ(R(), R(20, 0, 10, 10) & R(0, num_lowest, 10, 10));
EXPECT_EQ(R(), R(num_lowest, 0, 10, 10) & R(0, num_lowest, 10, 10));
}
REGISTER_TYPED_TEST_CASE_P(Rect_Test, Overflows);
typedef ::testing::Types<int, float, double> RectTypes;
INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Rect_Test, RectTypes);
}} // namespace