角点检测是用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域。角点检测归为以下三类1、基于灰度图像的角点检测 2、基于二值图像的角点检测 3、基于轮廓曲线的角点检测。基于灰度图像的角点检测又分1.1基于梯度、1.2基于模板、1.3基于模板梯度组合三类方法。基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,常见的有1.2.1 Kitchen-Rosenfeld、1.2.2 Harris、1.2.3 KLT、1.2.4 SUSAN。
harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对L型角点检测精度高。但由于采用了高斯滤波,运算速度相对较慢,角点信息有丢失和位置偏移的现象,而且角点提取有聚簇现象。cornerHarris(src,dst,int bookSize,int ksize,double k)第三个参数bookSize表示领域的大小。第四个参数ksize表示Sobel()算子的孔径大小。第五个参数k,Harris参数。
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src,dst,dst_1;
src = imread("5.jpg",0);
resize(src,src,Size(350,350));
imshow( "原图" ,src);
cornerHarris(src,dst,2,3,0.01);
threshold(dst,dst_1,0.00001,255,CV_THRESH_BINARY);
imshow("角点检测后的二值图",dst_1);
waitKey();
return 0;
}
Shi-Tomasi算法是Harris算法的改进,若两个特征值中较小的一个大于最小阙值,则会得到强角点。goodFeaturesToTrack(src,corners,int maxCorners,double qualityLevel,double minDistance,InputArray mask=noArray())。第二个参数corners,检测到的角点的输出向量。第三个参数maxCorners,角点的最大数量。第四个参数qualityLevel角点检测可接受的最小特征值,通常不会超过1,常用0.10或0.01。第五个参数minDistance,角点之间的最小距离。第六个参数表示感兴趣区域。
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src,dst,dst_1;
src = imread("5.jpg",0);
resize(src,src,Size(350,350));
imshow( "1" ,src);
//角点检测
vector<Point2f>corners;
goodFeaturesToTrack(src,corners,200,0.01,10,Mat());
//绘制角点
Mat copy=src.clone();//复制源图像到临时变量中,作为感兴趣区域。
int r=4;
for(int i=0;i < corners.size();i++)
{
RNG rng;
circle(copy,corners[i],r,Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)),-1);
}
imshow("2",copy);
waitKey();
return 0;
}
亚像素级角点检测。
函数goodFeaturesToTrack()只能提供简单的像素的坐标值。即有时候需要精确到实数坐标值,而非整数坐标值。cornerSubPix(src,corners,Size winSize,Size zeroZone,TermCriteria criteria)。第三个参数winSize,搜索窗口的一半尺寸。第四个参数zeroZone,表示死区的一半尺寸。死区即不进行求和运算的区域,用来避免自相关矩阵可能出现的奇异性。(-1,-1)表示没有死区。第五个参数,求角点的迭代过程的终止条件。
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src,dst,dst_1;
src = imread("5.jpg",0);
resize(src,src,Size(350,350));
imshow( "1" ,src);
//角点检测
vector<Point2f>corners;
goodFeaturesToTrack(src,corners,200,0.01,10,Mat());
//*计算出亚像素角点位置
TermCriteria criteria=TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,40,0.001);
cornerSubPix(src,corners,Size(5,5),Size(-1,-1),criteria);
//*输出角点信息
for(int i=0;i<corners.size();i++)
cout<<"Exact angular point coordinates["<<i<<"]("<<corners[i].x<<","<<corners[i].y<<")"<<endl;
//绘制角点
Mat copy=src.clone();
int r=4;
for(int i=0;i < corners.size();i++)
{
RNG rng;
circle(copy,corners[i],r,Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)),-1);
}
imshow("2",copy);
waitKey();
return 0;
}