opencv学习之路(32)、角点检测
一、角点检测的相关概念



二、Harris角点检测——cornerHarris()

参考网址: http://www.cnblogs.com/ronny/p/4009425.html

#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main()
{
Mat img = imread("E://3.jpg");
imshow("src", img);
Mat result = img.clone();
Mat gray, dst , corner_img;//corner_img存放检测后的角点图像
cvtColor(img, gray, CV_BGR2GRAY); cornerHarris(gray, corner_img, , , 0.04);//cornerHarris角点检测
//imshow("corner", corner_img);
threshold(corner_img, dst, 0.015, , CV_THRESH_BINARY);
imshow("dst", dst); int rowNumber = gray.rows; //获取行数
int colNumber = gray.cols; //获取每一行的元素
cout << rowNumber << endl;
cout << colNumber << endl;
cout << dst.type() << endl; for (int i = ; i<rowNumber; i++)
{
for (int j = ; j<colNumber; j++)
{
if (dst.at<float>(i, j) == )//二值化后,灰度值为255为角点
{
circle(result, Point(j, i),, Scalar(, , ), , );
}
}
} imshow("result", result);
waitKey();
}

浅墨代码
http://blog.csdn.net/poem_qianmo/article/details/29356187
#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; #define WINDOW_NAME1 "【程序窗口1】"
#define WINDOW_NAME2 "【程序窗口2】"
Mat g_srcImage, g_srcImage1, g_grayImage;
int thresh = ; //当前阈值
int max_thresh = ; //最大阈值 void on_CornerHarris(int, void*)
{
Mat dstImage;//目标图
Mat normImage;//归一化后的图
Mat scaledImage;//线性变换后的八位无符号整型的图 //初始化:置零当前需要显示的两幅图,即清除上一次调用此函数时他们的值
dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
g_srcImage1 = g_srcImage.clone(); //进行角点检测
cornerHarris(g_grayImage, dstImage, , , 0.04);
// 归一化与转换
normalize(dstImage, normImage, , , NORM_MINMAX, CV_32FC1, Mat());
convertScaleAbs(normImage, scaledImage);//将归一化后的图线性变换成8位无符号整型 // 进行绘制:将检测到的,且符合阈值条件的角点绘制出来
for (int j = ; j < normImage.rows; j++)
{
for (int i = ; i < normImage.cols; i++)
{
if ((int)normImage.at<float>(j, i) > thresh + )
{
circle(g_srcImage1, Point(i, j), , Scalar(, , ), , , );
circle(scaledImage, Point(i, j), , Scalar(, , ), , , );
}
}
}
imshow(WINDOW_NAME1, g_srcImage1);
imshow(WINDOW_NAME2, scaledImage); } static void ShowHelpText()
{
printf("\n\n\n\t\t\t【欢迎来到Harris角点检测示例程序~】\n\n");
printf("\n\n\n\t请调整滚动条观察图像效果~\n\n");
printf("\n\n\t\t\t\t\t\t\t\t by浅墨");
} void main()
{
system("color 3F");
ShowHelpText(); //载入原始图并进行克隆保存
g_srcImage = imread("E://1.jpg", );
if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return ; }
imshow("原始图", g_srcImage);
g_srcImage1 = g_srcImage.clone();
cvtColor(g_srcImage1, g_grayImage, CV_BGR2GRAY); //创建窗口和滚动条
namedWindow(WINDOW_NAME1, CV_WINDOW_NORMAL);
createTrackbar("阈值: ", WINDOW_NAME1, &thresh, max_thresh, on_CornerHarris);
on_CornerHarris(, );//调用一次回调函数,进行初始化 waitKey();
}

三、Shi-Tomasi角点检测——goodFeaturesToTrack()


#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main()
{
Mat src = imread("E://0.jpg");
imshow("src", src);
Mat result = src.clone();
Mat gray;
cvtColor(src, gray,CV_BGR2GRAY); vector<Point2f>corners;//Point2f类型的向量:存储每个角点的坐标
//输入图,向量,最大角点数量,角点的最小特征值,角点间最小距离,掩码(Mat()表示掩码为空),blocksize,是否使用Harris角点检测,权重系数
goodFeaturesToTrack(gray, corners, ,0.01,,Mat(),,false,0.04);
cout << "角点数量" << corners.size() << endl; //画圆标注角点
for (int i = ; i < corners.size(); i++)
circle(result, corners[i], , Scalar(, , ),,);
imshow("result", result);
waitKey();
}

浅墨大神代码(加了滑动条效果)
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std; #define WINDOW_NAME "【Shi-Tomasi角点检测】"
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = ;
int g_maxTrackbarNumber = ;
RNG g_rng();//初始化随机数生成器 //-----------------------------【on_GoodFeaturesToTrack( )函数】----------------------------
// 描述:响应滑动条移动消息的回调函数
//----------------------------------------------------------------------------------------------
void on_GoodFeaturesToTrack(int, void*)
{
//【1】对变量小于等于1时的处理
if (g_maxCornerNumber <= ) { g_maxCornerNumber = ; } //【2】Shi-Tomasi算法(goodFeaturesToTrack函数)的参数准备
vector<Point2f> corners;
double qualityLevel = 0.01;//角点检测可接受的最小特征值
double minDistance = ;//角点之间的最小距离
int blockSize = ;//计算导数自相关矩阵时指定的邻域范围
double k = 0.04;//权重系数
Mat copy = g_srcImage.clone(); //复制源图像到一个临时变量中,作为感兴趣区域 //【3】进行Shi-Tomasi角点检测
goodFeaturesToTrack(g_grayImage,//输入图像
corners,//检测到的角点的输出向量
g_maxCornerNumber,//角点的最大数量
qualityLevel,//角点检测可接受的最小特征值
minDistance,//角点之间的最小距离
Mat(),//感兴趣区域
blockSize,//计算导数自相关矩阵时指定的邻域范围
false,//不使用Harris角点检测
k);//权重系数 //【4】输出文字信息
cout << "\t>此次检测到的角点数量为:" << corners.size() << endl; //【5】绘制检测到的角点
int r = ;
for (int i = ; i < corners.size(); i++)
{
//以随机的颜色绘制出角点
circle(copy, corners[i], r, Scalar(g_rng.uniform(, ), g_rng.uniform(, ),
g_rng.uniform(, )), -, , );
} //【6】显示(更新)窗口
imshow(WINDOW_NAME, copy);
} static void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");
printf("\n\n\t\t\t此为本书OpenCV2版的第87个配套示例程序\n");
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
printf("\n\n ----------------------------------------------------------------------------\n");
//输出一些帮助信息
printf("\n\n\n\t欢迎来到【Shi-Tomasi角点检测】示例程序\n");
printf("\n\t请调整滑动条观察图像效果\n\n"); } void main()
{
system("color 2F");
ShowHelpText(); //【1】载入源图像并将其转换为灰度图
g_srcImage = imread("3.jpg", );
cvtColor(g_srcImage, g_grayImage, CV_BGR2GRAY); //【2】创建窗口和滑动条,并进行显示和回调函数初始化
namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);
createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
imshow(WINDOW_NAME, g_srcImage);
on_GoodFeaturesToTrack(, ); waitKey();
}
由于VS2015和opencv2有些兼容问题,会出现断言错误(具体原因在上一篇博客有讲),这里就不贴效果图了。
四、亚像素角点检测——cornerSubPix()

#include "opencv2/opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv; void main()
{
Mat img = imread("E://2.jpg");
imshow("src", img);
Mat result = img.clone();
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY); //Shi-Tomasi角点检测
vector<Point2f> corners;
goodFeaturesToTrack(gray, corners, , 0.01, , Mat(), , false, 0.04);
cout << "角点数量" << corners.size() << endl; for (int i = ; i<corners.size(); i++)
{
cout << "像素坐标:(" << corners[i].x << ", " << corners[i].y << ")" << endl;
circle(result, corners[i], , Scalar(, , ), , );
}
imshow("result", result); Size winSize = Size(, );
Size zeroZone = Size(-, -);
//精度或最大迭代数目,其中任意一个达到 迭代次数40,精度0.001
TermCriteria criteria = TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, , 0.001);
cornerSubPix(gray, corners, winSize, zeroZone, criteria); for (int j = ; j<corners.size(); j++)
{
cout << "亚像素坐标:(" << corners[j].x << ", " << corners[j].y << ")" << endl;
circle(img, corners[j], , Scalar(, , ), -, );
}
imshow("subPix", img); waitKey();
}

opencv学习之路(32)、角点检测的更多相关文章
- 【OpenCV文档】用于角点检测的Fast算法
原文地址:http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_fast/py_fast.html#fast-algorithm- ...
- OpenCV亚像素级的角点检测
亚像素级的角点检测 目标 在本教程中我们将涉及以下内容: 使用OpenCV函数 cornerSubPix 寻找更精确的角点位置 (不是整数类型的位置,而是更精确的浮点类型位置). 理论 代码 这个教程 ...
- opencv学习之路(37)、运动物体检测(二)
一.运动物体轮廓椭圆拟合及中心 #include "opencv2/opencv.hpp" #include<iostream> using namespace std ...
- opencv学习之路(36)、运动物体检测(一)
一.简介 二.背景减法 图片说明 #include "opencv2/opencv.hpp"using namespace cv; void main() { Mat img1 = ...
- opencv学习之路(35)、SURF特征点提取与匹配(三)
一.简介 二.opencv中的SURF算法接口 三.特征点匹配方法 四.代码 1.特征点提取 #include "opencv2/opencv.hpp" #include < ...
- OpenCV 学习笔记03 直线和圆检测
检测边缘和轮廓不仅重要,还经常用到,它们也是构成其他复杂操作的基础. 直线和形状检测与边缘和轮廓检测有密切的关系. 霍夫hough 变换是直线和形状检测背后的理论基础.霍夫变化是基于极坐标和向量开展的 ...
- Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练
在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资 ...
- opencv学习之路(41)、人脸识别
一.人脸检测并采集个人图像 //take_photo.cpp #include<opencv2/opencv.hpp> using namespace cv; using namespac ...
- opencv学习之路(34)、SIFT特征匹配(二)
一.特征匹配简介 二.暴力匹配 1.nth_element筛选 #include "opencv2/opencv.hpp" #include <opencv2/nonfree ...
随机推荐
- 源码编译vim
目录 获取最新版 vim 源码 1 git仓库clone 2, 源码包下载,里面有各个版本的vim压缩包 vim 配置选项 配置示例 参考文章 tip 获取最新版 vim 源码 1 git仓库clon ...
- JavaScript关于md5加密
/*中文加密 *181009 * */ function md5(string) { var x = Array(); var k, AA, BB, CC, DD, a, b, c, d; var S ...
- Spring Cloud 之Eureka(一)
简介 Eureka是Spring cloud 的基本套件之一,是基于Netflix 的Eureka做的二次封装,主要是负责完成微服务架构中的服务治理功能.它是微服务架构中最为核心和基础的模块,它主要是 ...
- volatile有什么用?能否用一句话描述volatile的应用场景
volatile保证内存可见性和禁止指令重排.volatile用于多线程环境下的单次操作(单次读或者单次写).volatile关键字不能提供原子性. volatile关键字为实例域的同步访问提 ...
- vue 基础的一些字眼及路由
每个框架都有一些自己的写法和一些字眼 摘自 vue 官网 v-bind 缩写 <!-- 完整语法 --> <a v-bind:href="url">...& ...
- web中spring框架启动流程第一发
web.xml中springmvc相关配置如下:<servlet> <servlet-name>springmvc</servlet-name> <servl ...
- 于用cocoapods添加第三方库,并且cocoapods添加成功,但是却在任何一个文件上都导入不了头文件
关于用cocoapods添加第三方库,并且cocoapods添加成功,但是却在任何一个文件上都导入不了头文件,而且根本没有提示,即使手动打#import "xxxx.h"也报错xx ...
- E. Neko and Flashback
传送门: 题意:假定我们已知a[]={3,4,6,5,7}, 那么b[]通过min(a[i],a[i+1])得到 那么b[]={3,4,5,5}, c[]通过max(a[i],a[i+1])得到 c ...
- JavaScript 当前URL取参返回字典
getParam : function(){ return (key, strURL = window.location.search) => new RegExp("(^|\\?|& ...
- java基础语法(三大基础)
一.标识符 标识符是用于包名.类名.变量名.方法名.对象名.数组名.集合名等的命名: 规则: (1)可以使用英文字母.阿拉伯数字.下划线_.$符号 (2)不能以数字开头 (3)不能使用Java中的 ...