Merge pull request #7773 from savuor:openvx_harris

This commit is contained in:
Alexander Alekhin 2016-12-19 11:39:38 +00:00
commit 07004a46ca

View File

@ -42,6 +42,8 @@
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "opencv2/core/openvx/ovx_defs.hpp"
#include <cstdio>
#include <vector>
#include <iostream>
@ -262,6 +264,95 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
#endif
#ifdef HAVE_OPENVX
struct VxKeypointsComparator
{
bool operator () (const vx_keypoint_t& a, const vx_keypoint_t& b)
{
return a.strength > b.strength;
}
};
static bool openvx_harris(Mat image, OutputArray _corners,
int _maxCorners, double _qualityLevel, double _minDistance,
int _blockSize, double _harrisK)
{
using namespace ivx;
if(image.type() != CV_8UC1) return false;
//OpenVX implementations don't have to provide other sizes
if(!(_blockSize == 3 || _blockSize == 5 || _blockSize == 7)) return false;
try
{
Context context = Context::create();
Image ovxImage = Image::createFromHandle(context, Image::matTypeToFormat(image.type()),
Image::createAddressing(image), image.data);
//The minimum threshold which to eliminate Harris Corner scores (computed using the normalized Sobel kernel).
//set to 0, we'll filter it later by threshold
ivx::Scalar strengthThresh = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0);
//The gradient window size to use on the input.
vx_int32 gradientSize = 3;
//The block window size used to compute the harris corner score
vx_int32 blockSize = _blockSize;
//The scalar sensitivity threshold k from the Harris-Stephens equation
ivx::Scalar sensivity = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _harrisK);
//The radial Euclidean distance for non-maximum suppression
ivx::Scalar minDistance = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, _minDistance);
vx_size capacity = image.cols * image.rows;
Array corners = Array::create(context, VX_TYPE_KEYPOINT, capacity);
ivx::Scalar numCorners = ivx::Scalar::create<VX_TYPE_SIZE>(context, 0);
IVX_CHECK_STATUS(vxuHarrisCorners(context, ovxImage, strengthThresh, minDistance, sensivity,
gradientSize, blockSize, corners, numCorners));
std::vector<vx_keypoint_t> vxKeypoints;
corners.copyTo(vxKeypoints);
std::sort(vxKeypoints.begin(), vxKeypoints.end(), VxKeypointsComparator());
vx_float32 maxStrength = 0.0f;
if(vxKeypoints.size() > 0)
maxStrength = vxKeypoints[0].strength;
size_t maxKeypoints = min((size_t)_maxCorners, vxKeypoints.size());
std::vector<Point2f> keypoints;
keypoints.reserve(maxKeypoints);
for(size_t i = 0; i < maxKeypoints; i++)
{
vx_keypoint_t kp = vxKeypoints[i];
if(kp.strength < maxStrength*_qualityLevel) break;
keypoints.push_back(Point2f((float)kp.x, (float)kp.y));
}
Mat(keypoints).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
#ifdef VX_VERSION_1_1
//we should take user memory back before release
//(it's not done automatically according to standard)
ovxImage.swapHandle();
#endif
}
catch (RuntimeError & e)
{
VX_DbgThrow(e.what());
}
catch (WrapperError & e)
{
VX_DbgThrow(e.what());
}
return true;
}
#endif
}
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
@ -285,6 +376,10 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
return;
}
// Disabled due to bad accuracy
CV_OVX_RUN(false && useHarrisDetector && _mask.empty(),
openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, harrisK))
if( useHarrisDetector )
cornerHarris( image, eig, blockSize, 3, harrisK );
else