1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

Merge pull request #26907 from asmorkalov:as/openvx_hal_features2d

Migrate remaning OpenVX integrations to OpenVX HAL (features2d)
This commit is contained in:
Alexander Smorkalov
2025-02-14 19:39:58 +03:00
committed by GitHub
5 changed files with 110 additions and 75 deletions
+3 -72
View File
@@ -49,8 +49,6 @@ The references are:
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/utils/buffer_area.private.hpp"
#include "opencv2/core/openvx/ovx_defs.hpp"
namespace cv
{
@@ -370,72 +368,6 @@ static bool ocl_FAST( InputArray _img, std::vector<KeyPoint>& keypoints,
}
#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)
{
if (threshold > 20)
@@ -503,13 +435,12 @@ void FAST(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool
cv::Mat img = _img.getMat();
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,
(uchar*)(keypoints.data()), &keypoints_count, threshold, nonmax_suppression, type);
CV_OVX_RUN(true,
openvx_FAST(_img, keypoints, threshold, nonmax_suppression, type))
switch(type) {
case FastFeatureDetector::TYPE_5_8:
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
+32 -2
View File
@@ -118,8 +118,8 @@ void CV_FastTest::run( int )
read( fs["exp_kps2"], exp_kps2, Mat() );
fs.release();
if ( exp_kps1.size != kps1.size || 0 != cvtest::norm(exp_kps1, kps1, NORM_L2) ||
exp_kps2.size != kps2.size || 0 != cvtest::norm(exp_kps2, kps2, NORM_L2))
if ( exp_kps1.size != kps1.size || 0 != cvtest::norm(exp_kps1, kps1, NORM_L2) ||
exp_kps2.size != kps2.size || 0 != cvtest::norm(exp_kps2, kps2, NORM_L2))
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return;
@@ -135,4 +135,34 @@ void CV_FastTest::run( int )
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