opencv_c++学习(二十五)

一、Harris角点介绍

opencv_c++学习(二十五)_第1张图片
1、海瑞斯角点不可能出现在图像平滑的区域(上图1);
2、图像边缘的支线出不可能出现海瑞斯角点(上图2);
3、海瑞斯角点会出现在顶点处。(上图3);
上图中的下半部分红色圆圈内就是海瑞斯角点常出现的地方。
opencv_c++学习(二十五)_第2张图片
如上图第一个式子,海瑞斯角点就是将窗口移动后的数值与移动前的数值之差乘一个权重而获得。
Harris角点检测函数:

cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType = BORDER_DEFAULT)

src:待检测Harris角点的输入图像,图像必须是CV_8U或者CV_32F的单通道灰度图像。
dst:存放Harris评价系数的R矩阵,数据类型为CV_32F的单通道图像,与输入图像具有相同的尺寸。
blockSize:邻域大小。
ksize: Sobel算子的半径,用于得到梯度信息。
k:计算Harris评价系数R的权重系数,通常取值为0.02-0.04。
borderType:像素外推算法标志。
绘制角点函数:

drawKeypoints(InputArray image, const std:vector< KeyPoint > & keypoints, lnputOutputArray outlmage, const Scalar & collor = Scalar::all( -1), DrawMatchesFlags flags = DranwatchesFlags: :DEFAULT)

image:输入图像。
keypoints:存放关键点的坐标、方向、强度等。
outlmage:输入(图像)/输出(图像)参数。
collor:角点颜色参数。
flags:角点类型的标志参数。
应用案例如下:

int main() {

	//读取图片
	Mat src = imread("2.jpg", IMREAD_COLOR);
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//转成灰度图像
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	

	//计算Harris的相关系数
	Mat harris;
	//邻域半径
	int blockSize = 2;
	int apertureSize = 3;
	cornerHarris(gray, harris, blockSize, apertureSize, 0.04);

	//归一化便于进行数值比较和结果展示
	Mat harrisn;
	normalize(harris, harrisn, 0, 255, NORM_MINMAX);

	//将图像的数据类型变成CV_8U数据类型
	convertScaleAbs(harrisn, harrisn);
	

	//寻找harris角点
	vector<KeyPoint>keyPoints;
	for (int row = 0; row < harrisn.rows; row++)
	{
		for (int col = 0; col < harrisn.cols; col++)
		{
			int R = harrisn.at<uchar>(row, col);
			//如果大于阈值
			if (R>249)
			{
				//向角点中存入KeyPoint中
				KeyPoint keyPoint;
				keyPoint.pt.y = row;
				keyPoint.pt.x = col;
				
				keyPoints.push_back(keyPoint);
			}
		}
	}
	
	drawKeypoints(src, keyPoints, src);
	imshow("q", src);

	waitKey(0);
	return 0;

}

二、Shi-Tomas角点检测

opencv_c++学习(二十五)_第3张图片
上图左侧为Harris角点检测,而右侧为Shi-Tomas角点检测。

goodFeaturesToTrack(InputArrayimage, OutputArray corners, int maxConers, double qualityLevell, double minDistance, InputArray mask = noArray(), int blockSize = 3, useHarrisDetector =, bool false, double k = 0.04)

corners:检测到角点的输出量。
maxCorners:要寻找的角点数目。
qualityLevel:角点阈值与最佳角点的关系,又称质量等级,当参数为0.01,表示角点阈值是最佳角点的0.01倍。
minDistance:两个角点之间的最小欧式距离。
mask:掩码矩阵,表示检测角点的区域。
blockSize:计算梯度协方差矩阵的尺寸。
useHarrisDetector:是否使用Harris角点。
k: Harris检测角点过程中的常值权重系数。
本节应用案例如下:

int main() {

	//读取图片
	Mat src = imread("2.jpg");
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//转成灰度图像
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	//提取角点参数设置
	//要检测角点的数目
	int maxCorners = 100;
	//阈值与最佳角点的比例关系
	double quality_level = 0.01;
	//两角点之间最小欧氏距离
	double minDistance = 0.04;

	//开始检测角点
	vector<Point2f> corners;
	goodFeaturesToTrack(gray, corners, maxCorners, quality_level, minDistance, Mat(), 3, false);

	//绘制角点
	//存放角点信息的类
	vector<KeyPoint> keypoints;

	for (int i = 0; i < corners.size(); i++)
	{
		KeyPoint keyPoint;
		keyPoint.pt = corners[i];
		keypoints.push_back(keyPoint);
	}

	//绘制角点
	drawKeypoints(src, keypoints, src);
	imshow("q", src);
	waitKey(0);
	return 0;
}

检测结果如下:
opencv_c++学习(二十五)_第4张图片

三、角点位置亚像素优化

opencv_c++学习(二十五)_第5张图片

cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, size zeroZone, TermCriteria criteria)

image:输入图像,必须是CV_8U或者CV_32F的单通道灰度图像。corners:角点坐标,既是输入的角点坐标又是精确后的角点坐标。
winSize:搜索窗口尺寸的一半,必须是整数。实际的搜索窗口尺寸比该参数的2倍大1。
zeroZone:搜索区域中间死区大小的一半,即不提取像素点的区域,(-1,-1)表示没有死区。
criteria:终止角点优化迭代的条件。
本节应用案例如下:

int main() {

	//读取图片
	Mat src = imread("2.jpg", IMREAD_COLOR);
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//转成灰度图像
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	//提取角点的参数设置
	//检测角点的数目
	int maxCorners = 100;
	//质量等级(阈值与最佳角点的比例关系)
	double quality_level = 0.01;
	//两个角点之间的最小欧式距离
	double minDistance = 0.04;

	//开始检测角点
	vector<Point2f> corners;
	goodFeaturesToTrack(gray, corners, maxCorners, quality_level, minDistance, Mat(), 3, false);

	//计算亚像素级别角点坐标
	//对角点进行备份
	vector<Point2f> cornersSub = corners;

	Size winSize = Size(5, 5);
	Size zeroZone = Size(-1, -1);

	//设置迭代终止条件(精度、优化次数两种)
	TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 40, 0.001);

	//对角点位置进行优化
	cornerSubPix(gray, cornersSub, winSize, zeroZone, criteria);

	//输出初始坐标和精细化坐标
	for (size_t i = 0; i < corners.size(); i++)
	{
		string str = to_string(i);
		str = "第" + str + "个角点初始坐标";
		cout << str << corners[i] << "精细化后坐标:" << cornersSub[i] << endl;
	}
	return 0;
}

运行后的结果为:

0个角点初始坐标[658, 22]精细化后坐标:[653.352, 23.3173]1个角点初始坐标[651, 11]精细化后坐标:[650.709, 12.4754]2个角点初始坐标[679, 22]精细化后坐标:[677.97, 19.1283]3个角点初始坐标[642, 14]精细化后坐标:[642, 14]4个角点初始坐标[703, 14]精细化后坐标:[707.443, 13.5734]5个角点初始坐标[707, 22]精细化后坐标:[707, 22]6个角点初始坐标[701, 22]精细化后坐标:[701, 22]7个角点初始坐标[676, 20]精细化后坐标:[676.378, 19.5311]8个角点初始坐标[737, 10]精细化后坐标:[737.425, 10.4305]9个角点初始坐标[456, 455]精细化后坐标:[455.578, 455.946]10个角点初始坐标[714, 21]精细化后坐标:[714, 21]11个角点初始坐标[671, 15]精细化后坐标:[671, 15]12个角点初始坐标[645, 22]精细化后坐标:[648.17, 21.9485]13个角点初始坐标[329, 337]精细化后坐标:[328.559, 335.181]14个角点初始坐标[200, 70]精细化后坐标:[198.728, 69.3837]15个角点初始坐标[717, 11]精细化后坐标:[718.391, 9.59862]16个角点初始坐标[658, 15]精细化后坐标:[658, 15]17个角点初始坐标[675, 16]精细化后坐标:[676.382, 19.5321]18个角点初始坐标[694, 15]精细化后坐标:[694, 15]19个角点初始坐标[205, 77]精细化后坐标:[200.108, 78.0214]20个角点初始坐标[712, 21]精细化后坐标:[712, 21]21个角点初始坐标[732, 21]精细化后坐标:[732.617, 21.8419]22个角点初始坐标[650, 22]精细化后坐标:[648.169, 21.9459]23个角点初始坐标[724, 629]精细化后坐标:[725.753, 630.577]24个角点初始坐标[708, 14]精细化后坐标:[707.444, 13.5744]25个角点初始坐标[665, 11]精细化后坐标:[665, 11]26个角点初始坐标[726, 21]精细化后坐标:[726, 21]27个角点初始坐标[665, 22]精细化后坐标:[661.722, 20.5759]28个角点初始坐标[684, 15]精细化后坐标:[684, 15]29个角点初始坐标[655, 25]精细化后坐标:[653.352, 23.3171]30个角点初始坐标[686, 17]精细化后坐标:[683.677, 21.9529]31个角点初始坐标[689, 20]精细化后坐标:[690.806, 19.2633]32个角点初始坐标[689, 16]精细化后坐标:[690.808, 19.2695]33个角点初始坐标[697, 21]精细化后坐标:[697, 21]34个角点初始坐标[96, 192]精细化后坐标:[95.4687, 192.106]35个角点初始坐标[106, 197]精细化后坐标:[105.057, 197.03]36个角点初始坐标[720, 20]精细化后坐标:[720, 20]37个角点初始坐标[661, 20]精细化后坐标:[661, 20]38个角点初始坐标[640, 22]精细化后坐标:[640, 22]39个角点初始坐标[720, 18]精细化后坐标:[720, 18]40个角点初始坐标[415, 408]精细化后坐标:[415.696, 409.389]41个角点初始坐标[657, 18]精细化后坐标:[657, 18]42个角点初始坐标[669, 22]精细化后坐标:[669, 22]43个角点初始坐标[693, 18]精细化后坐标:[690.808, 19.2698]44个角点初始坐标[368, 405]精细化后坐标:[367.959, 405.776]45个角点初始坐标[712, 14]精细化后坐标:[712, 14]46个角点初始坐标[665, 14]精细化后坐标:[665, 14]47个角点初始坐标[661, 15]精细化后坐标:[663.909, 19.4959]48个角点初始坐标[699, 18]精细化后坐标:[699, 18]49个角点初始坐标[720, 10]精细化后坐标:[718.391, 9.59848]50个角点初始坐标[322, 294]精细化后坐标:[319.152, 293.47]51个角点初始坐标[693, 20]精细化后坐标:[690.808, 19.2693]52个角点初始坐标[702, 18]精细化后坐标:[702, 18]53个角点初始坐标[718, 22]精细化后坐标:[718, 22]54个角点初始坐标[733, 618]精细化后坐标:[733, 618]55个角点初始坐标[103, 156]精细化后坐标:[102.664, 156.514]56个角点初始坐标[731, 17]精细化后坐标:[732.617, 21.8415]57个角点初始坐标[349, 393]精细化后坐标:[348.878, 392.607]58个角点初始坐标[323, 280]精细化后坐标:[322.064, 277.923]59个角点初始坐标[322, 228]精细化后坐标:[322, 228]60个角点初始坐标[323, 46]精细化后坐标:[318.326, 44.3267]61个角点初始坐标[314, 43]精细化后坐标:[318.326, 44.329]62个角点初始坐标[295, 263]精细化后坐标:[291.54, 266.728]63个角点初始坐标[365, 331]精细化后坐标:[364.131, 328.912]64个角点初始坐标[156, 99]精细化后坐标:[155.564, 95.6742]65个角点初始坐标[699, 635]精细化后坐标:[699, 635]66个角点初始坐标[156, 135]精细化后坐标:[156.318, 136.249]67个角点初始坐标[729, 10]精细化后坐标:[729, 10]68个角点初始坐标[715, 16]精细化后坐标:[715, 16]69个角点初始坐标[698, 637]精细化后坐标:[698, 637]70个角点初始坐标[293, 36]精细化后坐标:[293, 36]71个角点初始坐标[445, 287]精细化后坐标:[444.51, 286.728]72个角点初始坐标[82, 99]精细化后坐标:[81.8857, 97.2768]73个角点初始坐标[139, 155]精细化后坐标:[139.134, 154.738]74个角点初始坐标[155, 95]精细化后坐标:[155.002, 94.6353]75个角点初始坐标[235, 49]精细化后坐标:[234.488, 47.0019]76个角点初始坐标[353, 391]精细化后坐标:[348.878, 392.607]77个角点初始坐标[149, 83]精细化后坐标:[147.25, 84.5725]78个角点初始坐标[135, 156]精细化后坐标:[137.54, 155.613]79个角点初始坐标[155, 92]精细化后坐标:[154.337, 93.5162]80个角点初始坐标[346, 394]精细化后坐标:[348.876, 392.607]81个角点初始坐标[82, 135]精细化后坐标:[81.7435, 135.518]82个角点初始坐标[366, 369]精细化后坐标:[365.88, 366.191]83个角点初始坐标[337, 56]精细化后坐标:[337, 56]84个角点初始坐标[150, 81]精细化后坐标:[147.252, 84.5742]85个角点初始坐标[146, 150]精细化后坐标:[145.671, 150.114]86个角点初始坐标[149, 146]精细化后坐标:[149.521, 146.281]87个角点初始坐标[713, 19]精细化后坐标:[713, 19]88个角点初始坐标[252, 307]精细化后坐标:[252.645, 307.682]89个角点初始坐标[737, 14]精细化后坐标:[737.425, 10.4304]90个角点初始坐标[304, 369]精细化后坐标:[302.66, 369.575]91个角点初始坐标[350, 326]精细化后坐标:[348.492, 327.303]92个角点初始坐标[99, 154]精细化后坐标:[101.828, 156.138]93个角点初始坐标[713, 638]精细化后坐标:[713, 638]94个角点初始坐标[86, 144]精细化后坐标:[85.6566, 142.36]95个角点初始坐标[293, 267]精细化后坐标:[291.54, 266.728]96个角点初始坐标[492, 493]精细化后坐标:[489.718, 492.288]97个角点初始坐标[355, 395]精细化后坐标:[355, 395]98个角点初始坐标[314, 357]精细化后坐标:[314, 357]99个角点初始坐标[718, 14]精细化后坐标:[718.391, 9.59858]

你可能感兴趣的:(opencv学习,opencv,c++,学习)