1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #28803 from asmorkalov:as/gftt_migration

Migrated goodFeaturesToTrack to features module.
This commit is contained in:
Alexander Smorkalov
2026-04-15 08:36:33 +03:00
committed by GitHub
30 changed files with 164 additions and 136 deletions
@@ -130,6 +130,91 @@ public:
static void retainBest( std::vector<KeyPoint>& keypoints, int npoints );
};
/** @brief Determines strong corners on an image.
The function finds the most prominent corners in the image or in the specified image region, as
described in @cite Shi94
- Function calculates the corner quality measure at every source image pixel using the
#cornerMinEigenVal or #cornerHarris .
- Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are
retained).
- The corners with the minimal eigenvalue less than
\f$\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)\f$ are rejected.
- The remaining corners are sorted by the quality measure in the descending order.
- Function throws away each corner for which there is a stronger corner at a distance less than
maxDistance.
The function can be used to initialize a point-based tracker of an object.
@note If the function is called with different values A and B of the parameter qualityLevel , and
A \> B, the vector of returned corners with qualityLevel=A will be the prefix of the output vector
with qualityLevel=B .
@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 Optional 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 blockSize Size of an average block for computing a derivative covariation matrix over each
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.
@sa cornerMinEigenVal, cornerHarris, calcOpticalFlowPyrLK, estimateRigidTransform,
*/
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 );
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 );
/** @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);
/************************************ Base Classes ************************************/
+3
View File
@@ -14,5 +14,8 @@
"jni_type": "jbyte",
"suffix": "B"
}
},
"func_arg_fix" : {
"goodFeaturesToTrack" : { "corners" : {"ctype" : "vector_Point"} }
}
}
@@ -10,6 +10,7 @@ import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Range;
@@ -19,6 +20,7 @@ import org.opencv.features.DescriptorMatcher;
import org.opencv.features.Features;
import org.opencv.core.KeyPoint;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.test.OpenCVTestCase;
import org.opencv.test.OpenCVTestRunner;
import org.opencv.features.Feature2D;
@@ -169,4 +171,25 @@ public class FeaturesTest extends OpenCVTestCase {
assertMatEqual(ref, outImg);
}
public void testGoodFeaturesToTrackMatListOfPointIntDoubleDouble() {
Mat src = gray0;
Imgproc.rectangle(src, new Point(2, 2), new Point(8, 8), new Scalar(100), -1);
MatOfPoint lp = new MatOfPoint();
Features.goodFeaturesToTrack(src, lp, 100, 0.01, 3);
assertEquals(4, lp.total());
}
public void testGoodFeaturesToTrackMatListOfPointIntDoubleDoubleMatIntBooleanDouble() {
Mat src = gray0;
Imgproc.rectangle(src, new Point(2, 2), new Point(8, 8), new Scalar(100), -1);
MatOfPoint lp = new MatOfPoint();
Features.goodFeaturesToTrack(src, lp, 100, 0.01, 3, gray1, 4, 3, true, 0);
assertEquals(4, lp.total());
}
}
+3
View File
@@ -1,6 +1,9 @@
{
"whitelist":
{
"": [
"goodFeaturesToTrack"
],
"Feature2D": ["detect", "compute", "detectAndCompute", "descriptorSize", "descriptorType", "defaultNorm", "empty", "getDefaultName"],
"ORB": ["create", "setMaxFeatures", "setScaleFactor", "setNLevels", "setEdgeThreshold", "setFastThreshold", "setFirstLevel", "setWTA_K", "setScoreType", "setPatchSize", "getFastThreshold", "getDefaultName"],
"MSER": ["create", "detectRegions", "setDelta", "getDelta", "setMinArea", "getMinArea", "setMaxArea", "getMaxArea", "setPass2Only", "getPass2Only", "getDefaultName"],
+1
View File
@@ -9,6 +9,7 @@
"FastFeatureDetector" : { "DetectorType": "FastDetectorType" }
},
"func_arg_fix" : {
"goodFeaturesToTrack" : { "corners" : {"ctype" : "vector_Point"} },
"Feature2D": {
"(void)compute:(NSArray<Mat*>*)images keypoints:(NSMutableArray<NSMutableArray<KeyPoint*>*>*)keypoints descriptors:(NSMutableArray<Mat*>*)descriptors" : { "compute" : {"name" : "compute2"} },
"(void)detect:(NSArray<Mat*>*)images keypoints:(NSMutableArray<NSMutableArray<KeyPoint*>*>*)keypoints masks:(NSArray<Mat*>*)masks" : { "detect" : {"name" : "detect2"} }
@@ -0,0 +1,30 @@
//
// FeaturesTest.swift
//
// Created by Alexander Smorkalov on 2026/13/04.
//
import XCTest
import OpenCV
class ImgprocTest: OpenCVTestCase {
func testGoodFeaturesToTrackMatListOfPointIntDoubleDouble() {
let src = gray0
Imgproc.rectangle(img: src, pt1: Point(x: 2, y: 2), pt2: Point(x: 8, y: 8), color: Scalar(100), thickness: -1)
var lp = [Point]()
Imgproc.goodFeaturesToTrack(image: src, corners: &lp, maxCorners: 100, qualityLevel: 0.01, minDistance: 3)
XCTAssertEqual(4, lp.count)
}
func testGoodFeaturesToTrackMatListOfPointIntDoubleDoubleMatIntBooleanDouble() {
let src = gray0
Imgproc.rectangle(img: src, pt1: Point(x: 2, y: 2), pt2: Point(x: 8, y: 8), color: Scalar(100), thickness: -1)
var lp = [Point]()
Imgproc.goodFeaturesToTrack(image: src, corners: &lp, maxCorners: 100, qualityLevel: 0.01, minDistance: 3, mask: gray1, blockSize: 4, gradientSize: 3, useHarrisDetector: true, k: 0)
XCTAssertEqual(4, lp.count)
}
}
@@ -40,7 +40,7 @@
//M*/
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "opencl_kernels_features.hpp"
#include <cstdio>
#include <vector>
@@ -100,7 +100,7 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
wgs2_aligned <<= 1;
wgs2_aligned >>= 1;
ocl::Kernel k("maxEigenVal", ocl::imgproc::gftt_oclsrc,
ocl::Kernel k("maxEigenVal", ocl::features::gftt_oclsrc,
format("-D OP_MAX_EIGEN_VAL -D WGS=%d -D groupnum=%d -D WGS2_ALIGNED=%d%s",
(int)wgs, dbsize, wgs2_aligned, haveMask ? " -D HAVE_MASK" : ""));
if (k.empty())
@@ -123,7 +123,7 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
if (!k.run(1, &globalsize, &wgs, false))
return false;
ocl::Kernel k2("maxEigenValTask", ocl::imgproc::gftt_oclsrc,
ocl::Kernel k2("maxEigenValTask", ocl::features::gftt_oclsrc,
format("-D OP_MAX_EIGEN_VAL -D WGS=%zu -D WGS2_ALIGNED=%d -D groupnum=%d",
wgs, wgs2_aligned, dbsize));
if (k2.empty())
@@ -137,7 +137,7 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
// collect list of pointers to features - put them into temporary image
{
ocl::Kernel k("findCorners", ocl::imgproc::gftt_oclsrc,
ocl::Kernel k("findCorners", ocl::features::gftt_oclsrc,
format("-D OP_FIND_CORNERS%s", haveMask ? " -D HAVE_MASK" : ""));
if (k.empty())
return false;
+1
View File
@@ -5,6 +5,7 @@
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/features.hpp"
#endif
@@ -2103,92 +2103,6 @@ CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,
Size winSize, Size zeroZone,
TermCriteria criteria );
/** @brief Determines strong corners on an image.
The function finds the most prominent corners in the image or in the specified image region, as
described in @cite Shi94
- Function calculates the corner quality measure at every source image pixel using the
#cornerMinEigenVal or #cornerHarris .
- Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are
retained).
- The corners with the minimal eigenvalue less than
\f$\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)\f$ are rejected.
- The remaining corners are sorted by the quality measure in the descending order.
- Function throws away each corner for which there is a stronger corner at a distance less than
maxDistance.
The function can be used to initialize a point-based tracker of an object.
@note If the function is called with different values A and B of the parameter qualityLevel , and
A \> B, the vector of returned corners with qualityLevel=A will be the prefix of the output vector
with qualityLevel=B .
@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 Optional 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 blockSize Size of an average block for computing a derivative covariation matrix over each
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.
@sa cornerMinEigenVal, cornerHarris, calcOpticalFlowPyrLK, estimateRigidTransform,
*/
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 );
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 );
/** @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
An example using the Hough line detector
![Sample input image](Hough_Lines_Tutorial_Original_Image.jpg) ![Output image](Hough_Lines_Tutorial_Result.jpg)
-1
View File
@@ -105,7 +105,6 @@
}
},
"func_arg_fix" : {
"goodFeaturesToTrack" : { "corners" : {"ctype" : "vector_Point"} },
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"fillPoly" : { "pts" : {"ctype" : "vector_vector_Point"} },
@@ -1007,26 +1007,6 @@ public class ImgprocTest extends OpenCVTestCase {
assertMatEqual(truth, dst);
}
public void testGoodFeaturesToTrackMatListOfPointIntDoubleDouble() {
Mat src = gray0;
Imgproc.rectangle(src, new Point(2, 2), new Point(8, 8), new Scalar(100), -1);
MatOfPoint lp = new MatOfPoint();
Imgproc.goodFeaturesToTrack(src, lp, 100, 0.01, 3);
assertEquals(4, lp.total());
}
public void testGoodFeaturesToTrackMatListOfPointIntDoubleDoubleMatIntBooleanDouble() {
Mat src = gray0;
Imgproc.rectangle(src, new Point(2, 2), new Point(8, 8), new Scalar(100), -1);
MatOfPoint lp = new MatOfPoint();
Imgproc.goodFeaturesToTrack(src, lp, 100, 0.01, 3, gray1, 4, 3, true, 0);
assertEquals(4, lp.total());
}
public void testGrabCutMatMatRectMatMatInt() {
fail("Not yet implemented");
}
-1
View File
@@ -59,7 +59,6 @@
"getRectSubPix",
"getRotationMatrix2D",
"getStructuringElement",
"goodFeaturesToTrack",
"grabCut",
"HoughCircles",
"HoughLines",
-1
View File
@@ -45,7 +45,6 @@
},
"func_arg_fix" : {
"Imgproc" : {
"goodFeaturesToTrack" : { "corners" : {"ctype" : "vector_Point"} },
"minEnclosingCircle" : { "points" : {"ctype" : "vector_Point2f"} },
"fitEllipse" : { "points" : {"ctype" : "vector_Point2f"} },
"fillPoly" : { "pts" : {"ctype" : "vector_vector_Point"},
@@ -848,26 +848,6 @@ class ImgprocTest: OpenCVTestCase {
try assertMatEqual(truth!, dst)
}
func testGoodFeaturesToTrackMatListOfPointIntDoubleDouble() {
let src = gray0
Imgproc.rectangle(img: src, pt1: Point(x: 2, y: 2), pt2: Point(x: 8, y: 8), color: Scalar(100), thickness: -1)
var lp = [Point]()
Imgproc.goodFeaturesToTrack(image: src, corners: &lp, maxCorners: 100, qualityLevel: 0.01, minDistance: 3)
XCTAssertEqual(4, lp.count)
}
func testGoodFeaturesToTrackMatListOfPointIntDoubleDoubleMatIntBooleanDouble() {
let src = gray0
Imgproc.rectangle(img: src, pt1: Point(x: 2, y: 2), pt2: Point(x: 8, y: 8), color: Scalar(100), thickness: -1)
var lp = [Point]()
Imgproc.goodFeaturesToTrack(image: src, corners: &lp, maxCorners: 100, qualityLevel: 0.01, minDistance: 3, mask: gray1, blockSize: 4, gradientSize: 3, useHarrisDetector: true, k: 0)
XCTAssertEqual(4, lp.count)
}
func testHoughCirclesMatMatIntDoubleDouble() {
let sz:Int32 = 512
let img = Mat(rows: sz, cols: sz, type: CvType.CV_8U, scalar: Scalar(128))
+1
View File
@@ -4,6 +4,7 @@ ocv_define_module(video
opencv_imgproc
OPTIONAL
opencv_3d
opencv_features
opencv_dnn
WRAP
java
@@ -46,6 +46,7 @@
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#include "opencv2/features.hpp"
#ifdef HAVE_OPENCL
@@ -44,6 +44,7 @@
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/features.hpp"
#ifdef HAVE_OPENCL
+1
View File
@@ -1,5 +1,6 @@
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
@@ -6,6 +6,7 @@
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features.hpp"
#include <iostream>
using namespace cv;
@@ -7,6 +7,7 @@
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features.hpp"
#include <iostream>
using namespace cv;
@@ -2,6 +2,7 @@
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
+2 -1
View File
@@ -9,6 +9,7 @@
#include <opencv2/cudaoptflow.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/cudafeatures2d.hpp>
using namespace std;
using namespace cv;
@@ -328,4 +329,4 @@ int main(int argc, const char* argv[])
waitKey(0);
return 0;
}
}
@@ -23,6 +23,7 @@ import org.opencv.core.TermCriteria;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.features.Features;
class CornerSubPix {
private Mat src = new Mat();
@@ -102,7 +103,7 @@ class CornerSubPix {
Mat copy = src.clone();
/// Apply corner detection
Imgproc.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
Features.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
blockSize, gradientSize, useHarrisDetector, k);
/// Draw corners detected
@@ -20,6 +20,7 @@ import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.features.Features;
class GoodFeaturesToTrack {
private Mat src = new Mat();
@@ -99,7 +100,7 @@ class GoodFeaturesToTrack {
Mat copy = src.clone();
/// Apply corner detection
Imgproc.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
Features.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
blockSize, gradientSize, useHarrisDetector, k);
/// Draw corners detected
+1
View File
@@ -4,6 +4,7 @@
#include "opencv2/core/utility.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/features.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/ocl.hpp"