1、harris角点检测与绘制
void cornerHarris(InputArray src,OutputArray dst,int blocksize,int ksize,double k,int borderType=BORDER_DEFAULT)
参数一:输入阵列,Mat类单通道8位或浮点型图像
参数二:输出阵列
参数三:领域大小
参数四:sobel算子孔径大小
参数五:边界模式
示例代码:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【效果图】"
using namespace std;
using namespace cv;
Mat g_srcImage,g_srcImage1,g_grayImage;
int thresh=30;
int max_thresh=275;
void on_CornerHarris(int ,void *);
int main(int argc,char *argv[])
{
g_srcImage = imread(argv[1]);
if(g_srcImage.empty())
{
printf("读取图片错误,请检查目录下图片是否存在\n");
return -1;
}
g_srcImage1 = g_srcImage.clone();
cvtColor(g_srcImage1,g_grayImage,COLOR_BGR2GRAY);
namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);
createTrackbar("阈值:",WINDOW_NAME1,&thresh,max_thresh,on_CornerHarris);
on_CornerHarris(0,0);
waitKey(0);
return 0;
}
void on_CornerHarris(int,void *)
{
Mat dstImage;
Mat normImage;
Mat scaleImage;
dstImage = Mat::zeros(g_srcImage.size(),CV_32FC1);
g_srcImage1 = g_srcImage.clone();
//进行角点检测
cornerHarris(g_grayImage,dstImage,2,3,0.04,BORDER_DEFAULT);
//归一化
normalize(dstImage,normImage,0,255,NORM_MINMAX,CV_32FC1,Mat());
//转换成八位无符号整型
convertScaleAbs(normImage,scaleImage);
for(int i=0;i<normImage.rows;i++)
{
for(int j=0;j<normImage.cols;j++)
{
if((int)normImage.at<float>(i,j) > thresh+80)
{
circle(g_srcImage1,Point(i,j),5,Scalar(10,10,255),2,8,0);
circle(scaleImage,Point(i,j),5,Scalar(0,10,255),2,8,0);
}
}
}
imshow(WINDOW_NAME1,g_srcImage1);
imshow(WINDOW_NAME2,scaleImage);
}
原图:
效果图:
2、Shi_Tomasi角点检测
void goodFeaturesToTrack(InputArray image,OutputArray corner,int maxCorners,double qualityLevel,double minDistance,InputArray mask=noArray(),int blockSize=3,bool useHarrisDetector=false,double k=0.04)
参数一:8位或浮点型32位图像
参数二:检测到的焦点输出向量
参数三:角点最大数量
参数四:检点检测可接受的最小特征值(0.01、0.10)
参数五:角点之间的最小距离
参数六:可选区域,表示感兴趣区域
参数七:计算导数相关矩阵时指定的领域范围
参数八:表示是否使用harris角点检测
参数九:用于设置hessian自相关矩阵行列式的相对权重的权重系数
示例:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#define WINDOW_NAME "【角点检测】"
using namespace std;
using namespace cv;
Mat g_srcImage,g_grayImage;
int g_maxCornerNumber = 33;
int g_maxTrackbarNumber = 500;
RNG g_rng(12345);
void on_GoodFeaturesToTrack(int ,void *)
{
if(g_maxCornerNumber <=1)
g_maxCornerNumber =1;
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
double k =0.04;
Mat copy = g_srcImage.clone();
goodFeaturesToTrack(g_grayImage,corners,g_maxCornerNumber,qualityLevel,minDistance,Mat(),blockSize,false,k);
cout<<"此次检测的角点数量:"<<corners.size()<<endl;
int r = 4;
for(int i=0;i<corners.size();i++)
{
circle(copy,corners[i],r,Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)),-1,8,0);
}
imshow(WINDOW_NAME,copy);
}
int main(int argc,char *argv[])
{
g_srcImage = imread(argv[1]);
cvtColor(g_srcImage,g_grayImage,COLOR_BGR2GRAY);
namedWindow(WINDOW_NAME,WINDOW_AUTOSIZE);
createTrackbar("最大的角点数:",WINDOW_NAME,&g_maxCornerNumber,g_maxTrackbarNumber,on_GoodFeaturesToTrack);
imshow(WINDOW_NAME,g_srcImage);
on_GoodFeaturesToTrack(0,0);
waitKey(0);
return 0;
}
角点的数量是:113个
3、亚像素级角点检测
如果进行图像处理的目的不是为了提取用于识别的特征点,而是进行几何测量,这通常需要更高精度的;而函数goodFeaturesToTrack只能提供简单的角点坐标值,有时候需要的是实数坐标值而非证书坐标值
void cornerSubPix(InputArray image,InputOutputArray corners,Size winSize,Size zeroZone,TermCriteria criteria)
参数一:输入图像阵列
参数二:提供输入角点的初始坐标和精确的输出坐标
参数三:搜索窗口尺寸的一半
参数四:死区的一半尺寸,死区是不对搜索区的中央位置做求和运算的区域,用来避免自相关矩阵的某些可能的奇异性。(-1,-1)表示没有死区
参数五:求角点过程的迭代终止条件。可以是最大迭代数或者是设定的精确度,也可以是他们的组合。