From 5f4112a1cf1cb1757d832fd03b8cdaf4a95876e7 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Mon, 28 Nov 2016 19:13:41 +0300 Subject: [PATCH 1/6] added initial version of wrapper for Harris corner detection --- modules/imgproc/src/featureselect.cpp | 125 ++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 3f54bef61e..2c14b18492 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -42,6 +42,12 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" +#ifdef HAVE_OPENVX +#define IVX_USE_OPENCV +#define IVX_HIDE_INFO_WARNINGS +#include "ivx.hpp" +#endif + #include #include #include @@ -262,6 +268,117 @@ 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(context, 0); + + //The gradient window size to use on the input. + ivx::Scalar gradientSize = ivx::Scalar::create(context, 3); + + //The block window size used to compute the harris corner score + ivx::Scalar blockSize = ivx::Scalar::create(context, _blockSize); + + //The scalar sensitivity threshold k from the Harris-Stephens equation + ivx::Scalar sensivity = ivx::Scalar::create(context, _harrisK); + + //The radial Euclidean distance for non-maximum suppression + ivx::Scalar minDistance = ivx::Scalar::create(context, _minDistance); + + vx_size capacity = image.cols * image.rows; + Array corners = Array::create(context, VX_TYPE_KEYPOINT, capacity); + ivx::Scalar numCorners = ivx::Scalar::create(context, 0); + + IVX_CHECK_STATUS(vxuHarrisCorners(context, ovxImage, strengthThresh, minDistance, sensivity, + gradientSize.getValue(), blockSize.getValue(), + corners, numCorners)); + + //Download points from array (to be replaced by wrapper version) + size_t nPoints = numCorners.getValue(); + vx_size arrayStride; + vx_keypoint_t* arrayPtr = NULL; +#ifndef VX_VERSION_1_1 + IVX_CHECK_STATUS(vxAccessArrayRange(corners, 0, nPoints, &arrayStride, (void**)&arrayPtr, VX_READ_ONLY)); +#else + vx_map_id mapId; + IVX_CHECK_STATUS(vxMapArrayRange(corners, 0, nPoints, &mapId, &arrayStride, (void**)&arrayPtr, VX_READ_ONLY, + VX_MEMORY_TYPE_HOST, 0)); +#endif + std::vector vxKeypoints(nPoints); + for(size_t i = 0; i < nPoints; i++) + { + vxKeypoints[i] = vxArrayItem(vx_keypoint_t, arrayPtr, i, arrayStride); + } + +#ifndef VX_VERSION_1_1 + IVX_CHECK_STATUS(vxCommitArrayRange(corners, 0, nPoints, &arrayPtr)); +#else + IVX_CHECK_STATUS(vxUnmapArrayRange(corners, mapId)); +#endif + 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 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) + { + CV_Error(CV_StsInternal, e.what()); + return false; + } + catch (WrapperError & e) + { + CV_Error(CV_StsInternal, e.what()); + return false; + } + + return true; +} + +#endif + } void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, @@ -285,6 +402,14 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, return; } +#ifdef HAVE_OPENVX + if(useHarrisDetector && _mask.empty() && + openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, harrisK)) + { + return; + } +#endif + if( useHarrisDetector ) cornerHarris( image, eig, blockSize, 3, harrisK ); else From 77f99358dff0d5799f9e37b528490b1f033ca600 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 2 Dec 2016 14:19:51 +0300 Subject: [PATCH 2/6] fix vxCommitArrayRange() call --- modules/imgproc/src/featureselect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 2c14b18492..29b465245f 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -336,7 +336,7 @@ static bool openvx_harris(Mat image, OutputArray _corners, } #ifndef VX_VERSION_1_1 - IVX_CHECK_STATUS(vxCommitArrayRange(corners, 0, nPoints, &arrayPtr)); + IVX_CHECK_STATUS(vxCommitArrayRange(corners, 0, nPoints, arrayPtr)); #else IVX_CHECK_STATUS(vxUnmapArrayRange(corners, mapId)); #endif From 3f1734bbc7ffd2b5df489e17c4ca4a2e8b3a20e9 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 2 Dec 2016 19:19:11 +0300 Subject: [PATCH 3/6] fixed type checks in wrappers; array downloading code simplified --- modules/imgproc/src/featureselect.cpp | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 29b465245f..ef3deac20b 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -318,28 +318,9 @@ static bool openvx_harris(Mat image, OutputArray _corners, gradientSize.getValue(), blockSize.getValue(), corners, numCorners)); - //Download points from array (to be replaced by wrapper version) - size_t nPoints = numCorners.getValue(); - vx_size arrayStride; - vx_keypoint_t* arrayPtr = NULL; -#ifndef VX_VERSION_1_1 - IVX_CHECK_STATUS(vxAccessArrayRange(corners, 0, nPoints, &arrayStride, (void**)&arrayPtr, VX_READ_ONLY)); -#else - vx_map_id mapId; - IVX_CHECK_STATUS(vxMapArrayRange(corners, 0, nPoints, &mapId, &arrayStride, (void**)&arrayPtr, VX_READ_ONLY, - VX_MEMORY_TYPE_HOST, 0)); -#endif - std::vector vxKeypoints(nPoints); - for(size_t i = 0; i < nPoints; i++) - { - vxKeypoints[i] = vxArrayItem(vx_keypoint_t, arrayPtr, i, arrayStride); - } + std::vector vxKeypoints; + corners.copyTo(vxKeypoints); -#ifndef VX_VERSION_1_1 - IVX_CHECK_STATUS(vxCommitArrayRange(corners, 0, nPoints, arrayPtr)); -#else - IVX_CHECK_STATUS(vxUnmapArrayRange(corners, mapId)); -#endif std::sort(vxKeypoints.begin(), vxKeypoints.end(), VxKeypointsComparator()); vx_float32 maxStrength = 0.0f; @@ -365,12 +346,12 @@ static bool openvx_harris(Mat image, OutputArray _corners, } catch (RuntimeError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } catch (WrapperError & e) { - CV_Error(CV_StsInternal, e.what()); + CV_Error(cv::Error::StsInternal, e.what()); return false; } From ee77538cf9c0a66c1090b24f3a11e03c0aa8a697 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 2 Dec 2016 19:24:30 +0300 Subject: [PATCH 4/6] disabled due to bad accuracy --- modules/imgproc/src/featureselect.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index ef3deac20b..743892ed8d 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -384,7 +384,9 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, } #ifdef HAVE_OPENVX - if(useHarrisDetector && _mask.empty() && + // Disabled due to bad accuracy + if(false && + useHarrisDetector && _mask.empty() && openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, harrisK)) { return; From 1e2ad7e3e32482690fb8e77cc4c2bfbaf3fbc218 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Wed, 14 Dec 2016 18:08:09 +0300 Subject: [PATCH 5/6] rewritten for new macro use --- modules/imgproc/src/featureselect.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 743892ed8d..1e6b593390 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -42,11 +42,7 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" -#ifdef HAVE_OPENVX -#define IVX_USE_OPENCV -#define IVX_HIDE_INFO_WARNINGS -#include "ivx.hpp" -#endif +#include "opencv2/core/openvx/ovx_defs.hpp" #include #include @@ -346,13 +342,11 @@ static bool openvx_harris(Mat image, OutputArray _corners, } catch (RuntimeError & e) { - CV_Error(cv::Error::StsInternal, e.what()); - return false; + VX_DbgThrow(e.what()); } catch (WrapperError & e) { - CV_Error(cv::Error::StsInternal, e.what()); - return false; + VX_DbgThrow(e.what()); } return true; @@ -383,15 +377,9 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, return; } -#ifdef HAVE_OPENVX // Disabled due to bad accuracy - if(false && - useHarrisDetector && _mask.empty() && - openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, harrisK)) - { - return; - } -#endif + CV_OVX_RUN(false && useHarrisDetector && _mask.empty(), + openvx_harris(image, _corners, maxCorners, qualityLevel, minDistance, blockSize, harrisK)) if( useHarrisDetector ) cornerHarris( image, eig, blockSize, 3, harrisK ); From a2646062b2ee6a22f78d6fd8399642d3419e3d1f Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 16 Dec 2016 15:43:11 +0300 Subject: [PATCH 6/6] ivx::Scalars replaced by immediate values --- modules/imgproc/src/featureselect.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 1e6b593390..fc1b034209 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -295,10 +295,10 @@ static bool openvx_harris(Mat image, OutputArray _corners, ivx::Scalar strengthThresh = ivx::Scalar::create(context, 0); //The gradient window size to use on the input. - ivx::Scalar gradientSize = ivx::Scalar::create(context, 3); + vx_int32 gradientSize = 3; //The block window size used to compute the harris corner score - ivx::Scalar blockSize = ivx::Scalar::create(context, _blockSize); + vx_int32 blockSize = _blockSize; //The scalar sensitivity threshold k from the Harris-Stephens equation ivx::Scalar sensivity = ivx::Scalar::create(context, _harrisK); @@ -311,8 +311,7 @@ static bool openvx_harris(Mat image, OutputArray _corners, ivx::Scalar numCorners = ivx::Scalar::create(context, 0); IVX_CHECK_STATUS(vxuHarrisCorners(context, ovxImage, strengthThresh, minDistance, sensivity, - gradientSize.getValue(), blockSize.getValue(), - corners, numCorners)); + gradientSize, blockSize, corners, numCorners)); std::vector vxKeypoints; corners.copyTo(vxKeypoints);