Shi-Tomasi corner detector
一.引入
- Shi-Tomasi算子是在Harrise算子的基础上改进的,改进之处在于他们使用了不同的响应函数。
- Harrise算子的响应函数为:
Shi-Tomasi算子的响应函数为:
- Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。在对自相关矩阵 M 进行特征值分析时,产生两个特征值和两个特征方向向量。因为较大的不确定度取决于较小的特征值,所以通过寻找最小特征值的最大值来寻找好的特征点更加准确。
二.函数原型与参数
goodFeaturesToTrack() [1/2]
void cv::goodFeaturesToTrack | ( | InputArray | image, |
---|---|---|---|
OutputArray | corners, | ||
int | maxCorners, | ||
double | qualityLevel, | ||
double | minDistance, | ||
InputArray | mask = noArray() , | ||
int | blockSize = 3 , | ||
bool | useHarrisDetector = false , | ||
double | k = 0.04 | ||
) |
第一个参数:8位或32位浮点型输入图像,单通道
第二个参数:保存检测出的角点
第三个参数:角点数目最大值,如果实际检测的角点超过此值,则只返回前maxCorners个强角点
第四个参数:角点的品质因子
第五个参数:对于初选出的角点而言,如果在其周围minDistance范围内存在其他更强角点,则将此角点删除
第六个参数:指定感兴趣区,如不需在整幅图上寻找角点,则用此参数指定ROI
第七个参数:计算协方差矩阵时的窗口大小
第八个参数:指示是否使用Harris角点检测,如不指定,则计算shi-tomasi角点
第九个参数:Harris角点检测需要的k值
三.源码分析
参考博客:
https://blog.csdn.net/chaipp0607/article/details/54697457此博客给出了详细的函数源码分析
下面是我从官网直接copy的源码,简单注释了一下
#include "opencv2/imgcodecs.hpp"
/**
* @function goodFeaturesToTrack_Demo.cpp
* @brief Demo code for detecting corners using Shi-Tomasi method
* @author OpenCV team
*/
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
/// Global variables
Mat src, src_gray;
int maxCorners = 23;//检测的最多角点数
int maxTrackbar = 100;
RNG rng(12345);
const char* source_window = "Image";
/// Function header
void goodFeaturesToTrack_Demo( int, void* );
/**
* @function main
*/
int main( int argc, char** argv )
{
/// Load source image and convert it to gray
CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
src = imread( parser.get<String>( "@input" ) );
if( src.empty() )
{
cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
cvtColor( src, src_gray, COLOR_BGR2GRAY );
/// Create Window
namedWindow( source_window );
/// Create Trackbar to set the number of corners
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );//滑动条
imshow( source_window, src );
goodFeaturesToTrack_Demo( 0, 0 );
waitKey();
return 0;
}
/**
* @function goodFeaturesToTrack_Demo.cpp
* @brief Apply Shi-Tomasi corner detector
*/
void goodFeaturesToTrack_Demo( int, void* )
{
/// Parameters for Shi-Tomasi algorithm 该函数的各参数
maxCorners = MAX(maxCorners, 1);
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3, gradientSize = 3;
bool useHarrisDetector = false;
double k = 0.04;
/// Copy the source image
Mat copy = src.clone();
/// Apply corner detection调用函数
goodFeaturesToTrack( src_gray,
corners,
maxCorners,
qualityLevel,
minDistance,
Mat(),
blockSize,
gradientSize,
useHarrisDetector,
k );
/// Draw corners detected
cout << "** Number of corners detected: " << corners.size() << endl;
int radius = 10;//指定画出的圈的半径
for( size_t i= 0; i < corners.size(); i++ )
{ //画圆
circle( copy, corners[i], radius, Scalar(rng.uniform(0,255), rng.uniform(0, 256), rng.uniform(0, 256)), FILLED );
}
/// Show what you got
namedWindow( source_window );
imshow( source_window, copy );
}
运行截图: