Shi-Tomasi角点检测理论 跟Harris角点检测的理论几乎完全一致,唯一不同的是在使用矩阵 特征值 λ1 λ2 计算角度响应的时候
R = min(λ1, λ2)
void goodFeaturesToTrack( // Shi-Tomasi角点检测
InputArray image, // 灰度图像
OutputArray corners, // 检测出来的角点在输入图像的Point
int maxCorners, // -maxCorners 表示返回角点的数目,如果检测出来的角点数目大于最大数目则返回响应值最强前maxCorners数目。
double qualityLevel, // -qualityLevel表示最小可接受的向量值1500, 0.01, 15
double minDistance, // -minDistance两个角点之间的最小距离(欧几里得距离)
InputArray mask = noArray(),
int blockSize = 3, // -blockSize 计算导数微分不同的窗口大小
bool useHarrisDetector = false, // -useHarrisDetector是否使用Harris角点检测,设置为false的时候 下一个参数 k 无效
double k = 0.04 // 最好 0.04~0.06
);
代码
#include "../common/common.hpp"
static Mat src, gray;
static const char title[] = "shi-tomasi";
static int thresh_v = 25;
static int thresh_max = 200;
static RNG rng(12345);
static void shi_tomasi(int, void*);
void main(int argc, char** argv)
{
src = imread(getCVImagesPath("images/home.jpg"), IMREAD_COLOR);
imshow("src2-5", src);
cvtColor(src, gray, CV_BGR2GRAY);
namedWindow(title, CV_WINDOW_AUTOSIZE);
createTrackbar("thresh:", title, &thresh_v, thresh_max, shi_tomasi);
shi_tomasi(0, 0);
waitKey(0);
}
void shi_tomasi(int, void*)
{
if (thresh_v < 5) thresh_v = 5;
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
bool useHarris = false;
double k = 0.04;
Mat retImg = gray.clone();
cvtColor(retImg, retImg, CV_GRAY2BGR); // 让原图灰度,角点彩色
// opencv中的所有函数都有对应的 cv 开头的函数,那是没有使用命名空间时使用的,函数作用一致
// shi-tomasi 角点检测,运算速度比harris角点检测要快很多,但是harris找出的角点比ShiTomasi要多。不过ShiTomasi的检测结果是能接受的
goodFeaturesToTrack(gray, corners, thresh_v, qualityLevel, minDistance, Mat(), blockSize, useHarris, k);
printf("corners.size=%d\n", corners.size());
for (int i = 0; i < corners.size(); i++)
{
circle(retImg, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8, 0);
}
imshow(title, retImg);
}