From 4a8f06755cf93785a82a455a2035a2ff572cafae Mon Sep 17 00:00:00 2001 From: Anas Date: Tue, 14 Jul 2020 09:14:38 +0300 Subject: [PATCH] goodFeaturesToTrack returns also corner value --- .../include/opencv2/imgproc/imgproc_c.h | 2 +- modules/imgproc/perf/opencl/perf_gftt.cpp | 2 +- .../imgproc/perf/perf_goodFeaturesToTrack.cpp | 2 +- modules/imgproc/src/featureselect.cpp | 18 +-- modules/imgproc/test/ocl/test_gftt.cpp | 10 +- .../imgproc/test/test_goodfeaturetotrack.cpp | 112 ++---------------- 6 files changed, 26 insertions(+), 120 deletions(-) diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h b/modules/imgproc/include/opencv2/imgproc/imgproc_c.h index 86dc119fdd..0daebd0d4b 100644 --- a/modules/imgproc/include/opencv2/imgproc/imgproc_c.h +++ b/modules/imgproc/include/opencv2/imgproc/imgproc_c.h @@ -896,7 +896,7 @@ CVAPI(void) cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, @see cv::goodFeaturesToTrack */ CVAPI(void) cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, - CvArr* temp_image, CvPoint2D32f* corners, + CvArr* temp_image, CvPoint3D32f* corners, int* corner_count, double quality_level, double min_distance, const CvArr* mask CV_DEFAULT(NULL), diff --git a/modules/imgproc/perf/opencl/perf_gftt.cpp b/modules/imgproc/perf/opencl/perf_gftt.cpp index a352e9933f..58dc2732a7 100644 --- a/modules/imgproc/perf/opencl/perf_gftt.cpp +++ b/modules/imgproc/perf/opencl/perf_gftt.cpp @@ -71,7 +71,7 @@ OCL_PERF_TEST_P(GoodFeaturesToTrackFixture, GoodFeaturesToTrack, checkDeviceMaxMemoryAllocSize(img.size(), img.type()); - UMat src(img.size(), img.type()), dst(1, maxCorners, CV_32FC2); + UMat src(img.size(), img.type()), dst(1, maxCorners, CV_32FC3); img.copyTo(src); declare.in(src, WARMUP_READ).out(dst); diff --git a/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp b/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp index a344ff1176..4d951d8e66 100644 --- a/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp +++ b/modules/imgproc/perf/perf_goodFeaturesToTrack.cpp @@ -30,7 +30,7 @@ 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; double minDistance = 1; TEST_CYCLE() goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, noArray(), blockSize, gradientSize, useHarrisDetector); diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index 26c20ea832..3811c8b958 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -175,7 +175,7 @@ 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; corners.reserve(total); if (minDistance >= 1) @@ -236,7 +236,7 @@ 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(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))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -250,7 +250,7 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners, { const Corner & c = corner_ptr[i]; - corners.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))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; @@ -409,7 +409,7 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, } } - std::vector corners; + std::vector corners; size_t i, j, total = tmpCorners.size(), ncorners = 0; if (total == 0) @@ -485,7 +485,7 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, { grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); - corners.push_back(Point2f((float)x, (float)y)); + corners.push_back(Point3f((float)x, (float)y, eig.at(y,x))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -501,7 +501,7 @@ 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(Point2f((float)x, (float)y)); + corners.push_back(Point3f((float)x, (float)y, eig.at(y,x))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; @@ -513,13 +513,13 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners, CV_IMPL void cvGoodFeaturesToTrack( const void* _image, void*, void*, - CvPoint2D32f* _corners, int *_corner_count, + CvPoint3D32f* _corners, int *_corner_count, double quality_level, double min_distance, const void* _maskImage, int block_size, int use_harris, double harris_k ) { cv::Mat image = cv::cvarrToMat(_image), mask; - std::vector corners; + std::vector corners; if( _maskImage ) mask = cv::cvarrToMat(_maskImage); @@ -530,7 +530,7 @@ cvGoodFeaturesToTrack( const void* _image, void*, void*, size_t i, ncorners = corners.size(); for( i = 0; i < ncorners; i++ ) - _corners[i] = cvPoint2D32f(corners[i]); + _corners[i] = cvPoint3D32f(corners[i]); *_corner_count = (int)ncorners; } diff --git a/modules/imgproc/test/ocl/test_gftt.cpp b/modules/imgproc/test/ocl/test_gftt.cpp index 1e47cd250f..24160a3568 100644 --- a/modules/imgproc/test/ocl/test_gftt.cpp +++ b/modules/imgproc/test/ocl/test_gftt.cpp @@ -82,10 +82,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_32FC2, &v[0])); + um.copyTo(Mat(um.size(), CV_32FC3, &v[0])); } }; @@ -98,7 +98,7 @@ 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())); ASSERT_FALSE(points.empty()); @@ -113,9 +113,9 @@ OCL_TEST_P(GoodFeaturesToTrack, Accuracy) int mistmatch = 0; for (size_t i = 0; i < pts.size(); ++i) { - Point2i a = upts[i], b = pts[i]; + Point3f a = upts[i], b = pts[i]; - bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1; + bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1 && std::abs(a.z - b.z) < 1; if (!eq) ++mistmatch; diff --git a/modules/imgproc/test/test_goodfeaturetotrack.cpp b/modules/imgproc/test/test_goodfeaturetotrack.cpp index 0ffee1e55c..59e1244988 100644 --- a/modules/imgproc/test/test_goodfeaturetotrack.cpp +++ b/modules/imgproc/test/test_goodfeaturetotrack.cpp @@ -62,100 +62,6 @@ struct greaterThanPtr { return *a > *b; } }; -static void -test_cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size, - int _aperture_size, double k, int mode, int borderType, const Scalar& _borderValue ) -{ - int i, j; - Scalar borderValue = _borderValue; - int aperture_size = _aperture_size < 0 ? 3 : _aperture_size; - Point anchor( aperture_size/2, aperture_size/2 ); - - CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); - CV_Assert( eigenv.type() == CV_32FC1 ); - CV_Assert( ( src.rows == eigenv.rows ) && - (((mode == MINEIGENVAL)||(mode == HARRIS)) && (src.cols == eigenv.cols)) ); - - int type = src.type(); - int ftype = CV_32FC1; - double kernel_scale = 1; - - Mat dx2, dy2, dxdy(src.size(), CV_32F), kernel; - - kernel = cvtest::calcSobelKernel2D( 1, 0, _aperture_size ); - cvtest::filter2D( src, dx2, ftype, kernel*kernel_scale, anchor, 0, borderType, borderValue ); - kernel = cvtest::calcSobelKernel2D( 0, 1, _aperture_size ); - cvtest::filter2D( src, dy2, ftype, kernel*kernel_scale, anchor, 0, borderType,borderValue ); - - double denom = (1 << (aperture_size-1))*block_size; - denom = denom * denom; - - if( _aperture_size < 0 ) - denom *= 4; - if(type != ftype ) - denom *= 255.; - - denom = 1./denom; - - for( i = 0; i < src.rows; i++ ) - { - float* dxdyp = dxdy.ptr(i); - float* dx2p = dx2.ptr(i); - float* dy2p = dy2.ptr(i); - - for( j = 0; j < src.cols; j++ ) - { - double xval = dx2p[j], yval = dy2p[j]; - dxdyp[j] = (float)(xval*yval*denom); - dx2p[j] = (float)(xval*xval*denom); - dy2p[j] = (float)(yval*yval*denom); - } - } - - kernel = Mat::ones(block_size, block_size, CV_32F); - anchor = Point(block_size/2, block_size/2); - - cvtest::filter2D( dx2, dx2, ftype, kernel, anchor, 0, borderType, borderValue ); - cvtest::filter2D( dy2, dy2, ftype, kernel, anchor, 0, borderType, borderValue ); - cvtest::filter2D( dxdy, dxdy, ftype, kernel, anchor, 0, borderType, borderValue ); - - if( mode == MINEIGENVAL ) - { - for( i = 0; i < src.rows; i++ ) - { - float* eigenvp = eigenv.ptr(i); - const float* dxdyp = dxdy.ptr(i); - const float* dx2p = dx2.ptr(i); - const float* dy2p = dy2.ptr(i); - - for( j = 0; j < src.cols; j++ ) - { - double a = dx2p[j], b = dxdyp[j], c = dy2p[j]; - double d = sqrt( ( a - c )*( a - c ) + 4*b*b ); - eigenvp[j] = (float)( 0.5*(a + c - d)); - } - } - } - else if( mode == HARRIS ) - { - - for( i = 0; i < src.rows; i++ ) - { - float* eigenvp = eigenv.ptr(i); - const float* dxdyp = dxdy.ptr(i); - const float* dx2p = dx2.ptr(i); - const float* dy2p = dy2.ptr(i); - - for( j = 0; j < src.cols; j++ ) - { - double a = dx2p[j], b = dxdyp[j], c = dy2p[j]; - eigenvp[j] = (float)(a*c - b*b - k*(a + c)*(a + c)); - } - } - } -} - - static void test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, int maxCorners, double qualityLevel, double minDistance, @@ -176,9 +82,9 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, eig.create( image.size(), CV_32F ); if( useHarrisDetector ) - test_cornerEigenValsVecs( image, eig, blockSize, aperture_size, harrisK, HARRIS, borderType, 0 ); + cornerHarris( image, eig, blockSize, gradientSize, harrisK ); else - test_cornerEigenValsVecs( image, eig, blockSize, aperture_size, 0, MINEIGENVAL, borderType, 0 ); + cornerMinEigenVal( image, eig, blockSize, gradientSize ); double maxVal = 0; @@ -207,7 +113,7 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, } } - vector corners; + vector corners; size_t i, j, total = tmpCorners.size(), ncorners = 0; std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() ); @@ -277,7 +183,7 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, { grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y)); - corners.push_back(Point2f((float)x, (float)y)); + corners.push_back(Point3f((float)x, (float)y, eig.at(y, x))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) @@ -293,7 +199,7 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners, int y = (int)(ofs / eig.step); int x = (int)((ofs - y*eig.step)/sizeof(float)); - corners.push_back(Point2f((float)x, (float)y)); + corners.push_back(Point3f((float)x, (float)y, eig.at(y, x))); ++ncorners; if( maxCorners > 0 && (int)ncorners == maxCorners ) break; @@ -323,8 +229,8 @@ protected: Mat mask; int maxCorners; - vector corners; - vector Refcorners; + vector corners; + vector Refcorners; double qualityLevel; double minDistance; int blockSize; @@ -475,8 +381,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)) - printf("i = %i X %2.2f Xref %2.2f Y %2.2f Yref %2.2f\n",i,corners[i].x,Refcorners[i].x,corners[i].y,Refcorners[i].y); + 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); } } else