1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #29434 from Prasadayus:canny_ipp_extract

Extracting IPP integaration as HAL for Canny #29434

Backport of : https://github.com/opencv/opencv/pull/29433

**Performance Numbers on Intel(R) Core(TM) i9-11900K:** https://docs.google.com/spreadsheets/d/1RMvUZP1tSQtdjuNQY9JasYmlx1L5iN9XWGhXtG5u1uI/edit?usp=sharing 

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Prasad Ayush Kumar
2026-07-10 11:59:24 +01:00
committed by GitHub
parent 7230c1ce08
commit b022a9b321
6 changed files with 135 additions and 83 deletions
@@ -211,7 +211,6 @@ T* allocSingletonNew() { return new(allocSingletonNewBuffer(sizeof(T))) T(); }
// Temporary disabled named IPP region. Performance
#define IPP_DISABLE_PERF_COPYMAKE 1 // performance variations
#define IPP_DISABLE_PERF_TRUE_DIST_MT 1 // cv::distanceTransform OpenCV MT performance is better
#define IPP_DISABLE_PERF_CANNY_MT 1 // cv::Canny OpenCV MT performance is better
#ifdef HAVE_IPP
#include "ippversion.h"
+2 -82
View File
@@ -48,85 +48,6 @@
namespace cv
{
#ifdef HAVE_IPP
static bool ipp_Canny(const Mat& src , const Mat& dx_, const Mat& dy_, Mat& dst, float low, float high, bool L2gradient, int aperture_size)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP();
#if IPP_DISABLE_PERF_CANNY_MT
if(cv::getNumThreads()>1)
return false;
#endif
::ipp::IwiSize size(dst.cols, dst.rows);
IppDataType type = ippiGetDataType(dst.depth());
int channels = dst.channels();
IppNormType norm = (L2gradient)?ippNormL2:ippNormL1;
if(size.width <= 3 || size.height <= 3)
return false;
if(channels != 1)
return false;
if(type != ipp8u)
return false;
if(src.empty())
{
try
{
::ipp::IwiImage iwSrcDx;
::ipp::IwiImage iwSrcDy;
::ipp::IwiImage iwDst;
ippiGetImage(dx_, iwSrcDx);
ippiGetImage(dy_, iwSrcDy);
ippiGetImage(dst, iwDst);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCannyDeriv, iwSrcDx, iwSrcDy, iwDst, low, high, ::ipp::IwiFilterCannyDerivParams(norm));
}
catch (const ::ipp::IwException &)
{
return false;
}
}
else
{
IppiMaskSize kernel;
if(aperture_size == 3)
kernel = ippMskSize3x3;
else if(aperture_size == 5)
kernel = ippMskSize5x5;
else
return false;
try
{
::ipp::IwiImage iwSrc;
::ipp::IwiImage iwDst;
ippiGetImage(src, iwSrc);
ippiGetImage(dst, iwDst);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCanny, iwSrc, iwDst, low, high, ::ipp::IwiFilterCannyParams(ippFilterSobel, kernel, norm), ippBorderRepl);
}
catch (const ::ipp::IwException &)
{
return false;
}
}
return true;
#else
CV_UNUSED(src); CV_UNUSED(dx_); CV_UNUSED(dy_); CV_UNUSED(dst); CV_UNUSED(low); CV_UNUSED(high); CV_UNUSED(L2gradient); CV_UNUSED(aperture_size);
return false;
#endif
}
#endif
#ifdef HAVE_OPENCL
template <bool useCustomDeriv>
@@ -803,8 +724,6 @@ void Canny( InputArray _src, OutputArray _dst,
CALL_HAL(canny, cv_hal_canny, src.data, src.step, dst.data, dst.step, src.cols, src.rows, src.channels(),
low_thresh, high_thresh, aperture_size, L2gradient);
CV_IPP_RUN_FAST(ipp_Canny(src, Mat(), Mat(), dst, (float)low_thresh, (float)high_thresh, L2gradient, aperture_size))
if (L2gradient)
{
low_thresh = std::min(32767.0, low_thresh);
@@ -879,7 +798,8 @@ void Canny( InputArray _dx, InputArray _dy, OutputArray _dst,
Mat dx = _dx.getMat();
Mat dy = _dy.getMat();
CV_IPP_RUN_FAST(ipp_Canny(Mat(), dx, dy, dst, (float)low_thresh, (float)high_thresh, L2gradient, 0))
CALL_HAL(canny_deriv, cv_hal_canny_deriv, dx.ptr<short>(), dx.step, dy.ptr<short>(), dy.step,
dst.data, dst.step, dx.cols, dx.rows, dx.channels(), low_thresh, high_thresh, L2gradient);
if (L2gradient)
{
+21
View File
@@ -1520,6 +1520,27 @@ inline int hal_ni_canny(const uchar* src_data, size_t src_step, uchar* dst_data,
#define cv_hal_canny hal_ni_canny
//! @endcond
/**
@brief Canny edge detector from image derivatives
@param dx_data Source image x-derivative data
@param dx_step Source image x-derivative step
@param dy_data Source image y-derivative data
@param dy_step Source image y-derivative 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 L2gradient Flag, indicating use L2 or L1 norma.
*/
inline int hal_ni_canny_deriv(const short* dx_data, size_t dx_step, const short* dy_data, size_t dy_step, uchar* dst_data, size_t dst_step, int width, int height, int cn, double lowThreshold, double highThreshold, bool L2gradient) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_canny_deriv hal_ni_canny_deriv
//! @endcond
/**
@brief Calculates all of the moments up to the third order of a polygon or rasterized shape for image
@param src_data Source image data