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