#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; int main(int argc, char** argv)
{
Mat src;
src = imread("数字.jpg",);
if (src.empty()){
printf("Can not load Image...");
return -;
}
imshow("input Image", src); //进行Harris角点检测
Mat cornerStrength;
cornerHarris(src, cornerStrength,,,0.01);//返回局部最大值作为像素,角点坐标存储在cornerStrength中
imshow("角点检测的图", cornerStrength);//值太小,未转成二值图像显示不明显 Mat harrisCorner;
threshold(cornerStrength, harrisCorner,0.00001,,THRESH_BINARY);
imshow("角点检测的二值图", harrisCorner); waitKey();
return ;
}
 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat src,src_gray; int thresh = ;
int max_count = ; const char* output_title = "Harris_CornerDetection Result"; void Harris_demo(int,void*); int main(int argc, char** argv)
{
src = imread("数字.jpg");
if (src.empty()) {
printf("Can not load Image...");
return -;
}
imshow("input Image",src); cvtColor(src, src_gray, COLOR_BGR2GRAY); namedWindow(output_title,CV_WINDOW_AUTOSIZE);
createTrackbar("Threshold", output_title,&thresh, max_count, Harris_demo);
Harris_demo(, ); waitKey();
return ;
} void Harris_demo(int, void*) { Mat cornerStrength;
int blockSize = ;
int ksize = ;
double k = 0.04;
cornerHarris(src_gray, cornerStrength, blockSize, ksize,k,BORDER_DEFAULT);//返回局部最大值作为像素,角点坐标存储在cornerStrength中
normalize(cornerStrength, cornerStrength, , , NORM_MINMAX);//归一化
convertScaleAbs(cornerStrength, cornerStrength);//变成8位无符号整型 //循环遍历每个像素,将大于阈值的点画出来
Mat resultImage = src.clone();
for (int row = ; row < resultImage.rows; row++) {
uchar* currentRow = cornerStrength.ptr(row);
for (int col = ; col < resultImage.cols; col++) {
int value = (int)*currentRow;
if (value > thresh) {
circle(resultImage,Point(col,row),,Scalar(,,),,,);
}
currentRow++;
}
} imshow(output_title, resultImage); }

 因为公式更简单,所以Shi-Tomasi角点检测比Harris要快得多

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat src,src_gray; int num_corners = ;
int max_corners = ;
const char* output_title = "Shi_Tomasi Detector"; void Shi_Tomasi_demo(int,void*); RNG rng(); int main(int argc, char** argv) {
src = imread("数字.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src); cvtColor(src,src_gray,COLOR_BGR2GRAY); namedWindow(output_title, CV_WINDOW_AUTOSIZE);
createTrackbar("角点数:", output_title, &num_corners, max_corners, Shi_Tomasi_demo);
Shi_Tomasi_demo(,); waitKey();
return ;
} void Shi_Tomasi_demo(int, void*) {
if (num_corners < ) num_corners = ; vector<Point2f> corners;//保存检测到的角点
//参数设置
double qualityLevel = 0.01;
double minDistance = ;
int blockSize = ;
bool useHarris = false;//是否使用Harris角点检测
double k = 0.04;//如果前面使用了角点检测,则需要用到这一项,没有则没有用 goodFeaturesToTrack(src_gray,corners,num_corners,qualityLevel,minDistance,Mat(),blockSize,useHarris,k);
printf("Number of detected corner: %d\n",(int)corners.size()); //画出角点
Mat resultImage = src.clone();
for (size_t t=; t < corners.size(); t++)
{
circle(resultImage, corners[t], , Scalar(rng.uniform(, ), rng.uniform(, ), rng.uniform(, )), , , );
}
imshow(output_title, resultImage); }

自定义角点检测器简介:

  • 基于Harris与Shi-Tomasi角点检测

  • 首先通过计算矩阵M得到lamda1和lamda2两个特征值根据他们得到角点响应值

  • 然后自己设置阈值实现计算出阈值得到有效响应值的角点设置

相关API

C++: void cornerEigenValsAndVecs(
InputArray src, --单通道输入8位或浮点图像
OutputArray dst, --输出图像,同源图像或CV_32FC()
int blockSize, --邻域大小值
int apertureSize, --Sobel算子的参数
int borderType=BORDER_DEFAULT --像素外插方法
)//对应于Harris C++: void cornerMinEigenVal(
InputArray src, --单通道输入8位或浮点图像
OutputArray dst, --图像存储的最小特征值。类型为CV_32FC1
int blockSize, --邻域大小值
int apertureSize=, --Sobel算子的参数
int borderType=BORDER_DEFAULT --像素外插方法
}//对应Shi-Tomasi
 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat src,src_gray;
Mat HarrisRsImage; double harris_min_rsp,harris_max_rsp;
int qualityLevel = ;
int max_count = ; const char* harris_window = "Harris"; void CustomHarris_demo(int, void*); int main(int argc, char** argv)
{
src = imread("数字.jpg");
if (src.empty()) {
printf("Can not load Image...");
return -;
}
imshow("input Image",src); cvtColor(src, src_gray, COLOR_BGR2GRAY); //计算特征值lambda1和lambda2
int blockSize = ;
int ksize = ;
Mat Harris_dst=Mat::zeros(src.size(),CV_32FC());//CV_32FC(6),有6个值要存储
cornerEigenValsAndVecs(src_gray, Harris_dst, blockSize, ksize,); //计算响应
HarrisRsImage = Mat::zeros(src.size(), CV_32FC1);
double k = 0.04;
for (int row = ; row < Harris_dst.rows; row++) {
for (int col = ; col < Harris_dst.cols; col++) {
double lambda1=Harris_dst.at<Vec6f>(row, col)[];
double lambda2= Harris_dst.at<Vec6f>(row, col)[];
HarrisRsImage.at<float>(row, col) = lambda1 * lambda2 - k * pow((lambda1 + lambda2), );
}
} minMaxLoc(HarrisRsImage,&harris_min_rsp,&harris_max_rsp,,,Mat());
namedWindow(harris_window,CV_WINDOW_AUTOSIZE);
createTrackbar("Quality", harris_window,&qualityLevel, max_count,CustomHarris_demo);
CustomHarris_demo(,); waitKey();
return ;
} void CustomHarris_demo(int, void*)
{
if (qualityLevel < ) qualityLevel = ;
Mat resultImage = src.clone(); float thresh = harris_min_rsp + (((double)qualityLevel) / max_count)*(harris_max_rsp - harris_min_rsp);//阈值
for (int row = ; row < src.rows; row++) {
for (int col = ; col < src.cols; col++) {
float value = HarrisRsImage.at<float>(row, col);
if (value > thresh) {
circle(resultImage, Point(col, row), , Scalar(, , ), , , );
} }
} imshow(harris_window, resultImage);
}
 //Shi-Tomasi和Harris自定义角点检测

 #include <opencv2/opencv.hpp>
#include <iostream> #include <math.h>
using namespace cv;
using namespace std;
const char* harris_win = "Custom Harris Corners Detector";
const char* shitomasi_win = "Custom Shi-Tomasi Corners Detector";
Mat src, gray_src;
// harris corner response
Mat harris_dst, harrisRspImg;
double harris_min_rsp;
double harris_max_rsp;
// shi-tomasi corner response
Mat shiTomasiRsp;
double shitomasi_max_rsp;
double shitomasi_min_rsp;
int sm_qualitylevel = ;
// quality level
int qualityLevel = ;
int max_count = ;
void CustomHarris_Demo(int, void*);
void CustomShiTomasi_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("D:/vcprojects/images/home.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
cvtColor(src, gray_src, COLOR_BGR2GRAY);
// 计算特征值
int blockSize = ;
int ksize = ;
double k = 0.04;
harris_dst = Mat::zeros(src.size(), CV_32FC());
harrisRspImg = Mat::zeros(src.size(), CV_32FC1);
cornerEigenValsAndVecs(gray_src, harris_dst, blockSize, ksize, );
// 计算响应
for (int row = ; row < harris_dst.rows; row++) {
for (int col = ; col < harris_dst.cols; col++) {
double lambda1 =harris_dst.at<Vec6f>(row, col)[];
double lambda2 = harris_dst.at<Vec6f>(row, col)[];
harrisRspImg.at<float>(row, col) = lambda1*lambda2 - k*pow((lambda1 + lambda2), );
}
}
minMaxLoc(harrisRspImg, &harris_min_rsp, &harris_max_rsp, , , Mat());
namedWindow(harris_win, CV_WINDOW_AUTOSIZE);
createTrackbar("Quality Value:", harris_win, &qualityLevel, max_count, CustomHarris_Demo);
CustomHarris_Demo(, ); // 计算最小特征值
shiTomasiRsp = Mat::zeros(src.size(), CV_32FC1);
cornerMinEigenVal(gray_src, shiTomasiRsp, blockSize, ksize, );
minMaxLoc(shiTomasiRsp, &shitomasi_min_rsp, &shitomasi_max_rsp, , , Mat());
namedWindow(shitomasi_win, CV_WINDOW_AUTOSIZE);
createTrackbar("Quality:", shitomasi_win, &sm_qualitylevel, max_count, CustomShiTomasi_Demo);
CustomShiTomasi_Demo(, ); waitKey();
return ;
} void CustomHarris_Demo(int, void*) {
if (qualityLevel < ) {
qualityLevel = ;
}
Mat resultImg = src.clone();
float t = harris_min_rsp + (((double)qualityLevel) / max_count)*(harris_max_rsp - harris_min_rsp);
for (int row = ; row < src.rows; row++) {
for (int col = ; col < src.cols; col++) {
float v = harrisRspImg.at<float>(row, col);
if (v > t) {
circle(resultImg, Point(col, row), , Scalar(, , ), , , );
}
}
} imshow(harris_win, resultImg);
} void CustomShiTomasi_Demo(int, void*) {
if (sm_qualitylevel < ) {
sm_qualitylevel = ;
} Mat resultImg = src.clone();
float t = shitomasi_min_rsp + (((double)sm_qualitylevel) / max_count)*(shitomasi_max_rsp - shitomasi_min_rsp);
for (int row = ; row < src.rows; row++) {
for (int col = ; col < src.cols; col++) {
float v = shiTomasiRsp.at<float>(row, col);
if (v > t) {
circle(resultImg, Point(col, row), , Scalar(, , ), , , );
}
}
}
imshow(shitomasi_win, resultImg);
}

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; Mat src,src_gray; int max_corners = ;
int max_count = ; const char* output_title = "SubPix Result"; void SubPixel_demo(int,void*); int main(int argc, char** argv)
{
src = imread("数字.jpg");
if (src.empty()) {
printf("Can not load Image...");
return -;
}
imshow("input Image",src); cvtColor(src, src_gray, COLOR_BGR2GRAY); namedWindow(output_title,CV_WINDOW_AUTOSIZE);
createTrackbar("Corners:", output_title,&max_corners, max_count, SubPixel_demo);
SubPixel_demo(,); waitKey();
return ;
} void SubPixel_demo(int, void*)
{
if (max_corners < ) max_corners = ; //先进行Shi-Tomasi角点检测
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = ;
int blockSize = ;
goodFeaturesToTrack(src_gray, corners,max_corners,qualityLevel,minDistance,Mat());
cout << "number of corners:" << corners.size() << endl; //画出角点
Mat resultImage = src.clone();
for (size_t t = ; t < corners.size(); t++)
{
circle(resultImage, corners[t],,Scalar(,,),,,);
} imshow(output_title, resultImage); Size winSize = Size(,);
Size zerozone = Size(-, -);
TermCriteria tc = TermCriteria(TermCriteria::EPS+ TermCriteria::MAX_ITER,,0.001);//最大值迭代次数40,精度半径0.001
cornerSubPix(src_gray, corners, winSize, zerozone, tc);//corners需要输入初始坐标,然后输出精确坐标(因此前面才会先做Shi—Tomasi)
for (size_t t = ; t < corners.size(); t++)
{
cout << (t + ) << "Point(x,y):" << corners[t].x << "," << corners[t].y << endl;
}
}

OpenCV——Harris、Shi Tomas、自定义、亚像素角点检测的更多相关文章

  1. 寻找Harris、Shi-Tomasi和亚像素角点

    Harris.Shi-Tomasi和亚像素角点都是角点,隶属于特征点这个大类(特征点可以分为边缘.角点.斑点). 一.Harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性较高,但是也可能出 ...

  2. OpenCV亚像素角点cornerSubPixel()源代码分析

    上一篇博客中讲到了goodFeatureToTrack()这个API函数能够获取图像中的强角点.但是获取的角点坐标是整数,但是通常情况下,角点的真实位置并不一定在整数像素位置,因此为了获取更为精确的角 ...

  3. OpenCV探索之路(十五):角点检测

    角点检测是计算机视觉系统中用来获取图像特征的一种方法.我们都常说,这幅图像很有特点,但是一问他到底有哪些特点,或者这幅图有哪些特征可以让你一下子就识别出该物体,你可能就说不出来了.其实说图像的特征,你 ...

  4. opencv学习之路(32)、角点检测

    一.角点检测的相关概念 二.Harris角点检测——cornerHarris() 参考网址: http://www.cnblogs.com/ronny/p/4009425.html #include ...

  5. OpenCV 之 角点检测

    角点 (corners) 的定义有两个版本:一是 两条边缘的交点,二是 邻域内具有两个主方向的特征点. 一般而言,角点是边缘曲线上曲率为极大值的点,或者 图像亮度发生剧烈变化的点.例如,从人眼角度来看 ...

  6. 【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测

    角点 特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系.点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(k ...

  7. Harris角点及Shi-Tomasi角点检测(转)

    一.角点定义 有定义角点的几段话: 1.角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测.图像匹配.视频跟踪.三维建模和目标识别等领域中.也 ...

  8. 角点检测:Harris角点及Shi-Tomasi角点检测

    角点 特征检测与匹配是Computer Vision 应用总重要的一部分,这需要寻找图像之间的特征建立对应关系.点,也就是图像中的特殊位置,是很常用的一类特征,点的局部特征也可以叫做“关键特征点”(k ...

  9. OpenCV亚像素级的角点检测

    亚像素级的角点检测 目标 在本教程中我们将涉及以下内容: 使用OpenCV函数 cornerSubPix 寻找更精确的角点位置 (不是整数类型的位置,而是更精确的浮点类型位置). 理论 代码 这个教程 ...

随机推荐

  1. Java - HashCode源码解析

    Java提高篇(二六)-----hashCode hashCode的作用 要想了解一个方法的内在原理,我们首先需要明白它是干什么的,也就是这个方法的作用.在讲解数组时(java提高篇(十八)----- ...

  2. Linux常用基本命令wc-统计文件的字节,字符,行数

    wc命令 作用:统计文件的字节,单词,行数 用法:wc [option] [file] -c:统计字节 ghostwu@dev:~/linux/uniq$ cat ghostwu.txt 192.16 ...

  3. 设计模式原则(4)--Interface Segregation Principle(ISP)--接口隔离原则

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.定义: 使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 2.使用场景: 类A ...

  4. 【读书笔记】iOS-iOS定位

    iOS提供3种不同的定位途径: 1,WiFi定位,通过查询一个WiFi路由器的地理位置信息,比较省电:iPhone,iPod touch和iPad都可以采用: 2,蜂窝式移动电话基站定位,通过移动运营 ...

  5. 使用Apache php 的一些基本操作(一)

    切换目录命令:(就可以在www文件夹里面操作了) cd /var/www/html 新建一个文件: sudo vim info.php (这里出现了一个问题,sudo: vim: command no ...

  6. gis cad导出弧段在arcmap下 不准问题

    我发现cad 的图形导出到arcmap下会出现各种各样的丢失问题,特别是cad的弧段在arcmap下会弯曲(弧度指向另外一边). 那么应该怎么解决这个问题呢?后来想到FME可以高效的还原cad的图形, ...

  7. 安卓测试【一】android sdk环境变量配置

    移动应用自动化测试的配置,先于官网下载Android SDK,然后配置环境变量. 配置android sdk环境变量 1.  新建ANDROID_HOME环境变量,变量值为SDK解压的路径 2. 追加 ...

  8. JSP隐含对象

    1.out隐含对象 (输出对象) 直接用于在JSP页面输出内容 javax.servlet.jsp.JspWriter(抽象类) 继承自java.io.Writer JSP中的out对象最终被转化成s ...

  9. 《JavaScript面向对象编程指南》

    第一章.引言 1.5 面向对象的程序设计常用概念 对象(名词):是指"事物"在程序设计语言中的表现形式. 这里的事物可以是任何东西,我们可以看到它们具有某些明确特征,能执行某些动作 ...

  10. Visual Studio Code配置JavaScript环境

    一·下载并安装Node.js/Visual Studil Code 下载对应你系统的Node.js版本:https://nodejs.org/en/download/ 选安装目录进行安装 环境配置 · ...