From 8218b6435fa49fd07dccff85071ac8d2bcee428a Mon Sep 17 00:00:00 2001 From: Mark Horvath Date: Fri, 16 May 2025 13:24:24 +0000 Subject: [PATCH 1/2] Fix types in the checks of the conformity tests The template argument of are_matrices_different should match with the element type of the input matrices. --- conformity/opencv/test_min_max.cpp | 6 +++--- conformity/opencv/test_scharr.cpp | 4 ++-- conformity/opencv/test_sobel.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/conformity/opencv/test_min_max.cpp b/conformity/opencv/test_min_max.cpp index d84adc0c0..a176c7473 100644 --- a/conformity/opencv/test_min_max.cpp +++ b/conformity/opencv/test_min_max.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: 2024 - 2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 @@ -49,7 +49,7 @@ bool test_min_max(int index, RecreatedMessageQueue& request_queue, cv::Mat actual = exec_min_max(input); cv::Mat expected = get_expected_from_subordinate(index, request_queue, reply_queue, input); - if (are_matrices_different(0, actual, expected)) { + if (are_matrices_different(0, actual, expected)) { fail_print_matrices(x, y, input, actual, expected); return true; } @@ -64,7 +64,7 @@ bool test_min_max(int index, RecreatedMessageQueue& request_queue, cv::Mat actual = exec_min_max(input); cv::Mat expected = get_expected_from_subordinate(index, request_queue, reply_queue, input); - if (are_matrices_different(0, actual, expected)) { + if (are_matrices_different(0, actual, expected)) { std::cout << "[FAIL]\n"; std::cout << "=== Input Matrix:\n"; for (int i = 0; i < z; ++i) { diff --git a/conformity/opencv/test_scharr.cpp b/conformity/opencv/test_scharr.cpp index 9f2630718..fcdd3ce03 100644 --- a/conformity/opencv/test_scharr.cpp +++ b/conformity/opencv/test_scharr.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: 2024 - 2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 @@ -27,7 +27,7 @@ bool test_scharr_interleaved(int index, RecreatedMessageQueue& request_queue, cv::Mat expected = get_expected_from_subordinate(index, request_queue, reply_queue, input); - if (are_matrices_different(0, actual, expected)) { + if (are_matrices_different(0, actual, expected)) { fail_print_matrices(x, y, input, actual, expected); return true; } diff --git a/conformity/opencv/test_sobel.cpp b/conformity/opencv/test_sobel.cpp index 807af0c8a..5cedab2bb 100644 --- a/conformity/opencv/test_sobel.cpp +++ b/conformity/opencv/test_sobel.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: 2024 - 2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 @@ -32,7 +32,7 @@ bool test_sobel(int index, RecreatedMessageQueue& request_queue, cv::Mat expected = get_expected_from_subordinate(index, request_queue, reply_queue, input); - if (are_matrices_different(0, actual, expected)) { + if (are_matrices_different(0, actual, expected)) { fail_print_matrices(x, y, input, actual, expected); return true; } -- GitLab From 769e99f0b2fd32bff0e6def738053118923c20bd Mon Sep 17 00:00:00 2001 From: Mark Horvath Date: Fri, 16 May 2025 14:36:07 +0000 Subject: [PATCH 2/2] Update the OpenCV HAL for remap16s Align the implementation to the current head of OpenCV's 4.x branch. --- adapters/opencv/kleidicv_hal.cpp | 100 ++++++++++++++---------------- adapters/opencv/kleidicv_hal.h | 38 +++--------- adapters/opencv/opencv-4.11.patch | 88 +++++++++----------------- 3 files changed, 83 insertions(+), 143 deletions(-) diff --git a/adapters/opencv/kleidicv_hal.cpp b/adapters/opencv/kleidicv_hal.cpp index a46b89d10..6b32e3108 100644 --- a/adapters/opencv/kleidicv_hal.cpp +++ b/adapters/opencv/kleidicv_hal.cpp @@ -1340,9 +1340,9 @@ int inRange_f32(const uchar *src_data, size_t src_step, uchar *dst_data, int remap_s16(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, - int dst_width, int dst_height, const int16_t *mapxy, - size_t mapxy_step, int border_type, - const double border_value_f64[4]) { + int dst_width, int dst_height, int16_t *mapx, size_t mapx_step, + uint16_t *mapy, size_t mapy_step, int interpolation, + int border_type, const double border_value_f64[4]) { kleidicv_border_type_t kleidicv_border_type; if (from_opencv(border_type, kleidicv_border_type)) { return CV_HAL_ERROR_NOT_IMPLEMENTED; @@ -1350,60 +1350,52 @@ int remap_s16(int src_type, const uchar *src_data, size_t src_step, auto mt = get_multithreading(); - if (src_type == CV_8UC1) { - auto border_value = get_border_value(border_value_f64); - return convert_error(kleidicv_thread_remap_s16_u8( - reinterpret_cast(src_data), src_step, - static_cast(src_width), static_cast(src_height), - reinterpret_cast(dst_data), dst_step, - static_cast(dst_width), static_cast(dst_height), - CV_MAT_CN(src_type), mapxy, mapxy_step, kleidicv_border_type, - border_value.data(), mt)); - } else if (src_type == CV_16UC1) { - auto border_value = get_border_value(border_value_f64); - return convert_error(kleidicv_thread_remap_s16_u16( - reinterpret_cast(src_data), src_step, - static_cast(src_width), static_cast(src_height), - reinterpret_cast(dst_data), dst_step, - static_cast(dst_width), static_cast(dst_height), - CV_MAT_CN(src_type), mapxy, mapxy_step, kleidicv_border_type, - border_value.data(), mt)); - } - - return CV_HAL_ERROR_NOT_IMPLEMENTED; -} + // OpenCV provides mapx and mapy inputs, while mapx is interleaved x and y + // coordinates, and mapy is interleaved fractional parts, if present. + // KleidiCV has different naming for the same inputs. -int remap_s16point5(int src_type, const uchar *src_data, size_t src_step, - int src_width, int src_height, uchar *dst_data, - size_t dst_step, int dst_width, int dst_height, - const int16_t *mapxy, size_t mapxy_step, - const uint16_t *mapfrac, size_t mapfrac_step, - int border_type, const double border_value_f64[4]) { - kleidicv_border_type_t kleidicv_border_type; - if (from_opencv(border_type, kleidicv_border_type)) { - return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (interpolation == CV_HAL_INTER_NEAREST) { + if (src_type == CV_8UC1) { + auto border_value = get_border_value(border_value_f64); + return convert_error(kleidicv_thread_remap_s16_u8( + reinterpret_cast(src_data), src_step, + static_cast(src_width), static_cast(src_height), + reinterpret_cast(dst_data), dst_step, + static_cast(dst_width), static_cast(dst_height), + CV_MAT_CN(src_type), mapx, mapx_step, kleidicv_border_type, + border_value.data(), mt)); + } else if (src_type == CV_16UC1) { + auto border_value = get_border_value(border_value_f64); + return convert_error(kleidicv_thread_remap_s16_u16( + reinterpret_cast(src_data), src_step, + static_cast(src_width), static_cast(src_height), + reinterpret_cast(dst_data), dst_step, + static_cast(dst_width), static_cast(dst_height), + CV_MAT_CN(src_type), mapx, mapx_step, kleidicv_border_type, + border_value.data(), mt)); + } } - auto mt = get_multithreading(); - - if (CV_MAT_DEPTH(src_type) == CV_8U) { - auto border_value = get_border_value(border_value_f64); - return convert_error(kleidicv_thread_remap_s16point5_u8( - reinterpret_cast(src_data), src_step, - static_cast(src_width), static_cast(src_height), - reinterpret_cast(dst_data), dst_step, - static_cast(dst_width), static_cast(dst_height), - CV_MAT_CN(src_type), mapxy, mapxy_step, mapfrac, mapfrac_step, - kleidicv_border_type, border_value.data(), mt)); - } else if (CV_MAT_DEPTH(src_type) == CV_16U) { - auto border_value = get_border_value(border_value_f64); - return convert_error(kleidicv_thread_remap_s16point5_u16( - reinterpret_cast(src_data), src_step, - static_cast(src_width), static_cast(src_height), - reinterpret_cast(dst_data), dst_step, - static_cast(dst_width), static_cast(dst_height), - CV_MAT_CN(src_type), mapxy, mapxy_step, mapfrac, mapfrac_step, - kleidicv_border_type, border_value.data(), mt)); + if (interpolation == CV_HAL_INTER_LINEAR) { + if (CV_MAT_DEPTH(src_type) == CV_8U) { + auto border_value = get_border_value(border_value_f64); + return convert_error(kleidicv_thread_remap_s16point5_u8( + reinterpret_cast(src_data), src_step, + static_cast(src_width), static_cast(src_height), + reinterpret_cast(dst_data), dst_step, + static_cast(dst_width), static_cast(dst_height), + CV_MAT_CN(src_type), mapx, mapx_step, mapy, mapy_step, + kleidicv_border_type, border_value.data(), mt)); + } else if (CV_MAT_DEPTH(src_type) == CV_16U) { + auto border_value = get_border_value(border_value_f64); + return convert_error(kleidicv_thread_remap_s16point5_u16( + reinterpret_cast(src_data), src_step, + static_cast(src_width), static_cast(src_height), + reinterpret_cast(dst_data), dst_step, + static_cast(dst_width), static_cast(dst_height), + CV_MAT_CN(src_type), mapx, mapx_step, mapy, mapy_step, + kleidicv_border_type, border_value.data(), mt)); + } } return CV_HAL_ERROR_NOT_IMPLEMENTED; diff --git a/adapters/opencv/kleidicv_hal.h b/adapters/opencv/kleidicv_hal.h index d83013ce9..dee7e9367 100644 --- a/adapters/opencv/kleidicv_hal.h +++ b/adapters/opencv/kleidicv_hal.h @@ -152,15 +152,9 @@ int inRange_f32(const uchar *src_data, size_t src_step, uchar *dst_data, int remap_s16(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, - int dst_width, int dst_height, const int16_t *mapxy, - size_t mapxy_step, int border_type, const double border_value[4]); - -int remap_s16point5(int src_type, const uchar *src_data, size_t src_step, - int src_width, int src_height, uchar *dst_data, - size_t dst_step, int dst_width, int dst_height, - const int16_t *mapxy, size_t mapxy_step, - const uint16_t *mapfrac, size_t mapfrac_step, - int border_type, const double border_value[4]); + int dst_width, int dst_height, int16_t *mapx, size_t mapx_step, + uint16_t *mapy, size_t mapy_step, int interpolation, + int border_type, const double border_value_f64[4]); int remap_f32(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, @@ -408,36 +402,18 @@ static inline int kleidicv_canny_with_fallback( static inline int kleidicv_remap_s16_with_fallback( int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width, - int dst_height, const int16_t *mapxy, size_t mapxy_step, int border_type, + int dst_height, int16_t *mapx, size_t mapx_step, uint16_t *mapy, + size_t mapy_step, int interpolation, int border_type, const double border_value[4]) { return KLEIDICV_HAL_FALLBACK_FORWARD( remap_s16, cv_hal_remap16s, src_type, src_data, src_step, src_width, - src_height, dst_data, dst_step, dst_width, dst_height, mapxy, mapxy_step, - border_type, border_value); + src_height, dst_data, dst_step, dst_width, dst_height, mapx, mapx_step, + mapy, mapy_step, interpolation, border_type, border_value); } #undef cv_hal_remap16s #define cv_hal_remap16s kleidicv_remap_s16_with_fallback #endif // cv_hal_remap16s -// This condition can be removed if this HAL macro is defined in all supported -// versions -#ifdef cv_hal_remap16s16u -static inline int kleidicv_remap_s16point5_with_fallback( - int src_type, const uchar *src_data, size_t src_step, int src_width, - int src_height, uchar *dst_data, size_t dst_step, int dst_width, - int dst_height, const int16_t *mapxy, size_t mapxy_step, - const uint16_t *mapfrac, size_t mapfrac_step, int border_type, - const double border_value[4]) { - return KLEIDICV_HAL_FALLBACK_FORWARD( - remap_s16point5, cv_hal_remap16s16u, src_type, src_data, src_step, - src_width, src_height, dst_data, dst_step, dst_width, dst_height, mapxy, - mapxy_step, mapfrac, mapfrac_step, border_type, border_value); -} - -#undef cv_hal_remap16s16u -#define cv_hal_remap16s16u kleidicv_remap_s16point5_with_fallback -#endif // cv_hal_remap16s16u - static inline int kleidicv_remap_f32_with_fallback( int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width, diff --git a/adapters/opencv/opencv-4.11.patch b/adapters/opencv/opencv-4.11.patch index 73e77e3f6..2ea21add4 100644 --- a/adapters/opencv/opencv-4.11.patch +++ b/adapters/opencv/opencv-4.11.patch @@ -13,7 +13,7 @@ // SPDX-License-Identifier: Apache-2.0 diff --git a/modules/core/src/convert.dispatch.cpp b/modules/core/src/convert.dispatch.cpp -index 2b40352..402f2d4 100644 +index 2b4035285f..402f2d451a 100644 --- a/modules/core/src/convert.dispatch.cpp +++ b/modules/core/src/convert.dispatch.cpp @@ -281,6 +281,15 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const @@ -33,7 +33,7 @@ index 2b40352..402f2d4 100644 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 474fe17..9a43264 100644 +index 474fe17393..9a43264a4b 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -307,9 +307,29 @@ Hamming distance between two vectors @@ -106,7 +106,7 @@ index 474fe17..9a43264 100644 diff --git a/modules/core/src/sum.dispatch.cpp b/modules/core/src/sum.dispatch.cpp -index fade948..17b40ca 100644 +index fade948336..17b40ca0e8 100644 --- a/modules/core/src/sum.dispatch.cpp +++ b/modules/core/src/sum.dispatch.cpp @@ -199,6 +199,10 @@ Scalar sum(InputArray _src) @@ -121,15 +121,15 @@ index fade948..17b40ca 100644 CV_Assert( cn <= 4 && func != 0 ); diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp -index fe6019e..b2d8c8b 100644 +index fe6019e3a7..994012fbc8 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp -@@ -378,6 +378,60 @@ inline int hal_ni_remap32f(int src_type, const uchar *src_data, size_t src_step, - #define cv_hal_remap32f hal_ni_remap32f - //! @endcond - +@@ -373,9 +373,35 @@ inline int hal_ni_remap32f(int src_type, const uchar *src_data, size_t src_step, + float* mapx, size_t mapx_step, float* mapy, size_t mapy_step, + int interpolation, int border_type, const double border_value[4]) + { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +/** -+ @brief hal_remap with a short integer map ++ @brief hal_remap with fixed-point maps + @param src_type source and destination image type + @param src_data source image data + @param src_step source image step @@ -139,73 +139,45 @@ index fe6019e..b2d8c8b 100644 + @param dst_step destination image step + @param dst_width destination image width + @param dst_height destination image height -+ @param mapxy map for interleaved x and y values -+ @param mapxy_step mapxy matrix step ++ @param mapx map for x values ++ @param mapx_step mapx matrix step ++ @param mapy map for y values ++ @param mapy_step mapy matrix step ++ @param interpolation interpolation mode (CV_HAL_INTER_NEAREST, ...) + @param border_type border processing mode (CV_HAL_BORDER_REFLECT, ...) + @param border_value values to use for CV_HAL_BORDER_CONSTANT mode + @sa cv::remap + */ +inline int hal_ni_remap16s(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, + uchar *dst_data, size_t dst_step, int dst_width, int dst_height, -+ const short* mapxy, size_t mapxy_step, int border_type, const double border_value[4]) ++ short* mapx, size_t mapx_step, ushort* mapy, size_t mapy_step, ++ int interpolation, int border_type, const double border_value[4]) +{ return CV_HAL_ERROR_NOT_IMPLEMENTED; } -+ -+//! @cond IGNORED + + //! @cond IGNORED + #define cv_hal_remap32f hal_ni_remap32f +#define cv_hal_remap16s hal_ni_remap16s -+//! @endcond -+ -+/** -+ @brief hal_remap with short maps plus fractions -+ @param src_type source and destination image type -+ @param src_data source image data -+ @param src_step source image step -+ @param src_width source image width -+ @param src_height source image height -+ @param dst_data destination image data -+ @param dst_step destination image step -+ @param dst_width destination image width -+ @param dst_height destination image height -+ @param mapxy map for interleaved x and y values -+ @param mapxy_step mapxy matrix step -+ @param mapfrac map for fractional part x and y values (5+5 bits) -+ @param mapfrac_step mapfrac matrix step -+ @param border_type border processing mode (CV_HAL_BORDER_REFLECT, ...) -+ @param border_value values to use for CV_HAL_BORDER_CONSTANT mode -+ @sa cv::remap -+ */ -+inline int hal_ni_remap16s16u(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, -+ uchar *dst_data, size_t dst_step, int dst_width, int dst_height, -+ const short* mapxy, size_t mapxy_step, const unsigned short* mapfrac, size_t mapfrac_step, int border_type, const double border_value[4]) -+{ return CV_HAL_ERROR_NOT_IMPLEMENTED; } -+ -+//! @cond IGNORED -+#define cv_hal_remap16s16u hal_ni_remap16s16u -+//! @endcond -+ + //! @endcond + /** - @brief hal_cvtBGRtoBGR - @param src_data source image data diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp -index dfc718b..c1f953f 100644 +index dfc718bf87..8e293cc805 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp -@@ -1819,6 +1819,14 @@ void cv::remap( InputArray _src, OutputArray _dst, - { +@@ -1820,6 +1820,11 @@ void cv::remap( InputArray _src, OutputArray _dst, CALL_HAL(remap32f, cv_hal_remap32f, 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); -+ } else if ((map1.type() == CV_16SC2) && map2.empty() && interpolation == INTER_NEAREST) + } ++ 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, borderType, borderValue.val); -+ } else if ((map1.type() == CV_16SC2) && (map2.type() == CV_16UC1) && interpolation == INTER_LINEAR) -+ { -+ CALL_HAL(remap16s16u, cv_hal_remap16s16u, 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, borderType, borderValue.val); - } ++ map1.ptr(), map1.step, map2.ptr(), map2.step, interpolation, borderType, borderValue.val); ++ } interpolation &= ~WARP_RELATIVE_MAP; + if( interpolation == INTER_AREA ) diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp -index 4cf99b4..332bc10 100644 +index 4cf99b4704..332bc10f06 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1371,7 +1371,13 @@ TEST_P(Imgproc_RemapRelative, validity) @@ -224,7 +196,7 @@ index 4cf99b4..332bc10 100644 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 673c6f0..56d9e0b 100644 +index 673c6f03e6..56d9e0b554 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 -- GitLab