diff --git a/modules/features2d/include/opencv2/features2d/hal/interface.h b/modules/features2d/include/opencv2/features2d/hal/interface.h new file mode 100644 index 0000000000..bcc6577c19 --- /dev/null +++ b/modules/features2d/include/opencv2/features2d/hal/interface.h @@ -0,0 +1,33 @@ +#ifndef OPENCV_FEATURE2D_HAL_INTERFACE_H +#define OPENCV_FEATURE2D_HAL_INTERFACE_H + +#include "opencv2/core/cvdef.h" +//! @addtogroup featrure2d_hal_interface +//! @{ + +//! @name Fast feature detector types +//! @sa cv::FastFeatureDetector +//! @{ +#define CV_HAL_TYPE_5_8 0 +#define CV_HAL_TYPE_7_12 1 +#define CV_HAL_TYPE_9_16 2 +//! @} + +//! @name Key point +//! @sa cv::KeyPoint +//! @{ +struct CV_EXPORTS cvhalKeyPoint +{ + float x; + float y; + float size; + float angle; + float response; + int octave; + int class_id; +}; +//! @} + +//! @} + +#endif diff --git a/modules/features2d/src/fast.cpp b/modules/features2d/src/fast.cpp index f81e7e2c2c..1e8c72778f 100644 --- a/modules/features2d/src/fast.cpp +++ b/modules/features2d/src/fast.cpp @@ -45,6 +45,7 @@ The references are: #include "fast.hpp" #include "fast_score.hpp" #include "opencl_kernels_features2d.hpp" +#include "hal_replacement.hpp" #include "opencv2/core/hal/intrin.hpp" #include "opencv2/core/openvx/ovx_defs.hpp" @@ -414,6 +415,62 @@ static bool openvx_FAST(InputArray _img, std::vector& keypoints, #endif +static inline int hal_FAST(cv::Mat& src, std::vector& keypoints, int threshold, bool nonmax_suppression, int type) +{ + if (threshold > 20) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + cv::Mat scores(src.size(), src.type()); + + int error = cv_hal_FAST_dense(src.data, src.step, scores.data, scores.step, src.cols, src.rows, type); + + if (error != CV_HAL_ERROR_OK) + return error; + + cv::Mat suppressedScores(src.size(), src.type()); + + if (nonmax_suppression) + { + error = cv_hal_FAST_NMS(scores.data, scores.step, suppressedScores.data, suppressedScores.step, scores.cols, scores.rows); + + if (error != CV_HAL_ERROR_OK) + return error; + } + else + { + suppressedScores = scores; + } + + if (!threshold && nonmax_suppression) threshold = 1; + + cv::KeyPoint kpt(0, 0, 7.f, -1, 0); + + uint32_t uthreshold = (uint32_t) threshold; + + int ofs = 3; + + int stride = (int)suppressedScores.step; + const uint8_t* pscore = suppressedScores.data; + + keypoints.clear(); + + for (int y = ofs; y + ofs < suppressedScores.rows; ++y) + { + kpt.pt.y = (float)(y); + for (int x = ofs; x + ofs < suppressedScores.cols; ++x) + { + uint32_t score = pscore[y * stride + x]; + if (score > uthreshold) + { + kpt.pt.x = (float)(x); + kpt.response = (nonmax_suppression != 0) ? (float)((int32_t)score - 1) : 0.f; + keypoints.push_back(kpt); + } + } + } + + return CV_HAL_ERROR_OK; +} void FAST(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression, int type) { @@ -422,6 +479,13 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool CV_OCL_RUN(_img.isUMat() && type == FastFeatureDetector::TYPE_9_16, ocl_FAST(_img, keypoints, threshold, nonmax_suppression, 10000)); + cv::Mat img = _img.getMat(); + CALL_HAL(fast_dense, hal_FAST, img, keypoints, threshold, nonmax_suppression, type); + + size_t keypoints_count; + CALL_HAL(fast, cv_hal_FAST, img.data, img.step, img.cols, img.rows, + (uchar*)(keypoints.data()), &keypoints_count, threshold, nonmax_suppression, type); + CV_OVX_RUN(true, openvx_FAST(_img, keypoints, threshold, nonmax_suppression, type)) diff --git a/modules/features2d/src/hal_replacement.hpp b/modules/features2d/src/hal_replacement.hpp new file mode 100644 index 0000000000..7780aa4a24 --- /dev/null +++ b/modules/features2d/src/hal_replacement.hpp @@ -0,0 +1,135 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2017, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_FEATURES2D_HAL_REPLACEMENT_HPP +#define OPENCV_FEATURES2D_HAL_REPLACEMENT_HPP + +#include "opencv2/core/hal/interface.h" + +#if defined __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-parameter" +#elif defined _MSC_VER +# pragma warning( push ) +# pragma warning( disable: 4100 ) +#endif + +//! @addtogroup features2d_hal_interface +//! @note Define your functions to override default implementations: +//! @code +//! #undef hal_add8u +//! #define hal_add8u my_add8u +//! @endcode +//! @{ +/** + @brief Detects corners using the FAST algorithm, returns mask. + @param src_data,src_step Source image + @param dst_data,dst_step Destination mask + @param width,height Source image dimensions + @param type FAST type +*/ +inline int hal_ni_FAST_dense(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int type) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_FAST_dense hal_ni_FAST_dense +//! @endcond + +/** + @brief Non-maximum suppression for FAST_9_16. + @param src_data,src_step Source mask + @param dst_data,dst_step Destination mask after NMS + @param width,height Source mask dimensions +*/ +inline int hal_ni_FAST_NMS(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_FAST_NMS hal_ni_FAST_NMS +//! @endcond + +/** + @brief Detects corners using the FAST algorithm. + @param src_data,src_step Source image + @param width,height Source image dimensions + @param keypoints_data Pointer to keypoints + @param keypoints_count Count of keypoints + @param threshold Threshold for keypoint + @param nonmax_suppression Indicates if make nonmaxima suppression or not. + @param type FAST type +*/ +inline int hal_ni_FAST(const uchar* src_data, size_t src_step, int width, int height, uchar* keypoints_data, size_t* keypoints_count, int threshold, bool nonmax_suppression, int type) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_FAST hal_ni_FAST +//! @endcond + +//! @} + + +#if defined __GNUC__ +# pragma GCC diagnostic pop +#elif defined _MSC_VER +# pragma warning( pop ) +#endif + +#include "custom_hal.hpp" + +//! @cond IGNORED +#define CALL_HAL_RET(name, fun, retval, ...) \ + int res = __CV_EXPAND(fun(__VA_ARGS__, &retval)); \ + if (res == CV_HAL_ERROR_OK) \ + return retval; \ + else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \ + CV_Error_(cv::Error::StsInternal, \ + ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); + + +#define CALL_HAL(name, fun, ...) \ +{ \ + int res = __CV_EXPAND(fun(__VA_ARGS__)); \ + if (res == CV_HAL_ERROR_OK) \ + return; \ + else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \ + CV_Error_(cv::Error::StsInternal, \ + ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); \ +} +//! @endcond + +#endif