From b6b5a10a8e4754378136f44eae72f5e49187f24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=9F=B3=E3=81=82=E3=82=81?= Date: Mon, 3 Mar 2025 21:13:40 +0800 Subject: [PATCH] Merge pull request #26946 from amane-ame:minmax_fix_hal_rvv Fix HAL dispatch in cv::minMaxIdx #26946 Closes https://github.com/opencv/opencv/pull/26939#issuecomment-2669617834. Closes https://github.com/opencv/opencv/issues/26947 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- 3rdparty/hal_rvv/hal_rvv_1p0/minmax.hpp | 18 ++++++++++++++---- modules/core/src/minmax.dispatch.cpp | 11 ++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/3rdparty/hal_rvv/hal_rvv_1p0/minmax.hpp b/3rdparty/hal_rvv/hal_rvv_1p0/minmax.hpp index dbaa4706db..e741ccbc66 100644 --- a/3rdparty/hal_rvv/hal_rvv_1p0/minmax.hpp +++ b/3rdparty/hal_rvv/hal_rvv_1p0/minmax.hpp @@ -10,10 +10,8 @@ namespace cv { namespace cv_hal_rvv { #undef cv_hal_minMaxIdx #define cv_hal_minMaxIdx cv::cv_hal_rvv::minMaxIdx - -// 1d support issue https://github.com/opencv/opencv/issues/26947 -//#undef cv_hal_minMaxIdxMaskStep -//#define cv_hal_minMaxIdxMaskStep cv::cv_hal_rvv::minMaxIdx +#undef cv_hal_minMaxIdxMaskStep +#define cv_hal_minMaxIdxMaskStep cv::cv_hal_rvv::minMaxIdx namespace { @@ -122,6 +120,8 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, found_min = true; minIdx[0] = i; minIdx[1] = j + index; + if (src_step == sizeof(T) && width > 1) + std::swap(minIdx[0], minIdx[1]); } } if (!found_max) @@ -133,6 +133,8 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, found_max = true; maxIdx[0] = i; maxIdx[1] = j + index; + if (src_step == sizeof(T) && width > 1) + std::swap(maxIdx[0], maxIdx[1]); } } } @@ -178,6 +180,8 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, found_min = true; minIdx[0] = i; minIdx[1] = j + index; + if (src_step == sizeof(T) && width > 1) + std::swap(minIdx[0], minIdx[1]); } } if (!found_max) @@ -189,6 +193,8 @@ inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, found_max = true; maxIdx[0] = i; maxIdx[1] = j + index; + if (src_step == sizeof(T) && width > 1) + std::swap(maxIdx[0], maxIdx[1]); } } } @@ -277,6 +283,8 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width, { minIdx[0] = __riscv_vmv_x(vec_minpos) / width; minIdx[1] = __riscv_vmv_x(vec_minpos) % width; + if (src_step == sizeof(T) && width > 1) + std::swap(minIdx[0], minIdx[1]); } } if (val_max < rvv::vmv_x_s(vec_max)) @@ -286,6 +294,8 @@ inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width, { maxIdx[0] = __riscv_vmv_x(vec_maxpos) / width; maxIdx[1] = __riscv_vmv_x(vec_maxpos) % width; + if (src_step == sizeof(T) && width > 1) + std::swap(maxIdx[0], maxIdx[1]); } } vec_min = __riscv_vslidedown(vec_min, 1, vlmax); diff --git a/modules/core/src/minmax.dispatch.cpp b/modules/core/src/minmax.dispatch.cpp index a79eadb543..dd335454cd 100644 --- a/modules/core/src/minmax.dispatch.cpp +++ b/modules/core/src/minmax.dispatch.cpp @@ -314,18 +314,15 @@ void cv::minMaxIdx(InputArray _src, double* minVal, if (src.dims <= 2) { - if ((size_t)src.step == (size_t)mask.step) + if ((size_t)src.step == (size_t)mask.step || mask.empty()) { CALL_HAL(minMaxIdx, cv_hal_minMaxIdx, src.data, src.step, src.cols*cn, src.rows, src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data); } - else - { - CALL_HAL(minMaxIdxMaskStep, cv_hal_minMaxIdxMaskStep, src.data, src.step, src.cols*cn, src.rows, - src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data, mask.step); - } + CALL_HAL(minMaxIdxMaskStep, cv_hal_minMaxIdxMaskStep, src.data, src.step, src.cols*cn, src.rows, + src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data, mask.step); } - else if (src.isContinuous() && mask.isContinuous()) + else if (src.isContinuous() && (mask.isContinuous() || mask.empty())) { int res = cv_hal_minMaxIdx(src.data, 0, (int)src.total()*cn, 1, src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data);