mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #26907 from asmorkalov:as/openvx_hal_features2d
Migrate remaning OpenVX integrations to OpenVX HAL (features2d)
This commit is contained in:
commit
36a5176a5f
1
3rdparty/openvx/hal/CMakeLists.txt
vendored
1
3rdparty/openvx/hal/CMakeLists.txt
vendored
@ -4,6 +4,7 @@ target_include_directories(openvx_hal PUBLIC
|
|||||||
${OPENCV_3P_OPENVX_DIR}/include
|
${OPENCV_3P_OPENVX_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/modules/core/include
|
${CMAKE_SOURCE_DIR}/modules/core/include
|
||||||
${CMAKE_SOURCE_DIR}/modules/imgproc/include
|
${CMAKE_SOURCE_DIR}/modules/imgproc/include
|
||||||
|
${CMAKE_SOURCE_DIR}/modules/features2d/include
|
||||||
${OPENVX_INCLUDE_DIR})
|
${OPENVX_INCLUDE_DIR})
|
||||||
target_link_libraries(openvx_hal PUBLIC ${OPENVX_LIBRARIES})
|
target_link_libraries(openvx_hal PUBLIC ${OPENVX_LIBRARIES})
|
||||||
set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
||||||
|
71
3rdparty/openvx/hal/openvx_hal.cpp
vendored
71
3rdparty/openvx/hal/openvx_hal.cpp
vendored
@ -1,5 +1,7 @@
|
|||||||
#include "openvx_hal.hpp"
|
#include "openvx_hal.hpp"
|
||||||
|
#include "opencv2/core/hal/interface.h"
|
||||||
#include "opencv2/imgproc/hal/interface.h"
|
#include "opencv2/imgproc/hal/interface.h"
|
||||||
|
#include "opencv2/features2d/hal/interface.h"
|
||||||
|
|
||||||
#define IVX_HIDE_INFO_WARNINGS
|
#define IVX_HIDE_INFO_WARNINGS
|
||||||
#include "ivx.hpp"
|
#include "ivx.hpp"
|
||||||
@ -1334,3 +1336,72 @@ int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width,
|
|||||||
|
|
||||||
return CV_HAL_ERROR_OK;
|
return CV_HAL_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> inline bool skipSmallImages<VX_KERNEL_FAST_CORNERS>(int w, int h) { return w*h < 800 * 600; }
|
||||||
|
|
||||||
|
int ovx_hal_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 /*cv::FastFeatureDetector::DetectorType*/ dtype)
|
||||||
|
{
|
||||||
|
// Nonmax suppression is done differently in OpenCV than in OpenVX
|
||||||
|
// 9/16 is the only supported mode in OpenVX
|
||||||
|
if(nonmax_suppression || dtype != CV_HAL_TYPE_9_16)
|
||||||
|
{
|
||||||
|
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipSmallImages<VX_KERNEL_FAST_CORNERS>(width, height))
|
||||||
|
{
|
||||||
|
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ivx::Context context = getOpenVXHALContext();
|
||||||
|
ivx::Image img = ivx::Image::createFromHandle(context, VX_DF_IMAGE_U8,
|
||||||
|
ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step),
|
||||||
|
const_cast<uchar*>(src_data));
|
||||||
|
|
||||||
|
ivx::Scalar vxthreshold = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, threshold);
|
||||||
|
vx_size capacity = width * height;
|
||||||
|
ivx::Array corners = ivx::Array::create(context, VX_TYPE_KEYPOINT, capacity);
|
||||||
|
|
||||||
|
ivx::Scalar numCorners = ivx::Scalar::create<VX_TYPE_SIZE>(context, 0);
|
||||||
|
|
||||||
|
ivx::IVX_CHECK_STATUS(vxuFastCorners(context, img, vxthreshold, (vx_bool)nonmax_suppression, corners, numCorners));
|
||||||
|
|
||||||
|
size_t nPoints = numCorners.getValue<vx_size>();
|
||||||
|
std::vector<vx_keypoint_t> vxCorners(nPoints);
|
||||||
|
corners.copyTo(vxCorners);
|
||||||
|
cvhalKeyPoint* keypoints = (cvhalKeyPoint*)keypoints_data;
|
||||||
|
for(size_t i = 0; i < std::min(nPoints, *keypoints_count); i++)
|
||||||
|
{
|
||||||
|
//if nonmaxSuppression is false, vxCorners[i].strength is undefined
|
||||||
|
keypoints[i].x = vxCorners[i].x;
|
||||||
|
keypoints[i].y = vxCorners[i].y;
|
||||||
|
keypoints[i].size = 7;
|
||||||
|
keypoints[i].angle = -1;
|
||||||
|
keypoints[i].response = vxCorners[i].strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
*keypoints_count = std::min(nPoints, *keypoints_count);
|
||||||
|
|
||||||
|
#ifdef VX_VERSION_1_1
|
||||||
|
//we should take user memory back before release
|
||||||
|
//(it's not done automatically according to standard)
|
||||||
|
img.swapHandle();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (const ivx::RuntimeError & e)
|
||||||
|
{
|
||||||
|
PRINT_HALERR_MSG(runtime);
|
||||||
|
return CV_HAL_ERROR_UNKNOWN;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (const ivx::WrapperError & e)
|
||||||
|
{
|
||||||
|
PRINT_HALERR_MSG(wrapper);
|
||||||
|
return CV_HAL_ERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CV_HAL_ERROR_OK;
|
||||||
|
}
|
||||||
|
4
3rdparty/openvx/hal/openvx_hal.hpp
vendored
4
3rdparty/openvx/hal/openvx_hal.hpp
vendored
@ -59,7 +59,8 @@ int ovx_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int he
|
|||||||
int ovx_hal_lut(const uchar *src_data, size_t src_step, size_t src_type, const uchar* lut_data, size_t lut_channel_size, size_t lut_channels, uchar *dst_data, size_t dst_step, int width, int height);
|
int ovx_hal_lut(const uchar *src_data, size_t src_step, size_t src_type, const uchar* lut_data, size_t lut_channel_size, size_t lut_channels, uchar *dst_data, size_t dst_step, int width, int height);
|
||||||
int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth,
|
int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth,
|
||||||
double* minVal, double* maxVal, int* minIdx, int* maxIdx, uchar* mask, size_t mask_step);
|
double* minVal, double* maxVal, int* minIdx, int* maxIdx, uchar* mask, size_t mask_step);
|
||||||
|
int ovx_hal_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 /*cv::FastFeatureDetector::DetectorType*/ dtype);
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// functions redefinition
|
// functions redefinition
|
||||||
// ...
|
// ...
|
||||||
@ -152,5 +153,6 @@ int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width,
|
|||||||
#define cv_hal_lut ovx_hal_lut
|
#define cv_hal_lut ovx_hal_lut
|
||||||
#undef cv_hal_minMaxIdxMaskStep
|
#undef cv_hal_minMaxIdxMaskStep
|
||||||
#define cv_hal_minMaxIdxMaskStep ovx_hal_minMaxIdxMaskStep
|
#define cv_hal_minMaxIdxMaskStep ovx_hal_minMaxIdxMaskStep
|
||||||
|
#define cv_hal_FAST ovx_hal_FAST
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,8 +49,6 @@ The references are:
|
|||||||
#include "opencv2/core/hal/intrin.hpp"
|
#include "opencv2/core/hal/intrin.hpp"
|
||||||
#include "opencv2/core/utils/buffer_area.private.hpp"
|
#include "opencv2/core/utils/buffer_area.private.hpp"
|
||||||
|
|
||||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -370,72 +368,6 @@ static bool ocl_FAST( InputArray _img, std::vector<KeyPoint>& keypoints,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENVX
|
|
||||||
namespace ovx {
|
|
||||||
template <> inline bool skipSmallImages<VX_KERNEL_FAST_CORNERS>(int w, int h) { return w*h < 800 * 600; }
|
|
||||||
}
|
|
||||||
static bool openvx_FAST(InputArray _img, std::vector<KeyPoint>& keypoints,
|
|
||||||
int _threshold, bool nonmaxSuppression, int type)
|
|
||||||
{
|
|
||||||
using namespace ivx;
|
|
||||||
|
|
||||||
// Nonmax suppression is done differently in OpenCV than in OpenVX
|
|
||||||
// 9/16 is the only supported mode in OpenVX
|
|
||||||
if(nonmaxSuppression || type != FastFeatureDetector::TYPE_9_16)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Mat imgMat = _img.getMat();
|
|
||||||
if(imgMat.empty() || imgMat.type() != CV_8UC1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ovx::skipSmallImages<VX_KERNEL_FAST_CORNERS>(imgMat.cols, imgMat.rows))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Context context = ovx::getOpenVXContext();
|
|
||||||
Image img = Image::createFromHandle(context, Image::matTypeToFormat(imgMat.type()),
|
|
||||||
Image::createAddressing(imgMat), (void*)imgMat.data);
|
|
||||||
ivx::Scalar threshold = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _threshold);
|
|
||||||
vx_size capacity = imgMat.cols * imgMat.rows;
|
|
||||||
Array corners = Array::create(context, VX_TYPE_KEYPOINT, capacity);
|
|
||||||
|
|
||||||
ivx::Scalar numCorners = ivx::Scalar::create<VX_TYPE_SIZE>(context, 0);
|
|
||||||
|
|
||||||
IVX_CHECK_STATUS(vxuFastCorners(context, img, threshold, (vx_bool)nonmaxSuppression, corners, numCorners));
|
|
||||||
|
|
||||||
size_t nPoints = numCorners.getValue<vx_size>();
|
|
||||||
keypoints.clear(); keypoints.reserve(nPoints);
|
|
||||||
std::vector<vx_keypoint_t> vxCorners;
|
|
||||||
corners.copyTo(vxCorners);
|
|
||||||
for(size_t i = 0; i < nPoints; i++)
|
|
||||||
{
|
|
||||||
vx_keypoint_t kp = vxCorners[i];
|
|
||||||
//if nonmaxSuppression is false, kp.strength is undefined
|
|
||||||
keypoints.push_back(KeyPoint((float)kp.x, (float)kp.y, 7.f, -1, kp.strength));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VX_VERSION_1_1
|
|
||||||
//we should take user memory back before release
|
|
||||||
//(it's not done automatically according to standard)
|
|
||||||
img.swapHandle();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (const RuntimeError & e)
|
|
||||||
{
|
|
||||||
VX_DbgThrow(e.what());
|
|
||||||
}
|
|
||||||
catch (const WrapperError & e)
|
|
||||||
{
|
|
||||||
VX_DbgThrow(e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int hal_FAST(cv::Mat& src, std::vector<KeyPoint>& keypoints, int threshold, bool nonmax_suppression, FastFeatureDetector::DetectorType type)
|
static inline int hal_FAST(cv::Mat& src, std::vector<KeyPoint>& keypoints, int threshold, bool nonmax_suppression, FastFeatureDetector::DetectorType type)
|
||||||
{
|
{
|
||||||
if (threshold > 20)
|
if (threshold > 20)
|
||||||
@ -503,13 +435,12 @@ void FAST(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool
|
|||||||
cv::Mat img = _img.getMat();
|
cv::Mat img = _img.getMat();
|
||||||
CALL_HAL(fast_dense, hal_FAST, img, keypoints, threshold, nonmax_suppression, type);
|
CALL_HAL(fast_dense, hal_FAST, img, keypoints, threshold, nonmax_suppression, type);
|
||||||
|
|
||||||
size_t keypoints_count;
|
size_t keypoints_count = 10000;
|
||||||
|
keypoints.clear();
|
||||||
|
keypoints.resize(keypoints_count);
|
||||||
CALL_HAL(fast, cv_hal_FAST, img.data, img.step, img.cols, img.rows,
|
CALL_HAL(fast, cv_hal_FAST, img.data, img.step, img.cols, img.rows,
|
||||||
(uchar*)(keypoints.data()), &keypoints_count, threshold, nonmax_suppression, type);
|
(uchar*)(keypoints.data()), &keypoints_count, threshold, nonmax_suppression, type);
|
||||||
|
|
||||||
CV_OVX_RUN(true,
|
|
||||||
openvx_FAST(_img, keypoints, threshold, nonmax_suppression, type))
|
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case FastFeatureDetector::TYPE_5_8:
|
case FastFeatureDetector::TYPE_5_8:
|
||||||
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
|
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
|
||||||
|
@ -135,4 +135,34 @@ void CV_FastTest::run( int )
|
|||||||
|
|
||||||
TEST(Features2d_FAST, regression) { CV_FastTest test; test.safe_run(); }
|
TEST(Features2d_FAST, regression) { CV_FastTest test; test.safe_run(); }
|
||||||
|
|
||||||
|
// #define DUMP_TEST_DATA
|
||||||
|
|
||||||
|
TEST(Features2d_FAST, noNMS)
|
||||||
|
{
|
||||||
|
Mat img = imread(string(cvtest::TS::ptr()->get_data_path()) + "inpaint/orig.png", cv::IMREAD_GRAYSCALE);
|
||||||
|
string xml = string(cvtest::TS::ptr()->get_data_path()) + "fast/result_no_nonmax.xml";
|
||||||
|
|
||||||
|
vector<KeyPoint> keypoints;
|
||||||
|
FAST(img, keypoints, 100, false, FastFeatureDetector::DetectorType::TYPE_9_16);
|
||||||
|
Mat kps(1, (int)(keypoints.size() * sizeof(KeyPoint)), CV_8U, &keypoints[0]);
|
||||||
|
|
||||||
|
Mat gt_kps;
|
||||||
|
FileStorage fs(xml, FileStorage::READ);
|
||||||
|
#ifdef DUMP_TEST_DATA
|
||||||
|
if (!fs.isOpened())
|
||||||
|
{
|
||||||
|
fs.open(xml, FileStorage::WRITE);
|
||||||
|
fs << "exp_kps" << kps;
|
||||||
|
fs.release();
|
||||||
|
fs.open(xml, FileStorage::READ);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ASSERT_TRUE(fs.isOpened());
|
||||||
|
fs["exp_kps"] >> gt_kps;
|
||||||
|
fs.release();
|
||||||
|
ASSERT_GT(gt_kps.total(), size_t(0));
|
||||||
|
|
||||||
|
ASSERT_EQ( 0, cvtest::norm(gt_kps, kps, NORM_L2));
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user