opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取
本章内容:
1. harris角点检测
2. shi-Tomasi角点检测
3. 亚像素角点提取
1.Harris 角点检测
输出结果:
边缘检测后角点检测
输出结果
2. STH-Tomas角点检测
输出结果
3.亚像素角点
输出结果
源码
#include <ostream>
#include <opencv.hpp>
#include <math.h>int main(int argc, char *argv[])
{
/*
本章内容:
1. harris角点检测
2. shi-Tomasi角点检测
3. 亚像素角点提取*/
cv::String fileName = "/home/wang/dev/Image/board.png";
// cv::String fileName = "/home/wang/dev/Image/c10.tif";
cv::Mat src = cv::imread(fileName);
// cv::Mat src1 = cv::imread(fileName1);
cv::Mat src1;
cv::Mat src2;
src1 = src.clone();
src2 = src.clone();
if(src.data == NULL){
printf("图像读入失败\n");
return -1;
}
cv::imshow("src",src);
/*
* api接口:CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
int ksize, double k,
int borderType = BORDER_DEFAULT );
参数分析
* @param dst 计算得分输出,CV_32FC1类型,与src相同大小
@param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ).
@param ksize Sobel核
@param k 一般取0.04~0.06;
*/
cv::Mat gray;
cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
cv::Mat dstHarris;
cv::cornerHarris(gray,dstHarris,3,5,0.04);
cv::normalize(dstHarris,dstHarris,0, 1, cv::NORM_MINMAX);
cv::imshow("Harris Score",dstHarris);// 标记角点
double threVal = 0.5;
for(int i=0;i <dstHarris.rows;i++){
for(int j=0; j<dstHarris.cols; j++){
if(dstHarris.at<float>(i,j) > threVal){
cv::circle(src,cv::Point(j,i),2,cv::Scalar(0,0,255),4);
}
}
}
cv::imshow("gray", gray);
cv::imshow("src marker", src);// 提取变换后角点检测
cv::Mat dstCanny;
cv::Canny(gray,dstCanny,50,150);
cv::Mat CaHarris;
cv::cornerHarris(dstCanny,CaHarris,3,3,0.04);
cv::imshow("dstCanny",dstCanny);
cv::normalize(CaHarris,CaHarris,0, 1, cv::NORM_MINMAX);
cv::Mat normScaleDst;double minVal,maxVal;
cv::minMaxIdx(normScaleDst,&minVal,&maxVal);
for(int i=0;i <CaHarris.rows;i++){
for(int j=0; j<CaHarris.cols; j++){
if(CaHarris.at<float>(i,j) > maxVal*0.7){
cv::circle(src1,cv::Point(j,i),2,cv::Scalar(0,0,255),4);
}
}
}
std::cout << "maxval:" << maxVal << std::endl;
cv::imshow("src1",src1);// Thi-Tomas角点检测
/*
api接口: CV_EXPORTS_W 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 );
参数分析
@param corners : vector<Point2f>
@param maxCorners 最大角点数目
@param qualityLevel 角点强度阈值系数,建议为最大值的0.01倍。
@param minDistance 角点之间的最小距离
*/
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(gray,corners,100,0.01,10);
for(int i=0; i < corners.size();i++){
cv::circle(src2,corners[i],1,cv::Scalar(0,0,255),4);
}
cv::imshow("src2 Thi-Tomas",src2);/*3.亚像素角点
* apie接口: CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,
Size winSize, Size zeroZone,
TermCriteria criteria );
参数分析:
corners: 输入输出类型,需要提供初始角点
winSize: 亚像素拟合大小
zeroZone: 避免出现奇异问题,(-1,-1)
TermCriteria criteria: 迭代终止条件,支持迭代次数或者迭代精度*/
// 构造方式: TermCriteria(int type, int maxCount, double epsilon);
cv::TermCriteria tc(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 50,0.01);
cv::cornerSubPix(gray,corners,cv::Size(5,5),cv::Size(-1,-1),tc);
std::cout << "亚像素角点"<< corners << std::endl;cv::waitKey(0);
return 1;
}