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

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2026-05-19 16:23:55 +03:00
160 changed files with 9385 additions and 2093 deletions
+8
View File
@@ -2995,6 +2995,14 @@ TEST(Core_Norm, NORM_L2_8UC4)
EXPECT_EQ(kNorm, cv::norm(a, b, NORM_L2));
}
TEST(Core_Norm, NORM_L2SQR_16SC4_large)
{
const int sizes[] = {1, 116, 40};
Mat src(3, sizes, CV_16SC4, Scalar::all(16384));
const double expected = static_cast<double>(src.total()) * src.channels() * 16384.0 * 16384.0;
EXPECT_EQ(expected, cv::norm(src, NORM_L2SQR));
}
TEST(Core_ConvertTo, regression_12121)
{
{
+31 -1
View File
@@ -680,13 +680,26 @@ public:
protected:
void run_func();
void prepare_to_validation( int test_case_idx );
double get_success_error_level( int test_case_idx, int i, int j );
};
CxCore_DFTTest::CxCore_DFTTest() : CxCore_DXTBaseTest( true, true, false )
{
}
double CxCore_DFTTest::get_success_error_level( int test_case_idx, int i, int j )
{
CV_Assert(i == OUTPUT);
CV_Assert(j == 0);
int depth = test_mat[i][j].depth();
// NOTE: non-default threshold intorduced for ARMPL integration
if (depth == CV_32F)
return 1.5e-4;
return CxCore_DXTBaseTest::get_success_error_level(test_case_idx, i, j);
}
void CxCore_DFTTest::run_func()
{
@@ -745,6 +758,9 @@ public:
protected:
void run_func();
void prepare_to_validation( int test_case_idx );
#if defined(HAVE_ARMPL)
double get_success_error_level( int test_case_idx, int i, int j ) CV_OVERRIDE;
#endif
};
@@ -752,6 +768,20 @@ CxCore_DCTTest::CxCore_DCTTest() : CxCore_DXTBaseTest( false, false, false )
{
}
#if defined(HAVE_ARMPL)
double CxCore_DCTTest::get_success_error_level(int, int i, int j)
{
CV_Assert(i == OUTPUT);
CV_Assert(j == 0);
int depth = test_mat[i][j].depth();
if (depth == CV_32F)
return 1.67e-5;
return 1e-12;
}
#endif
void CxCore_DCTTest::run_func()
{
+10 -10
View File
@@ -292,17 +292,17 @@ template<typename R> struct TheTest
}
// reinterpret_as
v_uint8 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);
v_int8 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);
v_uint16 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);
v_int16 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);
v_uint32 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);
v_int32 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);
v_uint64 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);
v_int64 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);
v_float32 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);
AlignedData<R> out_u8; v_uint8 vu8 = v_reinterpret_as_u8(r1); v_store((uchar*)out_u8.a.d, vu8); EXPECT_EQ(data.a, out_u8.a);
AlignedData<R> out_s8; v_int8 vs8 = v_reinterpret_as_s8(r1); v_store((schar*)out_s8.a.d, vs8); EXPECT_EQ(data.a, out_s8.a);
AlignedData<R> out_u16; v_uint16 vu16 = v_reinterpret_as_u16(r1); v_store((ushort*)out_u16.a.d, vu16); EXPECT_EQ(data.a, out_u16.a);
AlignedData<R> out_s16; v_int16 vs16 = v_reinterpret_as_s16(r1); v_store((short*)out_s16.a.d, vs16); EXPECT_EQ(data.a, out_s16.a);
AlignedData<R> out_u32; v_uint32 vu32 = v_reinterpret_as_u32(r1); v_store((unsigned*)out_u32.a.d, vu32); EXPECT_EQ(data.a, out_u32.a);
AlignedData<R> out_s32; v_int32 vs32 = v_reinterpret_as_s32(r1); v_store((int*)out_s32.a.d, vs32); EXPECT_EQ(data.a, out_s32.a);
AlignedData<R> out_u64; v_uint64 vu64 = v_reinterpret_as_u64(r1); v_store((uint64*)out_u64.a.d, vu64); EXPECT_EQ(data.a, out_u64.a);
AlignedData<R> out_s64; v_int64 vs64 = v_reinterpret_as_s64(r1); v_store((int64*)out_s64.a.d, vs64); EXPECT_EQ(data.a, out_s64.a);
AlignedData<R> out_f32; v_float32 vf32 = v_reinterpret_as_f32(r1); v_store((float*)out_f32.a.d, vf32); EXPECT_EQ(data.a, out_f32.a);
#if (CV_SIMD_64F || CV_SIMD_SCALABLE_64F)
v_float64 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);
AlignedData<R> out_f64; v_float64 vf64 = v_reinterpret_as_f64(r1); v_store((double*)out_f64.a.d, vf64); EXPECT_EQ(data.a, out_f64.a);
#endif
#if CV_SIMD_WIDTH == 16
+12 -2
View File
@@ -2218,9 +2218,19 @@ T fsWriteRead(const T& expectedValue, const char* ext)
fs_w.release();
FileStorage fs_r(fname, FileStorage::READ);
T value;
fs_r["value"] >> value;
fs_r.release();
// If ext is `.gz[0-9]`, fname on storage will end with `.gz`.
// FileStorage::Impl::open() truncates the last digit internally.
if (isdigit(fname.back()))
{
fname.pop_back();
}
remove(fname.c_str());
return value;
}
@@ -2275,7 +2285,7 @@ TEST_P(FileStorage_exact_type, long_int_mat)
}
INSTANTIATE_TEST_CASE_P(Core_InputOutput,
FileStorage_exact_type, Values(".yml", ".xml", ".json")
FileStorage_exact_type, Values(".yml", ".xml", ".json", ".xml.gz", ".xml.gz0", ".xml.gz9")
);
TEST(Core_InputOutput, YAML_Compatibility)
+12
View File
@@ -1370,6 +1370,8 @@ TEST(Core_Matx, from_initializer_list)
Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
Matx22d b = {10, 11, 12, 13};
ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
Mat_<double> c({2, 2}, {10, 11, 12, 13});
ASSERT_EQ( cvtest::norm(c, b, NORM_INF), 0.);
}
TEST(Core_Mat, regression_9507)
@@ -1825,6 +1827,11 @@ TEST(Mat, from_initializer_list)
auto D = Mat_<double>({2, 3}, {1, 2, 3, 4, 5, 6});
EXPECT_EQ(2, D.rows);
EXPECT_EQ(3, D.cols);
double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
Mat R({2, 2}, {a, -b, b, a});
ASSERT_EQ(CV_64FC1, R.type());
ASSERT_EQ(cv::Size(2, 2), R.size());
}
TEST(Mat_, from_initializer_list)
@@ -1837,6 +1844,11 @@ TEST(Mat_, from_initializer_list)
ASSERT_DOUBLE_EQ(cvtest::norm(A, B, NORM_INF), 0.);
ASSERT_DOUBLE_EQ(cvtest::norm(A, C, NORM_INF), 0.);
ASSERT_DOUBLE_EQ(cvtest::norm(B, C, NORM_INF), 0.);
double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
Mat_<double> R({2, 2}, {a, -b, b, a});
ASSERT_EQ(CV_64FC1, R.type());
ASSERT_EQ(cv::Size(2, 2), R.size());
}
+172
View File
@@ -3617,5 +3617,177 @@ TEST(Core_BFloat, convert)
#endif
}
////////////////////////////////////////////////////////////////////////////
// See https://github.com/opencv/opencv/issues/28930
typedef testing::TestWithParam<std::tuple<int,int,int,int, int>> Core_Point_DotProduct_regression28930;
TEST_P(Core_Point_DotProduct_regression28930, basic)
{
const int x1 = std::get<0>(GetParam());
const int y1 = std::get<1>(GetParam());
const int x2 = std::get<2>(GetParam());
const int y2 = std::get<3>(GetParam());
const int expect = std::get<4>(GetParam());
cv::Point pt1(x1, y1);
cv::Point pt2(x2, y2);
EXPECT_EQ(pt1.dot(pt2), expect) << "Failed for: (" << x1 << "," << y1 << ") dot (" << x2 << "," << y2 << ")";
}
INSTANTIATE_TEST_CASE_P(/* */, Core_Point_DotProduct_regression28930,
testing::Values(
// 1. INT_MIN*INT_MIN + INT_MIN*INT_MIN = 2^62 + 2^62 => Saturates to MAX
std::make_tuple( INT_MIN, INT_MIN,
INT_MIN, INT_MIN,
INT_MAX),
// 2. INT_MIN*INT_MAX + INT_MAX*INT_MAX = 4611686014132420609 + -4611686016279904256 = -2147483647
std::make_tuple( INT_MAX, INT_MIN,
INT_MAX, INT_MAX,
-2147483647),
// 3. INT_MAX*INT_MAX + INT_MAX*INT_MIN = 4611686014132420609 + -4611686016279904256 = -2147483647
std::make_tuple( INT_MAX, INT_MAX,
INT_MAX, INT_MIN,
-2147483647),
// 4. 46340^2 = 2147395600 (Under INT_MAX)
std::make_tuple( 46340, 0,
46340, 0,
2147395600),
// 5. 46341^2 = 2147488281 (Over INT_MAX) => Saturates to MAX
std::make_tuple( 46341, 0,
46341, 0,
INT_MAX),
// 6. -46340 * 46340 = -2147395600 (Over INT_MIN)
std::make_tuple( -46340, 0,
46340, 0,
-2147395600),
// 7. -46341 * 46341 = -2147488281 (Under INT_MIN) => Saturates to MIN
std::make_tuple( -46341, 0,
46341, 0,
INT_MIN),
// 8. Zero
std::make_tuple( 0, 0,
0, 0,
0),
// 9. Simple max
std::make_tuple( INT_MAX, 0,
1, 0,
INT_MAX)
));
typedef testing::TestWithParam<std::tuple<int,int,int,int,int,int, int>> Core_Point3i_DotProduct_regression28930;
TEST_P(Core_Point3i_DotProduct_regression28930, basic)
{
const int x1 = std::get<0>(GetParam());
const int y1 = std::get<1>(GetParam());
const int z1 = std::get<2>(GetParam());
const int x2 = std::get<3>(GetParam());
const int y2 = std::get<4>(GetParam());
const int z2 = std::get<5>(GetParam());
const int expect = std::get<6>(GetParam());
cv::Point3i pt1(x1, y1, z1);
cv::Point3i pt2(x2, y2, z2);
EXPECT_EQ(pt1.dot(pt2), expect) << "Failed for: (" << x1 << "," << y1 << "," << z1 << ") dot (" << x2 << "," << y2 << "," << z2 << ")";
}
INSTANTIATE_TEST_CASE_P(/* */, Core_Point3i_DotProduct_regression28930,
testing::Values(
// 1. INT_MIN*INT_MIN + INT_MIN*INT_MIN = 2^62 + 2^62 => Saturates to MAX
std::make_tuple( INT_MIN, INT_MIN, 0,
INT_MIN, INT_MIN, 0,
INT_MAX),
// 2. INT_MIN*INT_MAX + INT_MAX*INT_MAX = 4611686014132420609 + -4611686016279904256 = -2147483647
std::make_tuple( INT_MAX, INT_MIN, 0,
INT_MAX, INT_MAX, 0,
-2147483647),
// 3. INT_MAX*INT_MAX + INT_MAX*INT_MIN = 4611686014132420609 + -4611686016279904256 = -2147483647
std::make_tuple( INT_MAX, INT_MAX, 0,
INT_MAX, INT_MIN, 0,
-2147483647),
// 4. 46340^2 = 2147395600 (Under INT_MAX)
std::make_tuple( 46340, 0, 0,
46340, 0, 0,
2147395600),
// 5. 46341^2 = 2147488281 (Over INT_MAX) => Saturates to MAX
std::make_tuple( 46341, 0, 0,
46341, 0, 0,
INT_MAX),
// 6. -46340 * 46340 = -2147395600 (Over INT_MIN)
std::make_tuple( -46340, 0, 0,
46340, 0, 0,
-2147395600),
// 7. -46341 * 46341 = -2147488281 (Under INT_MIN) => Saturates to MIN
std::make_tuple( -46341, 0, 0,
46341, 0, 0,
INT_MIN),
// 8. Zero
std::make_tuple( 0, 0, 0,
0, 0, 0,
0),
// 9. Simple max
std::make_tuple( INT_MAX, 0, 0,
1, 0, 0,
INT_MAX),
// 10. All positive, no overflow
std::make_tuple( 1, 2, 3,
4, 5, 6,
(1*4 + 2*5 + 3*6)),
// 11. All negative, no overflow
std::make_tuple( -1, -2, -3,
-4, -5, -6,
(-1*-4 + -2*-5 + -3*-6)),
// 12. Three large positive products => saturate to MAX
std::make_tuple( INT_MAX, INT_MAX, INT_MAX,
INT_MAX, INT_MAX, INT_MAX,
INT_MAX),
// 13. Three large positive products from INT_MIN*INT_MIN => saturate to MAX
std::make_tuple( INT_MIN, INT_MIN, INT_MIN,
INT_MIN, INT_MIN, INT_MIN,
INT_MAX),
// 14. Three large negative products => saturate to MIN
std::make_tuple( INT_MIN, INT_MIN, INT_MIN,
INT_MAX, INT_MAX, INT_MAX,
INT_MIN),
// 15. Mixed signs: + + -
std::make_tuple( INT_MAX, INT_MAX, INT_MIN,
INT_MAX, INT_MAX, INT_MAX,
INT_MAX),
// 16. Mixed signs: + - +
std::make_tuple( INT_MAX, INT_MIN, INT_MAX,
INT_MAX, INT_MAX, INT_MAX,
INT_MAX),
// 17. Mixed signs: - + -
std::make_tuple( INT_MIN, INT_MAX, INT_MIN,
INT_MAX, INT_MAX, INT_MAX,
INT_MIN)
));
}} // namespace
/* End of file. */