一、Harris角点介绍
1、海瑞斯角点不可能出现在图像平滑的区域(上图1);
2、图像边缘的支线出不可能出现海瑞斯角点(上图2);
3、海瑞斯角点会出现在顶点处。(上图3);
上图中的下半部分红色圆圈内就是海瑞斯角点常出现的地方。
如上图第一个式子,海瑞斯角点就是将窗口移动后的数值与移动前的数值之差乘一个权重而获得。
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角点检测
上图左侧为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;
}
检测结果如下:
三、角点位置亚像素优化
cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, size zeroZone, TermCriteria criteria)
image:输入图像,必须是CV_8U或者CV_32F的单通道灰度图像。corners:角点坐标,既是输入的角点坐标又是精确后的角点坐标。
winSize:搜索窗口尺寸的一半,必须是整数。实际的搜索窗口尺寸比该参数的2倍大1。
zeroZone:搜索区域中间死区大小的一半,即不提取像素点的区域,(-1,-1)表示没有死区。
criteria:终止角点优化迭代的条件。
本节应用案例如下:文章来源:https://www.toymoban.com/news/detail-465697.html
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;
}
运行后的结果为:文章来源地址https://www.toymoban.com/news/detail-465697.html
第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_c++学习(二十五)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!