Merge pull request #19392 from amirtu:OCV-165_finalize_goodFeaturesToTrack_returns_also_corner_value_PR
* goodFeaturesToTrack returns also corner value (cherry picked from commit 4a8f06755cf93785a82a455a2035a2ff572cafae) * Added response to GFTT Detector keypoints (cherry picked from commit b88fb40c6ea037e5283e4fbcf0ffde160c65a035) * Moved corner values to another optional variable to preserve backward compatibility (cherry picked from commit 6137383d32859efad7b44dd8a798e7b69f68dec5) * Removed corners valus from perf tests and better unit tests for corners values (cherry picked from commit f3d0ef21a78b7d0dc8696c457a6fabecfbe5e8ff) * Fixed detector gftt call (cherry picked from commit be2975553ba01a7d2e63f549fadccec6d7d56797) * Restored test_cornerEigenValsVecs (cherry picked from commit ea3e11811faee63487449983c0b80ff8ee35bbac) * scaling fixed; mineigen calculation rolled back; gftt function overload added (with quality parameter); perf tests were added for the new api function; external bindings were added for the function (with different alias); fixed issues with composition of the output array of the new function (e.g. as requested in comments) ; added sanity checks in the perf tests; removed C API changes. * minor change to GFTTDetector::detect * substitute ts->printf with EXPECT_LE * avoid re-allocations Co-authored-by: Anas <anas.el.amraoui@live.com> Co-authored-by: amir.tulegenov <amir.tulegenov@xperience.ai>
This commit is contained in:
parent
ad66b070a7
commit
47426a8ae5
@ -87,6 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Point2f> corners;
|
std::vector<Point2f> corners;
|
||||||
|
std::vector<float> cornersQuality;
|
||||||
|
|
||||||
if (_image.isUMat())
|
if (_image.isUMat())
|
||||||
{
|
{
|
||||||
@ -97,7 +98,7 @@ public:
|
|||||||
ugrayImage = _image.getUMat();
|
ugrayImage = _image.getUMat();
|
||||||
|
|
||||||
goodFeaturesToTrack( ugrayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
|
goodFeaturesToTrack( ugrayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
|
||||||
blockSize, gradSize, useHarrisDetector, k );
|
cornersQuality, blockSize, gradSize, useHarrisDetector, k );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -106,14 +107,14 @@ public:
|
|||||||
cvtColor( image, grayImage, COLOR_BGR2GRAY );
|
cvtColor( image, grayImage, COLOR_BGR2GRAY );
|
||||||
|
|
||||||
goodFeaturesToTrack( grayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
|
goodFeaturesToTrack( grayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
|
||||||
blockSize, gradSize, useHarrisDetector, k );
|
cornersQuality, blockSize, gradSize, useHarrisDetector, k );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_Assert(corners.size() == cornersQuality.size());
|
||||||
|
|
||||||
keypoints.resize(corners.size());
|
keypoints.resize(corners.size());
|
||||||
std::vector<Point2f>::const_iterator corner_it = corners.begin();
|
for (size_t i = 0; i < corners.size(); i++)
|
||||||
std::vector<KeyPoint>::iterator keypoint_it = keypoints.begin();
|
keypoints[i] = KeyPoint(corners[i], (float)blockSize, -1, cornersQuality[i]);
|
||||||
for( ; corner_it != corners.end() && keypoint_it != keypoints.end(); ++corner_it, ++keypoint_it )
|
|
||||||
*keypoint_it = KeyPoint( *corner_it, (float)blockSize );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1999,6 +1999,38 @@ CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners,
|
|||||||
InputArray mask, int blockSize,
|
InputArray mask, int blockSize,
|
||||||
int gradientSize, bool useHarrisDetector = false,
|
int gradientSize, bool useHarrisDetector = false,
|
||||||
double k = 0.04 );
|
double k = 0.04 );
|
||||||
|
|
||||||
|
/** @brief Same as above, but returns also quality measure of the detected corners.
|
||||||
|
|
||||||
|
@param image Input 8-bit or floating-point 32-bit, single-channel image.
|
||||||
|
@param corners Output vector of detected corners.
|
||||||
|
@param maxCorners Maximum number of corners to return. If there are more corners than are found,
|
||||||
|
the strongest of them is returned. `maxCorners <= 0` implies that no limit on the maximum is set
|
||||||
|
and all detected corners are returned.
|
||||||
|
@param qualityLevel Parameter characterizing the minimal accepted quality of image corners. The
|
||||||
|
parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue
|
||||||
|
(see #cornerMinEigenVal ) or the Harris function response (see #cornerHarris ). The corners with the
|
||||||
|
quality measure less than the product are rejected. For example, if the best corner has the
|
||||||
|
quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure
|
||||||
|
less than 15 are rejected.
|
||||||
|
@param minDistance Minimum possible Euclidean distance between the returned corners.
|
||||||
|
@param mask Region of interest. If the image is not empty (it needs to have the type
|
||||||
|
CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected.
|
||||||
|
@param cornersQuality Output vector of quality measure of the detected corners.
|
||||||
|
@param blockSize Size of an average block for computing a derivative covariation matrix over each
|
||||||
|
pixel neighborhood. See cornerEigenValsAndVecs .
|
||||||
|
@param gradientSize Aperture parameter for the Sobel operator used for derivatives computation.
|
||||||
|
See cornerEigenValsAndVecs .
|
||||||
|
@param useHarrisDetector Parameter indicating whether to use a Harris detector (see #cornerHarris)
|
||||||
|
or #cornerMinEigenVal.
|
||||||
|
@param k Free parameter of the Harris detector.
|
||||||
|
*/
|
||||||
|
CV_EXPORTS CV_WRAP_AS(goodFeaturesToTrackWithQuality) void goodFeaturesToTrack(
|
||||||
|
InputArray image, OutputArray corners,
|
||||||
|
int maxCorners, double qualityLevel, double minDistance,
|
||||||
|
InputArray mask, OutputArray cornersQuality, int blockSize = 3,
|
||||||
|
int gradientSize = 3, bool useHarrisDetector = false, double k = 0.04);
|
||||||
|
|
||||||
/** @example samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
|
/** @example samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
|
||||||
An example using the Hough line detector
|
An example using the Hough line detector
|
||||||
 
|
 
|
||||||
|
|||||||
@ -82,6 +82,35 @@ OCL_PERF_TEST_P(GoodFeaturesToTrackFixture, GoodFeaturesToTrack,
|
|||||||
SANITY_CHECK(dst);
|
SANITY_CHECK(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OCL_PERF_TEST_P(GoodFeaturesToTrackFixture, GoodFeaturesToTrackWithQuality,
|
||||||
|
::testing::Combine(OCL_PERF_ENUM(String("gpu/opticalflow/rubberwhale1.png")),
|
||||||
|
OCL_PERF_ENUM(3.0), Bool()))
|
||||||
|
{
|
||||||
|
GoodFeaturesToTrackParams params = GetParam();
|
||||||
|
const String fileName = get<0>(params);
|
||||||
|
const double minDistance = get<1>(params), qualityLevel = 0.01;
|
||||||
|
const bool harrisDetector = get<2>(params);
|
||||||
|
const int maxCorners = 1000;
|
||||||
|
|
||||||
|
Mat img = imread(getDataPath(fileName), cv::IMREAD_GRAYSCALE);
|
||||||
|
ASSERT_FALSE(img.empty()) << "could not load " << fileName;
|
||||||
|
|
||||||
|
checkDeviceMaxMemoryAllocSize(img.size(), img.type());
|
||||||
|
|
||||||
|
UMat src(img.size(), img.type()), dst(1, maxCorners, CV_32FC2);
|
||||||
|
img.copyTo(src);
|
||||||
|
|
||||||
|
std::vector<float> cornersQuality;
|
||||||
|
|
||||||
|
declare.in(src, WARMUP_READ).out(dst);
|
||||||
|
|
||||||
|
OCL_TEST_CYCLE() cv::goodFeaturesToTrack(src, dst, maxCorners, qualityLevel, minDistance,
|
||||||
|
noArray(), cornersQuality, 3, 3, harrisDetector, 0.04);
|
||||||
|
|
||||||
|
SANITY_CHECK(dst);
|
||||||
|
SANITY_CHECK(cornersQuality, 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
} } // namespace opencv_test::ocl
|
} } // namespace opencv_test::ocl
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -41,4 +41,37 @@ PERF_TEST_P(Image_MaxCorners_QualityLevel_MinDistance_BlockSize_gradientSize_Use
|
|||||||
SANITY_CHECK(corners);
|
SANITY_CHECK(corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PERF_TEST_P(Image_MaxCorners_QualityLevel_MinDistance_BlockSize_gradientSize_UseHarris, goodFeaturesToTrackWithQuality,
|
||||||
|
testing::Combine(
|
||||||
|
testing::Values( "stitching/a1.png", "cv/shared/pic5.png"),
|
||||||
|
testing::Values( 50 ),
|
||||||
|
testing::Values( 0.01 ),
|
||||||
|
testing::Values( 3 ),
|
||||||
|
testing::Values( 3 ),
|
||||||
|
testing::Bool()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
string filename = getDataPath(get<0>(GetParam()));
|
||||||
|
int maxCorners = get<1>(GetParam());
|
||||||
|
double qualityLevel = get<2>(GetParam());
|
||||||
|
int blockSize = get<3>(GetParam());
|
||||||
|
int gradientSize = get<4>(GetParam());
|
||||||
|
bool useHarrisDetector = get<5>(GetParam());
|
||||||
|
double minDistance = 1;
|
||||||
|
|
||||||
|
Mat image = imread(filename, IMREAD_GRAYSCALE);
|
||||||
|
if (image.empty())
|
||||||
|
FAIL() << "Unable to load source image" << filename;
|
||||||
|
|
||||||
|
std::vector<Point2f> corners;
|
||||||
|
std::vector<float> cornersQuality;
|
||||||
|
|
||||||
|
TEST_CYCLE() goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, noArray(),
|
||||||
|
cornersQuality, blockSize, gradientSize, useHarrisDetector);
|
||||||
|
|
||||||
|
SANITY_CHECK(corners);
|
||||||
|
SANITY_CHECK(cornersQuality, 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -74,8 +74,8 @@ struct Corner
|
|||||||
|
|
||||||
static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
||||||
int maxCorners, double qualityLevel, double minDistance,
|
int maxCorners, double qualityLevel, double minDistance,
|
||||||
InputArray _mask, int blockSize, int gradientSize,
|
InputArray _mask, OutputArray _cornersQuality, int blockSize, int gradientSize,
|
||||||
bool useHarrisDetector, double harrisK )
|
bool useHarrisDetector, double harrisK)
|
||||||
{
|
{
|
||||||
UMat eig, maxEigenValue;
|
UMat eig, maxEigenValue;
|
||||||
if( useHarrisDetector )
|
if( useHarrisDetector )
|
||||||
@ -176,7 +176,9 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
std::sort(corner_ptr, corner_ptr + total);
|
std::sort(corner_ptr, corner_ptr + total);
|
||||||
|
|
||||||
std::vector<Point2f> corners;
|
std::vector<Point2f> corners;
|
||||||
|
std::vector<float> cornersQuality;
|
||||||
corners.reserve(total);
|
corners.reserve(total);
|
||||||
|
cornersQuality.reserve(total);
|
||||||
|
|
||||||
if (minDistance >= 1)
|
if (minDistance >= 1)
|
||||||
{
|
{
|
||||||
@ -237,6 +239,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));
|
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(Point2f((float)c.x, (float)c.y));
|
||||||
|
cornersQuality.push_back(c.val);
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
||||||
@ -251,13 +254,19 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
const Corner & c = corner_ptr[i];
|
const Corner & c = corner_ptr[i];
|
||||||
|
|
||||||
corners.push_back(Point2f((float)c.x, (float)c.y));
|
corners.push_back(Point2f((float)c.x, (float)c.y));
|
||||||
|
cornersQuality.push_back(c.val);
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
||||||
|
if (_cornersQuality.needed()) {
|
||||||
|
Mat(cornersQuality).convertTo(_cornersQuality, _cornersQuality.fixedType() ? _cornersQuality.type() : CV_32F);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,9 +363,25 @@ 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, bool useHarrisDetector, double k )
|
||||||
|
{
|
||||||
|
return goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance,
|
||||||
|
mask, noArray(), blockSize, 3, useHarrisDetector, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::goodFeaturesToTrack( InputArray image, OutputArray corners,
|
||||||
|
int maxCorners, double qualityLevel, double minDistance,
|
||||||
|
InputArray mask, int blockSize, int gradientSize, bool useHarrisDetector, double k )
|
||||||
|
{
|
||||||
|
return goodFeaturesToTrack( image, corners, maxCorners, qualityLevel, minDistance,
|
||||||
|
mask, noArray(), blockSize, gradientSize, useHarrisDetector, k );
|
||||||
|
}
|
||||||
|
|
||||||
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
||||||
int maxCorners, double qualityLevel, double minDistance,
|
int maxCorners, double qualityLevel, double minDistance,
|
||||||
InputArray _mask, int blockSize, int gradientSize,
|
InputArray _mask, OutputArray _cornersQuality, int blockSize, int gradientSize,
|
||||||
bool useHarrisDetector, double harrisK )
|
bool useHarrisDetector, double harrisK )
|
||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION();
|
CV_INSTRUMENT_REGION();
|
||||||
@ -366,12 +391,13 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
|
|
||||||
CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(),
|
CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(),
|
||||||
ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,
|
ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,
|
||||||
_mask, blockSize, gradientSize, useHarrisDetector, harrisK))
|
_mask, _cornersQuality, blockSize, gradientSize, useHarrisDetector, harrisK))
|
||||||
|
|
||||||
Mat image = _image.getMat(), eig, tmp;
|
Mat image = _image.getMat(), eig, tmp;
|
||||||
if (image.empty())
|
if (image.empty())
|
||||||
{
|
{
|
||||||
_corners.release();
|
_corners.release();
|
||||||
|
_cornersQuality.release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,11 +436,13 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Point2f> corners;
|
std::vector<Point2f> corners;
|
||||||
|
std::vector<float> cornersQuality;
|
||||||
size_t i, j, total = tmpCorners.size(), ncorners = 0;
|
size_t i, j, total = tmpCorners.size(), ncorners = 0;
|
||||||
|
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
{
|
{
|
||||||
_corners.release();
|
_corners.release();
|
||||||
|
_cornersQuality.release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,6 +513,8 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
{
|
{
|
||||||
grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
|
grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
|
||||||
|
|
||||||
|
cornersQuality.push_back(*tmpCorners[i]);
|
||||||
|
|
||||||
corners.push_back(Point2f((float)x, (float)y));
|
corners.push_back(Point2f((float)x, (float)y));
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
@ -497,18 +527,24 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
{
|
{
|
||||||
for( i = 0; i < total; i++ )
|
for( i = 0; i < total; i++ )
|
||||||
{
|
{
|
||||||
|
cornersQuality.push_back(*tmpCorners[i]);
|
||||||
|
|
||||||
int ofs = (int)((const uchar*)tmpCorners[i] - eig.ptr());
|
int ofs = (int)((const uchar*)tmpCorners[i] - eig.ptr());
|
||||||
int y = (int)(ofs / eig.step);
|
int y = (int)(ofs / eig.step);
|
||||||
int x = (int)((ofs - y*eig.step)/sizeof(float));
|
int x = (int)((ofs - y*eig.step)/sizeof(float));
|
||||||
|
|
||||||
corners.push_back(Point2f((float)x, (float)y));
|
corners.push_back(Point2f((float)x, (float)y));
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
||||||
|
if (_cornersQuality.needed()) {
|
||||||
|
Mat(cornersQuality).convertTo(_cornersQuality, _cornersQuality.fixedType() ? _cornersQuality.type() : CV_32F);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CV_IMPL void
|
CV_IMPL void
|
||||||
@ -534,12 +570,4 @@ cvGoodFeaturesToTrack( const void* _image, void*, void*,
|
|||||||
*_corner_count = (int)ncorners;
|
*_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 )
|
|
||||||
{
|
|
||||||
cv::goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,
|
|
||||||
_mask, blockSize, 3, useHarrisDetector, harrisK );
|
|
||||||
}
|
|
||||||
/* End of file. */
|
/* End of file. */
|
||||||
|
|||||||
@ -62,6 +62,7 @@ PARAM_TEST_CASE(GoodFeaturesToTrack, double, bool)
|
|||||||
|
|
||||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||||
UMat points, upoints;
|
UMat points, upoints;
|
||||||
|
std::vector<float> quality, uquality;
|
||||||
|
|
||||||
virtual void SetUp()
|
virtual void SetUp()
|
||||||
{
|
{
|
||||||
@ -100,14 +101,16 @@ OCL_TEST_P(GoodFeaturesToTrack, Accuracy)
|
|||||||
|
|
||||||
std::vector<Point2f> upts, pts;
|
std::vector<Point2f> upts, pts;
|
||||||
|
|
||||||
OCL_OFF(cv::goodFeaturesToTrack(src_roi, points, maxCorners, qualityLevel, minDistance, noArray()));
|
OCL_OFF(cv::goodFeaturesToTrack(src_roi, points, maxCorners, qualityLevel, minDistance, noArray(), quality));
|
||||||
ASSERT_FALSE(points.empty());
|
ASSERT_FALSE(points.empty());
|
||||||
UMatToVector(points, pts);
|
UMatToVector(points, pts);
|
||||||
|
|
||||||
OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance));
|
OCL_ON(cv::goodFeaturesToTrack(usrc_roi, upoints, maxCorners, qualityLevel, minDistance, noArray(), uquality));
|
||||||
ASSERT_FALSE(upoints.empty());
|
ASSERT_FALSE(upoints.empty());
|
||||||
UMatToVector(upoints, upts);
|
UMatToVector(upoints, upts);
|
||||||
|
|
||||||
|
ASSERT_EQ(pts.size(), quality.size());
|
||||||
|
ASSERT_EQ(upts.size(), uquality.size());
|
||||||
ASSERT_EQ(upts.size(), pts.size());
|
ASSERT_EQ(upts.size(), pts.size());
|
||||||
|
|
||||||
int mistmatch = 0;
|
int mistmatch = 0;
|
||||||
@ -115,7 +118,8 @@ OCL_TEST_P(GoodFeaturesToTrack, Accuracy)
|
|||||||
{
|
{
|
||||||
Point2i a = upts[i], b = pts[i];
|
Point2i 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(quality[i] - uquality[i]) <= 3.f * FLT_EPSILON * std::max(quality[i], uquality[i]);
|
||||||
|
|
||||||
if (!eq)
|
if (!eq)
|
||||||
++mistmatch;
|
++mistmatch;
|
||||||
@ -131,9 +135,10 @@ OCL_TEST_P(GoodFeaturesToTrack, EmptyCorners)
|
|||||||
generateTestData();
|
generateTestData();
|
||||||
usrc_roi.setTo(Scalar::all(0));
|
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, noArray(), uquality));
|
||||||
|
|
||||||
ASSERT_TRUE(upoints.empty());
|
ASSERT_TRUE(upoints.empty());
|
||||||
|
ASSERT_TRUE(uquality.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
OCL_INSTANTIATE_TEST_CASE_P(Imgproc, GoodFeaturesToTrack,
|
OCL_INSTANTIATE_TEST_CASE_P(Imgproc, GoodFeaturesToTrack,
|
||||||
|
|||||||
@ -88,14 +88,13 @@ test_cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
|
|||||||
cvtest::filter2D( src, dy2, ftype, kernel*kernel_scale, anchor, 0, borderType,borderValue );
|
cvtest::filter2D( src, dy2, ftype, kernel*kernel_scale, anchor, 0, borderType,borderValue );
|
||||||
|
|
||||||
double denom = (1 << (aperture_size-1))*block_size;
|
double denom = (1 << (aperture_size-1))*block_size;
|
||||||
denom = denom * denom;
|
|
||||||
|
|
||||||
if( _aperture_size < 0 )
|
if( _aperture_size < 0 )
|
||||||
denom *= 4;
|
denom *= 2.;
|
||||||
if(type != ftype )
|
if(type != ftype )
|
||||||
denom *= 255.;
|
denom *= 255.;
|
||||||
|
|
||||||
denom = 1./denom;
|
denom = 1. / (denom * denom);
|
||||||
|
|
||||||
for( i = 0; i < src.rows; i++ )
|
for( i = 0; i < src.rows; i++ )
|
||||||
{
|
{
|
||||||
@ -159,8 +158,8 @@ test_cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
|
|||||||
static void
|
static void
|
||||||
test_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
test_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
||||||
int maxCorners, double qualityLevel, double minDistance,
|
int maxCorners, double qualityLevel, double minDistance,
|
||||||
InputArray _mask, int blockSize, int gradientSize,
|
InputArray _mask, OutputArray _cornersQuality,
|
||||||
bool useHarrisDetector, double harrisK )
|
int blockSize, int gradientSize, bool useHarrisDetector, double harrisK)
|
||||||
{
|
{
|
||||||
|
|
||||||
CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
|
CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
|
||||||
@ -208,6 +207,7 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vector<Point2f> corners;
|
vector<Point2f> corners;
|
||||||
|
vector<float> cornersQuality;
|
||||||
size_t i, j, total = tmpCorners.size(), ncorners = 0;
|
size_t i, j, total = tmpCorners.size(), ncorners = 0;
|
||||||
|
|
||||||
std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() );
|
std::sort( tmpCorners.begin(), tmpCorners.end(), greaterThanPtr() );
|
||||||
@ -277,6 +277,8 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
{
|
{
|
||||||
grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
|
grid[y_cell*grid_width + x_cell].push_back(Point2f((float)x, (float)y));
|
||||||
|
|
||||||
|
cornersQuality.push_back(*tmpCorners[i]);
|
||||||
|
|
||||||
corners.push_back(Point2f((float)x, (float)y));
|
corners.push_back(Point2f((float)x, (float)y));
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
@ -289,18 +291,24 @@ test_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
|
|||||||
{
|
{
|
||||||
for( i = 0; i < total; i++ )
|
for( i = 0; i < total; i++ )
|
||||||
{
|
{
|
||||||
|
cornersQuality.push_back(*tmpCorners[i]);
|
||||||
|
|
||||||
int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
|
int ofs = (int)((const uchar*)tmpCorners[i] - eig.data);
|
||||||
int y = (int)(ofs / eig.step);
|
int y = (int)(ofs / eig.step);
|
||||||
int x = (int)((ofs - y*eig.step)/sizeof(float));
|
int x = (int)((ofs - y*eig.step)/sizeof(float));
|
||||||
|
|
||||||
corners.push_back(Point2f((float)x, (float)y));
|
corners.push_back(Point2f((float)x, (float)y));
|
||||||
++ncorners;
|
++ncorners;
|
||||||
|
|
||||||
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
if( maxCorners > 0 && (int)ncorners == maxCorners )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
Mat(corners).convertTo(_corners, _corners.fixedType() ? _corners.type() : CV_32F);
|
||||||
|
if (_cornersQuality.needed()) {
|
||||||
|
Mat(cornersQuality).convertTo(_cornersQuality, _cornersQuality.fixedType() ? _cornersQuality.type() : CV_32F);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +333,8 @@ protected:
|
|||||||
int maxCorners;
|
int maxCorners;
|
||||||
vector<Point2f> corners;
|
vector<Point2f> corners;
|
||||||
vector<Point2f> Refcorners;
|
vector<Point2f> Refcorners;
|
||||||
|
vector<float> cornersQuality;
|
||||||
|
vector<float> RefcornersQuality;
|
||||||
double qualityLevel;
|
double qualityLevel;
|
||||||
double minDistance;
|
double minDistance;
|
||||||
int blockSize;
|
int blockSize;
|
||||||
@ -396,6 +406,7 @@ void CV_GoodFeatureToTTest::run_func()
|
|||||||
qualityLevel,
|
qualityLevel,
|
||||||
minDistance,
|
minDistance,
|
||||||
Mat(),
|
Mat(),
|
||||||
|
cornersQuality,
|
||||||
blockSize,
|
blockSize,
|
||||||
gradientSize,
|
gradientSize,
|
||||||
useHarrisDetector,
|
useHarrisDetector,
|
||||||
@ -414,6 +425,7 @@ void CV_GoodFeatureToTTest::run_func()
|
|||||||
qualityLevel,
|
qualityLevel,
|
||||||
minDistance,
|
minDistance,
|
||||||
Mat(),
|
Mat(),
|
||||||
|
cornersQuality,
|
||||||
blockSize,
|
blockSize,
|
||||||
gradientSize,
|
gradientSize,
|
||||||
useHarrisDetector,
|
useHarrisDetector,
|
||||||
@ -439,6 +451,7 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx )
|
|||||||
qualityLevel,
|
qualityLevel,
|
||||||
minDistance,
|
minDistance,
|
||||||
Mat(),
|
Mat(),
|
||||||
|
RefcornersQuality,
|
||||||
blockSize,
|
blockSize,
|
||||||
gradientSize,
|
gradientSize,
|
||||||
useHarrisDetector,
|
useHarrisDetector,
|
||||||
@ -457,6 +470,7 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx )
|
|||||||
qualityLevel,
|
qualityLevel,
|
||||||
minDistance,
|
minDistance,
|
||||||
Mat(),
|
Mat(),
|
||||||
|
RefcornersQuality,
|
||||||
blockSize,
|
blockSize,
|
||||||
gradientSize,
|
gradientSize,
|
||||||
useHarrisDetector,
|
useHarrisDetector,
|
||||||
@ -471,7 +485,7 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx )
|
|||||||
TEST_MESSAGEL (" TestCorners = ", corners.size())
|
TEST_MESSAGEL (" TestCorners = ", corners.size())
|
||||||
TEST_MESSAGE ("\n")
|
TEST_MESSAGE ("\n")
|
||||||
|
|
||||||
ts->printf(cvtest::TS::CONSOLE, "actual error: %g, expected: %g", e, eps);
|
EXPECT_LE(e, eps); // never true
|
||||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
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++){
|
for(int i = 0; i < (int)std::min((unsigned int)(corners.size()), (unsigned int)(Refcorners.size())); i++){
|
||||||
@ -488,6 +502,19 @@ int CV_GoodFeatureToTTest::validate_test_results( int test_case_idx )
|
|||||||
ts->set_failed_test_info(cvtest::TS::OK);
|
ts->set_failed_test_info(cvtest::TS::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e = cv::norm(cornersQuality, RefcornersQuality, NORM_RELATIVE | NORM_INF);
|
||||||
|
|
||||||
|
if (e > eps)
|
||||||
|
{
|
||||||
|
EXPECT_LE(e, eps); // never true
|
||||||
|
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||||
|
|
||||||
|
for(int i = 0; i < (int)std::min((unsigned int)(cornersQuality.size()), (unsigned int)(cornersQuality.size())); i++) {
|
||||||
|
if (std::abs(cornersQuality[i] - RefcornersQuality[i]) > eps * std::max(cornersQuality[i], RefcornersQuality[i]))
|
||||||
|
printf("i = %i Quality %2.6f Quality ref %2.6f\n", i, cornersQuality[i], RefcornersQuality[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return BaseTest::validate_test_results(test_case_idx);
|
return BaseTest::validate_test_results(test_case_idx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user