角点检测可能应用于工业检测中,可以作为特征点作为后续处理的条件,也可以做图像分割,比如工件外轮廓由直线、圆弧等连接而成,可以通过角点检测把直线和圆弧分割开等。OpenCV中通过两个函数实现图像的亚像素级角点检测。
1、goodFeaturesToTrack()
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 );
寻找像素级角点。
参数:
image:输入8位或32位浮点单通道图像;
corners:输出检测角点的向量;
maxCorners:返回角落的最大数量,如果检测到更多的角度,就返回它们中的最强壮的一个;
qualityLevel:表征图像角点的最小可接受质量的参数,参数值乘以最好角点质量–最小特征值或哈里斯函数响应;
minDistance:返回角点之间可能的最小的欧氏距离;
mask:可选的感兴趣区域,如果角点是空的,它就指定了检测到角点的区域;
blockSize:用于计算每个像素领域的协变导数矩阵的平均块大小;
useHarrisDetector:使用哈里斯检测器的指示参数;
k:哈里斯探测器的自由参数;
2、cornerSubPix()
void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria);
通过上述函数找到的角点进行亚像素级角点定位。
参数:
image:输入图像;
corners:初始化输入角点的坐标,为输出提供细化的坐标;
winSize:搜索窗口的边长的一半;
zeroZone:搜索区域中间的死区的一半大小,对它在下边的求和公式不计算,有时候它用来避免可能的自相关矩阵的奇异性,(-1,-1)用来表明这里没有这样的规模;
criteria:角点细化的迭代过程的终止条件;
3、创建TrackBar
自定义角点数。
createTrackbar("角点数", output_winName, &max_corners, max_count, SubPixel_Demo); //创建TrackBar
4、代码实现
void SubPixel_Demo(int, void*)
{
if (max_corners < 5)
{
max_corners = 5; //控制下限
}
vector<Point2f> corners; // 里面存放找到的角点坐标
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
double k = 0.04;
// 调用goodFeaturesToTrack进行shi-Tomasi角点检测
goodFeaturesToTrack(gray_img, corners, max_corners, qualityLevel, minDistance, Mat(), blockSize, false, k);
cout << "角点数: " << corners.size() << endl;
Mat result_img = src_img.clone();
Mat result_img1 = src_img.clone();
for (auto t = 0; t < corners.size(); ++t)
{
circle(result_img, corners[t], 2, Scalar(0,0,255), 2, 8, 0);
}
// 参数设置
Size winSize = Size(5, 5);
Size zerozone = Size(-1, -1);
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
cornerSubPix(gray_img, corners, winSize, zerozone, criteria); // 调用cornerSubPix函数计算出亚像素角点的位置
// 输出亚像素角点信息
for (auto t = 0; t < corners.size(); ++t)
{
circle(result_img, corners[t], 2, Scalar(255, 0, 0), 2, 8, 0);
cout << "亚像素角点坐标[" << t + 1 << "]" << " point[x, y] = " << corners[t].x << " , " << corners[t].y << endl;
}
imshow(output_winName, result_img);
}
5、结果
该代码是以前从大佬博客学习复制,今天写博客没有找到原作者,若涉嫌抄袭,请联系作者删除。