From 6137383d32859efad7b44dd8a798e7b69f68dec5 Mon Sep 17 00:00:00 2001 From: Anas Date: Wed, 22 Jul 2020 12:11:38 +0300 Subject: [PATCH] Moved corner values to another optional variable to preserve backward compatibility --- modules/core/include/opencv2/core/types.hpp | 12 ----- modules/features2d/src/gftt.cpp | 14 ++--- modules/imgproc/include/opencv2/imgproc.hpp | 6 ++- .../include/opencv2/imgproc/imgproc_c.h | 4 +- modules/imgproc/perf/opencl/perf_gftt.cpp | 6 ++- .../imgproc/perf/perf_goodFeaturesToTrack.cpp | 9 +++- modules/imgproc/src/featureselect.cpp | 52 +++++++++++++------ modules/imgproc/test/ocl/test_gftt.cpp | 19 ++++--- .../imgproc/test/test_goodfeaturetotrack.cpp | 36 ++++++++----- 9 files changed, 94 insertions(+), 64 deletions(-) diff --git a/modules/core/include/opencv2/core/types.hpp b/modules/core/include/opencv2/core/types.hpp index 2ef4d3b4e8..819fd52817 100644 --- a/modules/core/include/opencv2/core/types.hpp +++ b/modules/core/include/opencv2/core/types.hpp @@ -714,14 +714,6 @@ public: //! the default constructor CV_WRAP KeyPoint(); /** - @param _pt x & y coordinates of the keypoint while z is the response - @param _size keypoint diameter - @param _angle keypoint orientation - @param _octave pyramid octave in which the keypoint has been detected - @param _class_id object id - */ - KeyPoint(Point3f _pt, float _size, float _angle=-1, int _octave=0, int _class_id=-1); - /** @param _pt x & y coordinates of the keypoint @param _size keypoint diameter @param _angle keypoint orientation @@ -2435,10 +2427,6 @@ inline KeyPoint::KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {} -inline -KeyPoint::KeyPoint(Point3f _pt, float _size, float _angle, int _octave, int _class_id) - : pt(_pt.x, _pt.y), size(_size), angle(_angle), response(_pt.z), octave(_octave), class_id(_class_id) {} - inline KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle, float _response, int _octave, int _class_id) : pt(_pt), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {} diff --git a/modules/features2d/src/gftt.cpp b/modules/features2d/src/gftt.cpp index 6e4c17876e..31e5647a4f 100644 --- a/modules/features2d/src/gftt.cpp +++ b/modules/features2d/src/gftt.cpp @@ -86,7 +86,8 @@ public: return; } - std::vector corners; + std::vector corners; + std::vector corners_values; if (_image.isUMat()) { @@ -96,7 +97,7 @@ public: else ugrayImage = _image.getUMat(); - goodFeaturesToTrack( ugrayImage, corners, nfeatures, qualityLevel, minDistance, _mask, + goodFeaturesToTrack( ugrayImage, corners, corners_values, nfeatures, qualityLevel, minDistance, _mask, blockSize, gradSize, useHarrisDetector, k ); } else @@ -105,15 +106,16 @@ public: if( image.type() != CV_8U ) cvtColor( image, grayImage, COLOR_BGR2GRAY ); - goodFeaturesToTrack( grayImage, corners, nfeatures, qualityLevel, minDistance, _mask, + goodFeaturesToTrack( grayImage, corners, corners_values, nfeatures, qualityLevel, minDistance, _mask, blockSize, gradSize, useHarrisDetector, k ); } keypoints.resize(corners.size()); - std::vector::const_iterator corner_it = corners.begin(); + std::vector::const_iterator corner_it = corners.begin(); std::vector::iterator keypoint_it = keypoints.begin(); - for( ; corner_it != corners.end() && keypoint_it != keypoints.end(); ++corner_it, ++keypoint_it ) - *keypoint_it = KeyPoint( *corner_it, (float)blockSize); + std::vector::iterator corners_values_it = corners_values.begin(); + for( ; corner_it != corners.end() && keypoint_it != keypoints.end() && corners_values_it != corners_values.end(); ++corner_it, ++keypoint_it, ++corners_values_it ) + *keypoint_it = KeyPoint( *corner_it, (float)blockSize, -1, *corners_values_it); } diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index d23f2b0db9..52873e6342 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -1981,6 +1981,7 @@ pixel neighborhood. See cornerEigenValsAndVecs . @param useHarrisDetector Parameter indicating whether to use a Harris detector (see #cornerHarris) or #cornerMinEigenVal. @param k Free parameter of the Harris detector. +@param corners_values Optional vector of detected corens response. @sa cornerMinEigenVal, cornerHarris, calcOpticalFlowPyrLK, estimateRigidTransform, */ @@ -1988,13 +1989,14 @@ or #cornerMinEigenVal. CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask = noArray(), int blockSize = 3, - bool useHarrisDetector = false, double k = 0.04 ); + bool useHarrisDetector = false, double k = 0.04, + OutputArray corners_values = noArray()); CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask, int blockSize, int gradientSize, bool useHarrisDetector = false, - double k = 0.04 ); + double k = 0.04, OutputArray corners_values = noArray()); /** @example samples/cpp/tutorial_code/ImgTrans/houghlines.cpp An example using the Hough line detector ![Sample input image](Hough_Lines_Tutorial_Original_Image.jpg) ![Output image](Hough_Lines_Tutorial_Result.jpg) diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h b/modules/imgproc/include/opencv2/imgproc/imgproc_c.h index 0daebd0d4b..571d25d0df 100644 --- a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h +++ b/modules/imgproc/include/opencv2/imgproc/imgproc_c.h @@ -896,13 +896,13 @@ CVAPI(void) cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, @see cv::goodFeaturesToTrack */ CVAPI(void) cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, - CvArr* temp_image, CvPoint3D32f* corners, + CvArr* temp_image, CvPoint2D32f* corners, int* corner_count, double quality_level, double min_distance, const CvArr* mask CV_DEFAULT(NULL), int block_size CV_DEFAULT(3), int use_harris CV_DEFAULT(0), - double k CV_DEFAULT(0.04) ); + double k CV_DEFAULT(0.04), float* corners_values CV_DEFAULT(NULL)); /** @brief Finds lines on binary image using one of several methods. diff --git a/modules/imgproc/perf/opencl/perf_gftt.cpp b/modules/imgproc/perf/opencl/perf_gftt.cpp index 58dc2732a7..5ad57971f6 100644 --- a/modules/imgproc/perf/opencl/perf_gftt.cpp +++ b/modules/imgproc/perf/opencl/perf_gftt.cpp @@ -71,15 +71,17 @@ OCL_PERF_TEST_P(GoodFeaturesToTrackFixture, GoodFeaturesToTrack, checkDeviceMaxMemoryAllocSize(img.size(), img.type()); - UMat src(img.size(), img.type()), dst(1, maxCorners, CV_32FC3); + UMat src(img.size(), img.type()), dst(1, maxCorners, CV_32FC2); + std::vector values; img.copyTo(src); declare.in(src, WARMUP_READ).out(dst); OCL_TEST_CYCLE() cv::goodFeaturesToTrack(src, dst, maxCorners, qualityLevel, - minDistance, noArray(), 3, 3, harrisDetector, 0.04); + minDistance, noArray(), 3, 3, harrisDetector, 0.04, values); SANITY_CHECK(dst); + SANITY_CHECK(values); } } } // namespace opencv_test::ocl diff --git a/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp b/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp index 4d951d8e66..413f6e8085 100644 --- a/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp +++ b/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp @@ -30,15 +30,20 @@ PERF_TEST_P(Image_MaxCorners_QualityLevel_MinDistance_BlockSize_gradientSize_Use if (image.empty()) FAIL() << "Unable to load source image" << filename; - std::vector corners; + std::vector corners; + std::vector corners_values; double minDistance = 1; - TEST_CYCLE() goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, noArray(), blockSize, gradientSize, useHarrisDetector); + TEST_CYCLE() goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, noArray(), blockSize, gradientSize, useHarrisDetector, corners_values); if (corners.size() > 50) corners.erase(corners.begin() + 50, corners.end()); + if (corners_values.size() > 50) + corners_values.erase(corners_values.begin() + 50, corners_values.end()); + SANITY_CHECK(corners); + SANITY_CHECK(corners_values); } } // namespace diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 3811c8b958..4fc935bc34 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -75,7 +75,7 @@ struct Corner static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, InputArray _mask, int blockSize, int gradientSize, - bool useHarrisDetector, double harrisK ) + bool useHarrisDetector, double harrisK, OutputArray _corners_values) { UMat eig, maxEigenValue; if( useHarrisDetector ) @@ -175,8 +175,10 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners, Corner* corner_ptr = tmpCorners.ptr() + 1; std::sort(corner_ptr, corner_ptr + total); - std::vector corners; + std::vector corners; + std::vector corners_values; corners.reserve(total); + corners_values.reserve(total); if (minDistance >= 1) { @@ -236,7 +238,8 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners, { grid[y_cell*grid_width + x_cell].push_back(Point2f((float)c.x, (float)c.y)); - corners.push_back(Point3f((float)c.x, (float)c.y, eig.getMat(ACCESS_READ).at(c.y, c.x))); + corners.push_back(Point2f((float)c.x, (float)c.y)); + corners_values.push_back(eig.getMat(ACCESS_READ).at(c.y, c.x)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -250,14 +253,18 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners, { const Corner & c = corner_ptr[i]; - corners.push_back(Point3f((float)c.x, (float)c.y, eig.getMat(ACCESS_READ).at(c.y, c.x))); + corners.push_back(Point2f((float)c.x, (float)c.y)); + corners_values.push_back(eig.getMat(ACCESS_READ).at(c.y, c.x)); ++ncorners; + if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F); + Mat(corners_values).convertTo(_corners_values, _corners_values.fixedType() ? _corners_values.type() : CV_32F); + return true; } @@ -357,7 +364,7 @@ static bool openvx_harris(Mat image, OutputArray _corners, void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, InputArray _mask, int blockSize, int gradientSize, - bool useHarrisDetector, double harrisK ) + bool useHarrisDetector, double harrisK, OutputArray _corners_values) { CV_INSTRUMENT_REGION(); @@ -366,12 +373,13 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(), ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance, - _mask, blockSize, gradientSize, useHarrisDetector, harrisK)) + _mask, blockSize, gradientSize, useHarrisDetector, harrisK, _corners_values)) Mat image = _image.getMat(), eig, tmp; if (image.empty()) { _corners.release(); + _corners_values.release(); return; } @@ -409,12 +417,14 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, } } - std::vector corners; + std::vector corners; + std::vector corners_values; size_t i, j, total = tmpCorners.size(), ncorners = 0; if (total == 0) { _corners.release(); + _corners_values.release(); return; } @@ -485,7 +495,8 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, { grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); - corners.push_back(Point3f((float)x, (float)y, eig.at(y,x))); + corners.push_back(Point2f((float)x, (float)y)); + corners_values.push_back(eig.at(y,x)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -501,45 +512,52 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); - corners.push_back(Point3f((float)x, (float)y, eig.at(y,x))); + corners.push_back(Point2f((float)x, (float)y)); + corners_values.push_back(eig.at(y,x)); ++ncorners; + if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F); + Mat(corners_values).convertTo(_corners_values, _corners_values.fixedType() ? _corners_values.type() : CV_32F); } CV_IMPL void cvGoodFeaturesToTrack( const void* _image, void*, void*, - CvPoint3D32f* _corners, int *_corner_count, + CvPoint2D32f* _corners, int *_corner_count, double quality_level, double min_distance, const void* _maskImage, int block_size, - int use_harris, double harris_k ) + int use_harris, double harris_k, float* _corners_values) { cv::Mat image = cv::cvarrToMat(_image), mask; - std::vector corners; + std::vector corners; + std::vector corners_values; if( _maskImage ) mask = cv::cvarrToMat(_maskImage); CV_Assert( _corners && _corner_count ); cv::goodFeaturesToTrack( image, corners, *_corner_count, quality_level, - min_distance, mask, block_size, use_harris != 0, harris_k ); + min_distance, mask, block_size, use_harris != 0, harris_k, corners_values); size_t i, ncorners = corners.size(); - for( i = 0; i < ncorners; i++ ) - _corners[i] = cvPoint3D32f(corners[i]); + for( i = 0; i < ncorners; i++ ) { + _corners[i] = cvPoint2D32f(corners[i]); + _corners_values[i] = corners_values[i]; + } + *_corner_count = (int)ncorners; } void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, InputArray _mask, int blockSize, - bool useHarrisDetector, double harrisK ) + bool useHarrisDetector, double harrisK, OutputArray _corners_values) { cv::goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance, - _mask, blockSize, 3, useHarrisDetector, harrisK ); + _mask, blockSize, 3, useHarrisDetector, harrisK, _corners_values); } /* End of file. */ diff --git a/modules/imgproc/test/ocl/test_gftt.cpp b/modules/imgproc/test/ocl/test_gftt.cpp index 24160a3568..fd48e3a118 100644 --- a/modules/imgproc/test/ocl/test_gftt.cpp +++ b/modules/imgproc/test/ocl/test_gftt.cpp @@ -62,6 +62,7 @@ PARAM_TEST_CASE(GoodFeaturesToTrack, double, bool) TEST_DECLARE_INPUT_PARAMETER(src); UMat points, upoints; + std::vector values, uvalues; virtual void SetUp() { @@ -82,10 +83,10 @@ PARAM_TEST_CASE(GoodFeaturesToTrack, double, bool) UMAT_UPLOAD_INPUT_PARAMETER(src); } - void UMatToVector(const UMat & um, std::vector & v) const + void UMatToVector(const UMat & um, std::vector & v) const { v.resize(um.size().area()); - um.copyTo(Mat(um.size(), CV_32FC3, &v[0])); + um.copyTo(Mat(um.size(), CV_32FC2, &v[0])); } }; @@ -98,14 +99,16 @@ OCL_TEST_P(GoodFeaturesToTrack, Accuracy) { generateTestData(); - std::vector upts, pts; + std::vector upts, pts; - OCL_OFF(cv::goodFeaturesToTrack(src_roi, points, maxCorners, qualityLevel, minDistance, noArray())); + OCL_OFF(cv::goodFeaturesToTrack(src_roi, points, maxCorners, qualityLevel, minDistance, noArray(), 3, 0, 0.04, values)); ASSERT_FALSE(points.empty()); + ASSERT_FALSE(values.empty()); UMatToVector(points, pts); - OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance)); + OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance, noArray(), 3, 0, 0.04, uvalues)); ASSERT_FALSE(upoints.empty()); + ASSERT_FALSE(uvalues.empty()); UMatToVector(upoints, upts); ASSERT_EQ(upts.size(), pts.size()); @@ -113,9 +116,9 @@ OCL_TEST_P(GoodFeaturesToTrack, Accuracy) int mistmatch = 0; for (size_t i = 0; i < pts.size(); ++i) { - Point3f a = upts[i], b = pts[i]; + Point2f a = upts[i], b = pts[i]; - bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1 && std::abs(a.z - b.z) < 1; + bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1 && std::abs(values[i] - uvalues[i]) < 1; if (!eq) ++mistmatch; @@ -131,7 +134,7 @@ OCL_TEST_P(GoodFeaturesToTrack, EmptyCorners) generateTestData(); usrc_roi.setTo(Scalar::all(0)); - OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance)); + OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance, uvalues)); ASSERT_TRUE(upoints.empty()); } diff --git a/modules/imgproc/test/test_goodfeaturetotrack.cpp b/modules/imgproc/test/test_goodfeaturetotrack.cpp index 59e1244988..45b610ee99 100644 --- a/modules/imgproc/test/test_goodfeaturetotrack.cpp +++ b/modules/imgproc/test/test_goodfeaturetotrack.cpp @@ -66,7 +66,7 @@ static void test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, InputArray _mask, int blockSize, int gradientSize, - bool useHarrisDetector, double harrisK ) + bool useHarrisDetector, double harrisK, OutputArray _corners_values) { CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 ); @@ -74,7 +74,6 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, Mat image = _image.getMat(), mask = _mask.getMat(); - int aperture_size = gradientSize; int borderType = BORDER_DEFAULT; Mat eig, tmp, tt; @@ -113,7 +112,8 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, } } - vector corners; + vector corners; + vector corners_values; size_t i, j, total = tmpCorners.size(), ncorners = 0; std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() ); @@ -183,7 +183,8 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, { grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); - corners.push_back(Point3f((float)x, (float)y, eig.at(y, x))); + corners.push_back(Point2f((float)x, (float)y)); + corners_values.push_back(eig.at(y, x)); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -199,14 +200,17 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); - corners.push_back(Point3f((float)x, (float)y, eig.at(y, x))); + corners.push_back(Point2f((float)x, (float)y)); + corners_values.push_back(eig.at(y, x)); ++ncorners; + if( maxCorners > 0 && (int)ncorners == maxCorners ) break; } } Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F); + Mat(corners_values).convertTo(_corners_values, _corners_values.fixedType() ? _corners_values.type() : CV_32F); } @@ -229,8 +233,10 @@ protected: Mat mask; int maxCorners; - vector corners; - vector Refcorners; + vector corners; + vector corners_values; + vector Refcorners; + vector Refcorners_values; double qualityLevel; double minDistance; int blockSize; @@ -305,7 +311,8 @@ void CV_GoodFeatureToTTest::run_func() blockSize, gradientSize, useHarrisDetector, - k ); + k, + corners_values); } else { @@ -323,7 +330,8 @@ void CV_GoodFeatureToTTest::run_func() blockSize, gradientSize, useHarrisDetector, - k ); + k, + corners_values); } } @@ -348,7 +356,8 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx ) blockSize, gradientSize, useHarrisDetector, - k ); + k, + Refcorners_values); } else { @@ -366,7 +375,8 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx ) blockSize, gradientSize, useHarrisDetector, - k ); + k, + Refcorners_values); } double e = cv::norm(corners, Refcorners); // TODO cvtest @@ -381,8 +391,8 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx ) ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); for(int i = 0; i < (int)std::min((unsigned int)(corners.size()), (unsigned int)(Refcorners.size())); i++){ - if ( (corners[i].x != Refcorners[i].x) || (corners[i].y != Refcorners[i].y) || (corners[i].z != Refcorners[i].z)) - printf("i = %i X %2.6f Xref %2.6f Y %2.6f Yref %2.6f Z %2.6f Zref %2.6f\n",i,corners[i].x,Refcorners[i].x,corners[i].y,Refcorners[i].y,corners[i].z,Refcorners[i].z); + if ( (corners[i].x != Refcorners[i].x) || (corners[i].y != Refcorners[i].y) || (corners_values[i] != Refcorners_values[i])) + printf("i = %i X %2.6f Xref %2.6f Y %2.6f Yref %2.6f Values %2.6f Values ref %2.6f\n",i,corners[i].x,Refcorners[i].x,corners[i].y,Refcorners[i].y,corners_values[i],Refcorners_values[i]); } } else