角点检测(三)
1、moravec角点
2、harris角点
3、Shi-Tomasi角点
Shi-Tomasi角点
从上一篇harris角点可知,harris判断是否角点的评判公式是:
R = λ1λ2 - k(λ1 + λ2)²
而这里的 Shi-Tomasi角点,是harris角点算法的一个变式,其评判公式为:
R = min(λ1, λ2)
即为,当矩阵M的两个特征值λ都大于设定阈值时,才判定为角点。
核心函数
void goodFeaturesToTrack(
InputArray image,
OutputArray corners,
int maxCorners,
double qualityLevel,
double minDistance,
InputArray mask=norArray(),
int blockSize=3,
bool useHarrisDetector=false,
double k=0.4)
- 第一个参数,InputArray类型的image,输入图像,须为8位或浮点型32位单通道图像。
- 第二个参数,OutputArray类型的corners,检测到的角点的输出向量。
- 第三个参数,int类型的maxCorners,角点的最大数量。
- 第四个参数,double类型的qualityLevel,角点检测可接受的最小特征值。其实实际用于过滤角点的最小特征值是qualityLevel与图像中最大特征值的乘积。所以qualityLevel通常不会超过1(常用的值为0.10或者0.01)。而检测完所有的角点后,还要进一步剔除掉一些距离较近的角点。
- 第五个参数,double类型的minDistance,角点之间的最小距离,此参数用于保证返回的焦点之间的距离不小于minDistance个像素。
- 第六个参数,InputArray类型的mask,可选参数,表示感兴趣区域,有默认值noArray().若此参数非空(需为CV_8UC1类型,且和第一个参数image有相同的尺寸),便用于指定角点检测区域。
- 第七个参数,int类型的blockSize,有默认值3,是计算导数自相关矩阵时指定的领域范围。
- 第八个参数,bool类型的useHarrisDetector,默认值false,指示是否使用Harris角点检测。
- 第九个参数,double类型的k,有默认值0.04,为用于设置Hessian自相关矩阵行列式的相对权重的权重系数。
调用代码:
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
using namespace cv;
void main()
{
Mat srcImg = imread("F:\\opencv_re_learn\\flash.jpg");
if (!srcImg.data){
cout << "failed to read" << endl;
system("pause");
return;
}
Mat srcGray;
cvtColor(srcImg, srcGray, CV_BGR2GRAY);
//设置检测参数
vector<Point2f>vecCorners;
//可接受的角点最差指标
double qualityLevel = 0.1;
//焦点间最小距离
double minDistance = 10;
//像素邻域中计算协方差矩阵窗口的尺寸
int blockSize = 3;
bool useHarriesDetector = false;
double k = 0.04;
//检测到的角点输出最大数目
int maxCorners = 15;
int maxTrackbar = 100;
Mat result = srcImg.clone();
//调用函数
goodFeaturesToTrack(srcGray, vecCorners, maxCorners,
qualityLevel, minDistance, Mat(), blockSize,
useHarriesDetector, k);
cout << "Corners counts:" << vecCorners.size() << endl;
//绘制
for (int i = 0; i < vecCorners.size(); i++){
circle(result, vecCorners[i], 4, Scalar(0, 0, 255), 2);
}
imshow("resule", result);
waitKey(0);
}
测试效果:
可以看到,该方法检测的角点比harris角点还要细致一些