From d0978cea3909dce1eb4e72aa069e8a8d745c04e5 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 25 Apr 2024 16:42:48 +0300 Subject: [PATCH] Added moments interface to HAL. --- modules/imgproc/src/hal_replacement.hpp | 32 ++++++++++++++++++++++ modules/imgproc/src/moments.cpp | 35 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp index 8882106c82..ca25fbb47d 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp @@ -1028,6 +1028,38 @@ 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 Calculates all of the moments up to the third order of a polygon or rasterized shape for image + @param src_data Source image data + @param src_step Source image step + @param src_type source pints type + @param width Source image width + @param height Source image height + @param binary If it is true, all non-zero image pixels are treated as 1's + @param m Output array of moments (10 values) in the following order: + m00, m10, m01, m20, m11, m02, m30, m21, m12, m03. + @sa moments +*/ +inline int hal_ni_imageMoments(const uchar* src_data, size_t src_step, int src_type, int width, int height, bool binary, double m[10]) +{ return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief Calculates all of the moments up to the third order of a polygon of 2d points + @param src_data Source points (Point 2x32f or 2x32s) + @param src_size Source points count + @param src_type source pints type + @param m Output array of moments (10 values) in the following order: + m00, m10, m01, m20, m11, m02, m30, m21, m12, m03. + @sa moments +*/ +inline int hal_ni_polygonMoments(const uchar* src_data, size_t src_size, int src_type, double m[10]) +{ return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_imageMoments hal_ni_imageMoments +#define cv_hal_polygonMoments hal_ni_polygonMoments +//! @endcond + //! @} #if defined(__clang__) diff --git a/modules/imgproc/src/moments.cpp b/modules/imgproc/src/moments.cpp index b2320258b1..e89137053c 100644 --- a/modules/imgproc/src/moments.cpp +++ b/modules/imgproc/src/moments.cpp @@ -561,6 +561,37 @@ static bool ipp_moments(Mat &src, Moments &m ) } +namespace cv { namespace hal { + +static int moments(const cv::Mat& src, bool binary, cv::Moments& m) +{ + CV_INSTRUMENT_REGION(); + + double m_data[10]; + int status = 0; + int type = src.type(); + int depth = CV_MAT_DEPTH(type); + + if( src.checkVector(2) >= 0 && (depth == CV_32F || depth == CV_32S)) + status = hal_ni_polygonMoments(src.data, src.total()/2, src.type(), m_data); + else + status = hal_ni_imageMoments(src.data, src.step, src.type(), src.cols, src.rows, binary, m_data); + + if (status == CV_HAL_ERROR_OK) + { + m = cv::Moments(m_data[0], m_data[1], m_data[2], m_data[3], m_data[4], + m_data[5], m_data[6], m_data[7], m_data[8], m_data[9]); + } + else if (status != CV_HAL_ERROR_NOT_IMPLEMENTED) + { + CV_Error_(cv::Error::StsInternal, + ("HAL implementation moments ==> " CVAUX_STR(cv_hal_imageMoments) " returned %d (0x%08x)", status, status)); + } + + return status; +} +}} + cv::Moments cv::moments( InputArray _src, bool binary ) { CV_INSTRUMENT_REGION(); @@ -580,6 +611,10 @@ cv::Moments cv::moments( InputArray _src, bool binary ) #endif Mat mat = _src.getMat(); + + if (hal::moments(mat, binary, m) == CV_HAL_ERROR_OK) + return m; + if( mat.checkVector(2) >= 0 && (depth == CV_32F || depth == CV_32S)) return contourMoments(mat);