萌新学习手册:Shi-Tomasi角点检测

自学对象:https://blog.csdn.net/dcrmg/article/details/52551637

Shi-Tomas是对Harris算法的一种改进,效率也得到了大幅的改进。

首先介绍API

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 );

算法将处理图像依照公式求出所有大于设定阈值的点并储存在一个vector中,若点数超过设定的最大数量那么将选取特征最明显的前几个

image:8位或32位单通道灰度图像;

corners:位置点向量,保存的是检测到的角点的坐标;

maxCorners:定义可以检测到的角点的数量的最大值;

qualityLevel:检测到的角点的质量等级,角点特征值小于qualityLevel*最大特征值的点将被舍弃;

minDistance:两个角点间最小间距,以像素为单位;

mask:指定检测区域,若检测整幅图像,mask置为空Mat();

blockSize:计算协方差矩阵时窗口大小;

useHarrisDetector:是否使用Harris角点检测,为false,则使用Shi-Tomasi算子;

k:留给Harris角点检测算子用的中间参数,一般取经验值0.04~0.06。第八个参数为false时,该参数不起作用;

RNG rng(1234);
rng.uniform(0,255)

这是一个用于生成伪随机数的方法,当然,如果你想要生成的伪随机数是小数(例如大于等于0小于1)需要在调用rng.uniform(0.,1.)也就是传入两个浮点数类型

#include
#include
using namespace std;
using namespace cv;
Mat src, gray_src;
int corner_num = 25;
int max_corner = 200;
const char* output_title = "ShiTomasi Detector";
RNG rng(1234);

void ShiTomas_Demo(int, void*);

int main(int argc, char** argv) {
	src = imread("C:/Users/pbiha/Desktop/image/2.png");
	if (src.empty()) {
		puts("Can't find the image...");
		return -1;
	}
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);

	createTrackbar("Num corner:", output_title, &corner_num, max_corner, ShiTomas_Demo);
	ShiTomas_Demo(0, 0);
	waitKey(0);
	return 0;
}
void ShiTomas_Demo(int, void*) {
	if (corner_num < 5)corner_num = 5;
	vectorcorners;
	double qualityLevel = 0.01;
	double minDistance = 15;
	int blockSize = 3;
	bool useHarris = false;
	double k = 0.04;
	
	Mat resultImg = src.clone();

	goodFeaturesToTrack(gray_src, corners, corner_num, qualityLevel, minDistance, Mat(), blockSize, useHarris, k);
	printf("%d\n", corners.size());

	for (int i = 0; i < corners.size(); i++) {
		circle(resultImg, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8, 0);
	}
	imshow(output_title, resultImg);
}

 

你可能感兴趣的:(计算机视觉)