1.检测原理
(1)与Harris角点检测基本一致,但是,最后的计算角点响应时使用的公式有所不同,不同如下:
Shi-Tomasi角点检测采用的是较小特征值来确定R
(2)如果高于阈值的,就被认为是角。如果我们在λ1 - λ2空间里画出来,得到的图像是:
2.相关API
void cv::goodFeaturesToTrack( InputArray image, OutputArray corners,int maxCorners, double qualityLevel, double minDistance,InputArray mask, int blockSize,bool useHarrisDetector, double harrisK )
image:输入图像,一般灰度图像,与Harris一致
corners:返回的角点坐标(Point)
maxCorners:表示返回角点的数目,如果检测出来 角点数目大于最大数目则返回响应值最强前规定数目
qualityLevel:表示最小可接受的向量值
minDistance:两个角点之间的最小距离(欧几里得距离)
blockSize:计算导数微分不同的窗口大小
useHarrisDetector:是否使用Harris角点检测
k:系数,如果不适用Harris角点检测,则不用
3.代码实现
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
char inputName[] = "input";
char outputName[] = "result";
int numCorners = 25;//表示返回角点的数目
int maxCorners = 150;
void ShiTomasi(int, void *);
Mat src, dst,graySrc;
RNG rng(1234);
int main()
{
src = imread("D:/VS project/Image/qp.jpg");
if (src.empty())
{
cout << "无法找到图像" << endl;
return -1;
}
namedWindow(inputName, CV_WINDOW_AUTOSIZE);
imshow(inputName,src);
namedWindow(outputName, CV_WINDOW_AUTOSIZE);
cvtColor(src, graySrc, COLOR_BGR2GRAY);
createTrackbar("numConrners Value:", outputName, &numCorners, maxCorners, ShiTomasi);
ShiTomasi(0, 0);
waitKey(0);
}
void ShiTomasi(int, void *)
{
if (numCorners < 5)
{
numCorners = 5; //最小返回检测点数不小于5
}
//定义所有参数
vector<Point2f>corners; //存放返回点的坐标
double qualityLevel = 0.01; //表示最小可接受的向量值
double minDistance = 10; //最近两点之间的距离最小值
int blockSize = 3;
bool useHarris = false;
double k = 0.04;
Mat resultImage = src.clone();
goodFeaturesToTrack(graySrc, corners, numCorners, qualityLevel, minDistance, noArray(), blockSize, useHarris, k);
cout << "Number of Corners:" << corners.size() << endl;
//绘制所有的点
for (size_t i = 0; i < corners.size(); i++)
{
circle(resultImage, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),2,8,0);
}
imshow(outputName, resultImage);
}
结果最多返回了84个点,最后一列没有检测出来,总体效果还可以。