From d037b40faab71d90be2bfccf44bf06a20b8d3df8 Mon Sep 17 00:00:00 2001 From: quic-apreetam Date: Thu, 19 Dec 2024 16:01:26 +0530 Subject: [PATCH] Merge pull request #26621 from CodeLinaro:apreetam_2ndPost FastCV-based HAL for OpenCV acceleration 2ndpost-3 #26621 ### Detailed description: - Add cv_hal_canny for Canny API Requires binary from [opencv/opencv_3rdparty#90](https://github.com/opencv/opencv_3rdparty/pull/90) Depends on: [opencv/opencv#26617](https://github.com/opencv/opencv/pull/26617) Depends on: [opencv/opencv#26619](https://github.com/opencv/opencv/pull/26619) ### 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 --- .../fastcv/include/fastcv_hal_imgproc.hpp | 30 ++++++++++ 3rdparty/fastcv/src/fastcv_hal_imgproc.cpp | 55 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/3rdparty/fastcv/include/fastcv_hal_imgproc.hpp b/3rdparty/fastcv/include/fastcv_hal_imgproc.hpp index 8b9a2ca4da..c9360f95ed 100644 --- a/3rdparty/fastcv/include/fastcv_hal_imgproc.hpp +++ b/3rdparty/fastcv/include/fastcv_hal_imgproc.hpp @@ -26,6 +26,8 @@ #define cv_hal_cvtBGRtoHSV fastcv_hal_cvtBGRtoHSV #undef cv_hal_cvtBGRtoYUVApprox #define cv_hal_cvtBGRtoYUVApprox fastcv_hal_cvtBGRtoYUVApprox +#undef cv_hal_canny +#define cv_hal_canny fastcv_hal_canny //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Calculate medianBlur filter /// @param src_data Source image data @@ -235,4 +237,32 @@ int fastcv_hal_cvtBGRtoYUVApprox( int scn, bool swapBlue, bool isCbCr); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// @brief Canny edge detector +/// @param src_data Source image data +/// @param src_step Source image step +/// @param dst_data Destination image data +/// @param dst_step Destination image step +/// @param width Source image width +/// @param height Source image height +/// @param cn Number of channels +/// @param lowThreshold low hresholds value +/// @param highThreshold high thresholds value +/// @param ksize Kernel size for Sobel operator. +/// @param L2gradient Flag, indicating use of L2 or L1 norma. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int fastcv_hal_canny( + const uchar* src_data, + size_t src_step, + uchar* dst_data, + size_t dst_step, + int width, + int height, + int cn, + double lowThreshold, + double highThreshold, + int ksize, + bool L2gradient); + #endif diff --git a/3rdparty/fastcv/src/fastcv_hal_imgproc.cpp b/3rdparty/fastcv/src/fastcv_hal_imgproc.cpp index 58872d8f57..d1e972b672 100644 --- a/3rdparty/fastcv/src/fastcv_hal_imgproc.cpp +++ b/3rdparty/fastcv/src/fastcv_hal_imgproc.cpp @@ -992,4 +992,59 @@ int fastcv_hal_cvtBGRtoYUVApprox( fcvStatus status = FASTCV_SUCCESS; CV_HAL_RETURN(status, hal_BGRtoYUVApprox); +} + +int fastcv_hal_canny( + const uchar* src_data, + size_t src_step, + uchar* dst_data, + size_t dst_step, + int width, + int height, + int cn, + double lowThreshold, + double highThreshold, + int ksize, + bool L2gradient) +{ + int numThreads = cv::getNumThreads(); + + if(numThreads!=1) + CV_HAL_RETURN_NOT_IMPLEMENTED("API performs optimally in single-threaded mode"); + + if (cn != 1) + CV_HAL_RETURN_NOT_IMPLEMENTED("Multi-channel input is not supported"); + + if (lowThreshold > highThreshold) + CV_HAL_RETURN_NOT_IMPLEMENTED("lowThreshold is greater then highThreshold"); + + const double epsilon = 1e-9; + + if (std::abs(lowThreshold - std::round(lowThreshold)) > epsilon || std::abs(highThreshold - std::round(highThreshold)) > epsilon) + CV_HAL_RETURN_NOT_IMPLEMENTED("threshold with decimal values not supported"); + + INITIALIZATION_CHECK; + + fcvStatus status; + fcvNormType norm; + + if (L2gradient == 1) + norm = fcvNormType::FASTCV_NORM_L2; + else + norm = fcvNormType::FASTCV_NORM_L1; + + if ((ksize == 3) && (width > 2) && (height > 2) && (src_step >= (size_t)width) && (dst_step >= (size_t)width)) + { + int16_t* gx = (int16_t*)fcvMemAlloc(width * height * sizeof(int16_t), 16); + int16_t* gy = (int16_t*)fcvMemAlloc(width * height * sizeof(int16_t), 16); + uint32_t gstride = 2 * width; + status = fcvFilterCannyu8(src_data, width, height, src_step, ksize, static_cast(std::round(lowThreshold)), static_cast(std::round(highThreshold)), norm, dst_data, dst_step, gx, gy, gstride); + fcvMemFree(gx); + fcvMemFree(gy); + } + else + { + CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("Ksize:%d is not supported", ksize)); + } + CV_HAL_RETURN(status, hal_canny); } \ No newline at end of file