diff --git a/adapters/opencv/opencv-5.x.patch b/adapters/opencv/opencv-5.x.patch index 1fe914954c03cc19f2feb16f17fe95dd4b151ab2..ec3a3aebf29ede6df457fd8174e37f918c5abcb9 100644 --- a/adapters/opencv/opencv-5.x.patch +++ b/adapters/opencv/opencv-5.x.patch @@ -1,200 +1,121 @@ -// SPDX-FileCopyrightText: 2023 - 2025 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: 2024-2025 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: Copyright (C) 2000-2022, Intel Corporation, all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2015-2023, OpenCV Foundation, all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2008-2016, Itseez Inc., all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2019-2023, Xperience AI, all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2019-2022, Shenzhen Institute of Artificial Intelligence and Robotics for Society, all rights reserved. +// SPDX-FileCopyrightText: Copyright (C) 2022-2023, Southern University of Science And Technology, all rights reserved. +// SPDX-FileCopyrightText: Third party copyrights are property of their respective owners. // // SPDX-License-Identifier: Apache-2.0 -diff --git a/3rdparty/kleidicv/CMakeLists.txt b/3rdparty/kleidicv/CMakeLists.txt -new file mode 100644 -index 0000000000..5105214af3 ---- /dev/null -+++ b/3rdparty/kleidicv/CMakeLists.txt -@@ -0,0 +1,3 @@ -+set(KLEIDICV_SOURCE_PATH "${CMAKE_SOURCE_DIR}/kleidicv" CACHE PATH "Directory containing KleidiCV sources") -+ -+include("${KLEIDICV_SOURCE_PATH}/adapters/opencv/CMakeLists.txt") -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 56767f2ec7..5ade43b063 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -259,6 +259,8 @@ OCV_OPTION(WITH_CAP_IOS "Enable iOS video capture" ON - VERIFY HAVE_CAP_IOS) - OCV_OPTION(WITH_CAROTENE "Use NVidia carotene acceleration library for ARM platform" (NOT CV_DISABLE_OPTIMIZATION) - VISIBLE_IF (ARM OR AARCH64) AND NOT IOS AND NOT XROS) -+OCV_OPTION(WITH_KLEIDICV "Use KleidiCV library for ARM platforms" OFF -+ VISIBLE_IF (AARCH64)) - OCV_OPTION(WITH_CPUFEATURES "Use cpufeatures Android library" ON - VISIBLE_IF ANDROID - VERIFY HAVE_CPUFEATURES) -@@ -949,6 +951,13 @@ if(NOT DEFINED OpenCV_HAL) - set(OpenCV_HAL "OpenCV_HAL") - endif() - -+if(WITH_KLEIDICV) -+ ocv_debug_message(STATUS "Enable KleidiCV acceleration") -+ if(NOT ";${OpenCV_HAL};" MATCHES ";kleidicv;") -+ set(OpenCV_HAL "kleidicv;${OpenCV_HAL}") -+ endif() -+endif() -+ - if(WITH_CAROTENE) - ocv_debug_message(STATUS "Enable carotene acceleration") - if(NOT ";${OpenCV_HAL};" MATCHES ";carotene;") -@@ -973,6 +982,10 @@ foreach(hal ${OpenCV_HAL}) - else() - message(STATUS "Carotene: NEON is not available, disabling carotene...") - endif() -+ elseif(hal STREQUAL "kleidicv") -+ add_subdirectory(3rdparty/kleidicv) -+ ocv_hal_register(KLEIDICV_HAL_LIBRARIES KLEIDICV_HAL_HEADERS KLEIDICV_HAL_INCLUDE_DIRS) -+ list(APPEND OpenCV_USED_HAL "KleidiCV (ver ${KLEIDICV_HAL_VERSION})") - else() - ocv_debug_message(STATUS "OpenCV HAL: ${hal} ...") - ocv_clear_vars(OpenCV_HAL_LIBRARIES OpenCV_HAL_HEADERS OpenCV_HAL_INCLUDE_DIRS) -diff --git a/doc/tutorials/introduction/config_reference/config_reference.markdown b/doc/tutorials/introduction/config_reference/config_reference.markdown -index 3c61ae1c9a..f44e7d8dc2 100644 ---- a/doc/tutorials/introduction/config_reference/config_reference.markdown -+++ b/doc/tutorials/introduction/config_reference/config_reference.markdown -@@ -621,6 +621,7 @@ Following build options are utilized in `opencv_contrib` modules, as stated [pre - `CMAKE_TOOLCHAIN_FILE` - - `WITH_CAROTENE` -+`WITH_KLEIDICV` - `WITH_CPUFEATURES` - `WITH_EIGEN` - `WITH_DIRECTX` -diff --git a/modules/core/include/opencv2/core/hal/interface.h b/modules/core/include/opencv2/core/hal/interface.h -index c7445a4de4..49a459597b 100644 ---- a/modules/core/include/opencv2/core/hal/interface.h -+++ b/modules/core/include/opencv2/core/hal/interface.h -@@ -90,6 +90,8 @@ typedef short cv_hal_bf16; - - #define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) - #define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) -+#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) -+#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) - #define CV_IS_INT_TYPE(flags) (((1 << CV_MAT_DEPTH(flags)) & 0x1e1f) != 0) - #define CV_IS_FLOAT_TYPE(flags) (((1 << CV_MAT_DEPTH(flags)) & 0x1e0) != 0) - diff --git a/modules/core/src/convert.dispatch.cpp b/modules/core/src/convert.dispatch.cpp -index 4a8432fb0e..82cecf90c0 100644 +index c18fc2faef..34ef53dc57 100644 --- a/modules/core/src/convert.dispatch.cpp +++ b/modules/core/src/convert.dispatch.cpp -@@ -195,6 +195,11 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const - dst.create( dims, size, dtype, -1, allowTransposed ); - Mat dstMat = dst.getMat(); - -+ if( dims <= 2 ) { -+ int width_in_elements = src.cols * cn; -+ CALL_HAL(convertTo, cv_hal_convertTo, src.data, src.step, src.depth(), dstMat.data, dstMat.step, dstMat.depth(), width_in_elements, src.rows, alpha, beta); +@@ -176,6 +176,15 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const + CALL_HAL(convertScale, cv_hal_convertScale, src.data, 0, dstMat.data, 0, (int)src.total() * cn, 1, sdepth, ddepth, alpha, beta); + } + ++ if( dims <= 2 ) ++ { ++ CALL_HAL(convertScale, cv_hal_convertScale, src.data, src.step, dstMat.data, dstMat.step, src.cols * cn, src.rows, sdepth, ddepth, alpha, beta); + } -+ ++ else if( src.isContinuous() && dstMat.isContinuous() ) ++ { ++ CALL_HAL(convertScale, cv_hal_convertScale, src.data, 0, dstMat.data, 0, (int)src.total() * cn, 1, sdepth, ddepth, alpha, beta); ++ } ++ BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); double scale[] = {alpha, beta}; CV_Assert( func != 0 ); diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp -index dc65a25684..5be57f0923 100644 +index 0c9254a872..65ccbbf683 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp -@@ -968,6 +968,21 @@ inline int hal_ni_transpose2d(const uchar* src_data, size_t src_step, uchar* dst - #define cv_hal_transpose2d hal_ni_transpose2d +@@ -1223,6 +1223,40 @@ 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 ++ +/** -+ @brief convertTo ++ @brief inRange + @param src_data,src_step,src_depth Source image + @param dst_data,dst_step,dst_depth Destination image + @param width,height Source image dimensions -+ @param scale,shift Dst values = src_value * scale + shift ++ @param cn number of channels ++ @param lower_bound,upper_bound Dst values = (lower_bound <= src_value) && (src_value <= upper_bound) ? 255 : 0 +*/ -+inline int hal_ni_convertTo(const uchar *src_data, size_t src_step, int src_depth, ++inline int hal_ni_inRange8u(const uchar *src_data, size_t src_step, + uchar *dst_data, size_t dst_step, int dst_depth, int width, -+ int height, double scale, double shift) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } ++ int height, int cn, uchar lower_bound, uchar upper_bound) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } ++inline int hal_ni_inRange32f(const uchar *src_data, size_t src_step, ++ uchar *dst_data, size_t dst_step, int dst_depth, int width, ++ int height, int cn, double lower_bound, double upper_bound) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED -+#define cv_hal_convertTo hal_ni_convertTo ++#define cv_hal_inRange8u hal_ni_inRange8u ++#define cv_hal_inRange32f hal_ni_inRange32f +//! @endcond + //! @} - - -diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp -index 5c6497bd80..43e89d5b9c 100644 ---- a/modules/imgproc/src/hal_replacement.hpp -+++ b/modules/imgproc/src/hal_replacement.hpp -@@ -880,6 +880,12 @@ inline int hal_ni_gaussianBlur(const uchar* src_data, size_t src_step, uchar* ds - #define cv_hal_gaussianBlur hal_ni_gaussianBlur - //! @endcond - -+inline int hal_ni_gaussianBlurBinomial(const uchar*, size_t, uchar*, size_t, int, int, int, int, size_t, size_t, size_t, size_t, size_t, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } -+ -+//! @cond IGNORED -+#define cv_hal_gaussianBlurBinomial hal_ni_gaussianBlurBinomial -+//! @endcond + + +diff --git a/modules/core/src/sum.dispatch.cpp b/modules/core/src/sum.dispatch.cpp +index e56e10117f..3a612935a5 100644 +--- a/modules/core/src/sum.dispatch.cpp ++++ b/modules/core/src/sum.dispatch.cpp +@@ -199,6 +199,10 @@ Scalar sum(InputArray _src) + CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_sum(src, _res), _res); + + int k, cn = src.channels(), depth = src.depth(); + - /** - @brief Computes Sobel derivatives - @param src_depth Depth of source image -diff --git a/modules/imgproc/src/smooth.dispatch.cpp b/modules/imgproc/src/smooth.dispatch.cpp -index 3e23187de2..45737b1ee3 100644 ---- a/modules/imgproc/src/smooth.dispatch.cpp -+++ b/modules/imgproc/src/smooth.dispatch.cpp -@@ -570,6 +570,20 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, - ocl_GaussianBlur_8UC1(_src, _dst, ksize, CV_MAT_DEPTH(type), kx, ky, borderType) - ); - -+ if (sigma1 == 0.0 && sigma2 == 0.0 && ksize.height == ksize.width) -+ { -+ Mat src = _src.getMat(); -+ Mat dst = _dst.getMat(); -+ -+ Point ofs; -+ Size wsz(src.cols, src.rows); -+ if(!(borderType & BORDER_ISOLATED)) -+ src.locateROI( wsz, ofs ); -+ -+ CALL_HAL(gaussianBlurBinomial, cv_hal_gaussianBlurBinomial, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, cn, -+ ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, borderType&~BORDER_ISOLATED); -+ } ++ double result = 0; ++ CALL_HAL_RET(sum, cv_hal_sum, result, src.data, src.step, src.type(), src.cols, src.rows); + - if(sdepth == CV_8U && ((borderType & BORDER_ISOLATED) || !_src.isSubmatrix())) - { - std::vector fkx, fky; - -diff --git a/modules/imgproc/test/test_imgwarp_strict.cpp b/modules/imgproc/test/test_imgwarp_strict.cpp -index 83a5e23781..75df962fb7 100644 ---- a/modules/imgproc/test/test_imgwarp_strict.cpp -+++ b/modules/imgproc/test/test_imgwarp_strict.cpp -@@ -239,7 +239,7 @@ float CV_ImageWarpBaseTest::get_success_error_level(int _interpolation, int) con - else if (_interpolation == INTER_AREA) - return 2.0f; - else -- return 1.0f; -+ return 4.0f; // Reference algorithm uses integer interpolation with 5 bits fractional part, and this greater tolerance allows better precision algorithms to pass the test - } -diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp -index aded7bb74e..adf6a67e2b 100644 ---- a/modules/imgproc/test/test_imgwarp.cpp -+++ b/modules/imgproc/test/test_imgwarp.cpp -@@ -811,7 +811,11 @@ TEST_P(Imgproc_RemapRelative, validity) - cv::remap(src, dstRelative, mapRelativeX32F, mapRelativeY32F, interpolation | WARP_RELATIVE_MAP, borderType); + SumFunc func = getSumFunc(depth); + if (func == nullptr) { + if (depth == CV_Bool && cn == 1) +diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp +index 35fe093c2b..5529d8ee77 100644 +--- a/modules/imgproc/src/imgwarp.cpp ++++ b/modules/imgproc/src/imgwarp.cpp +@@ -1832,6 +1832,11 @@ void cv::convertMaps( InputArray _map1, InputArray _map2, + std::swap( m1, m2 ); + std::swap( m1type, m2type ); } - -- EXPECT_EQ(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 0); -+ if (interpolation != INTER_LINEAR) { -+ EXPECT_EQ(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 0); -+ } else { -+ EXPECT_LT(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 4); // Reference algorithm uses integer interpolation with 5 bits fractional part, and this greater tolerance allows better precision algorithms to pass the test ++ if ((map1.type() == CV_16SC2) && (map2.empty() || map2.type() == CV_16UC1)) ++ { ++ CALL_HAL(remap16s, cv_hal_remap16s, src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, ++ map1.ptr(), map1.step, map2.ptr(), map2.step, interpolation, borderType, borderValue.val); + } - }; - - INSTANTIATE_TEST_CASE_P(ImgProc, Imgproc_RemapRelative, testing::Combine( + + if( dstm1type <= 0 ) + dstm1type = m1type == CV_16SC2 ? CV_32FC2 : CV_16SC2; diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp -index e8840d231b..adfaad38b0 100644 +index 01b033cbef..25a8db9088 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp -@@ -1371,7 +1371,12 @@ TEST_P(Imgproc_RemapRelative, validity) +@@ -811,7 +811,13 @@ TEST_P(Imgproc_RemapRelative, validity) cv::remap(src, dstRelative, mapRelativeX32F, mapRelativeY32F, interpolation | WARP_RELATIVE_MAP, borderType); } - + - EXPECT_EQ(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 0); + if (interpolation != INTER_LINEAR) { + EXPECT_EQ(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 0); @@ -204,5 +125,18 @@ index e8840d231b..adfaad38b0 100644 + EXPECT_LT(cvtest::norm(dstAbsolute, dstRelative, NORM_INF), 1 << (src.elemSize1() * CHAR_BIT - INTER_BITS)); + } }; - + INSTANTIATE_TEST_CASE_P(ImgProc, Imgproc_RemapRelative, testing::Combine( +diff --git a/modules/imgproc/test/test_imgwarp_strict.cpp b/modules/imgproc/test/test_imgwarp_strict.cpp +index 92c76e254f..3890cade4b 100644 +--- a/modules/imgproc/test/test_imgwarp_strict.cpp ++++ b/modules/imgproc/test/test_imgwarp_strict.cpp +@@ -239,7 +239,7 @@ float CV_ImageWarpBaseTest::get_success_error_level(int _interpolation, int) con + else if (_interpolation == INTER_AREA) + return 2.0f; + else +- return 1.0f; ++ return 4.0f; // Reference algorithm uses integer interpolation with 5 bits fractional part, and this greater tolerance allows better precision algorithms to pass the test + } + + void CV_ImageWarpBaseTest::validate_results() const