SUSAN角点检测与匹配算法

  • 测试环境Ubuntu+OpenCV2.4.3
  • SUSAN角点检测代码

SUSAN(Small univalue segment assimilating nucleus)是一种基于灰度图像以及窗口模板的 特征点获取方法,适用于图像中边缘和角点的检测,对噪声鲁棒,而且具有简单、有效、计算速度快等特点。本文结合SUSAN算法原理, 实现SUSAN角点检测,并结合 Brief描述子,实现 角点匹配算法。话不多说,直接上代码,代码有详细的注释!后面还有相应的论文,感兴趣的可以深入研究一下。

测试环境Ubuntu+OpenCV2.4.3

ubuntu下安装OpenCV的过程可以参考这篇博客。其他的版本可能会有一些问题,但是应该可以按照代码的思路简单解决。

SUSAN角点检测代码

#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/legacy/legacy.hpp"
#include <iostream>
using namespace std;
using namespace cv;
void  MySusan(Mat imageGray, vector<Point2f>& corners);int main(int argc, char **argv)
{Mat image1 = imread("../image/1.jpg", 1);//读取图像Mat image2 = imread("../image/2.jpg", 1);//读取图像Mat imageGray1,imageGray2;cvtColor(image1,imageGray1,CV_RGB2GRAY);//将彩色图转化为灰度图cvtColor(image2,imageGray2,CV_RGB2GRAY);//将彩色图转化为灰度图IplImage  pBinary1 = image1,pBinary2 = image2;  IplImage *input1 = cvCloneImage(&pBinary1);//转化为iplpmage类型指针IplImage *input2 = cvCloneImage(&pBinary2);//转化为iplpmage类型指针vector<Point2f> corners1,corners2;     //角点vector<KeyPoint> keypoints1,keypoints2;        //关键点MySusan(imageGray1, corners1);MySusan(imageGray2, corners2);CvScalar color1 =CV_RGB(255,0,0);CvScalar color2 =CV_RGB(0,255,0);for(int i=0;i<corners1.size();i++){cvCircle(input1, cvPoint((int)(corners1[i].x), (int)(corners1[i].y)), 2, color1, 1, CV_AA, 0);//圈出角点}for(int i=0;i<corners2.size();i++){cvCircle(input2, cvPoint((int)(corners2[i].x), (int)(corners2[i].y)), 2, color2, 1, CV_AA, 0);//圈出角点}KeyPoint::convert(corners1,keypoints1);KeyPoint::convert(corners2,keypoints2);//特征点描述,为下边的特征点匹配做准备
//    SiftDescriptorExtractor SiftDescriptor;BriefDescriptorExtractor  Descriptor;Mat imageDesc1, imageDesc2;Descriptor.compute(imageGray1,keypoints1 , imageDesc1);Descriptor.compute(imageGray2, keypoints2, imageDesc2);BruteForceMatcher< L2<float> > matcher;
//  FlannBasedMatcher< L2<float> > matcher;vector<vector<DMatch> > matchePoints;vector<DMatch> GoodMatchePoints;matcher.knnMatch(imageDesc2, imageDesc1, matchePoints,2);//获取两个最优匹配点,在imageDesc2中找imageDesc1的2个最佳匹配点cout << "total match points: " << matchePoints.size() << endl;// Lowe's algorithm,获取优秀匹配点for (int i = 0; i < matchePoints.size(); i++){if (matchePoints[i][0].distance < 0.4 * matchePoints[i][1].distance){GoodMatchePoints.push_back(matchePoints[i][0]);}}cout << "GoodMatchePoints: " << GoodMatchePoints.size() << endl;Mat first_match;drawMatches(image2, keypoints2, image1, keypoints1, GoodMatchePoints, first_match);imshow("first_match ", first_match);imwrite("first_match.jpg", first_match);//     cout<<"corners1.size="<<corners1.size()<<endl;
//     cout<<"corners2.size="<<corners2.size()<<endl;
//     imshow("imageBefore1",image1);
//     cvShowImage("imageAfter1",input1);
//     cvSaveImage( "ImageAfter1.jpg", input1);
//     imshow("imageBefore2",image2);
//     cvShowImage("imageAfter2",input2);
//     cvSaveImage( "ImageAfter2.jpg", input2);waitKey();return 0;
}//susan角点检测
//输入灰度图,输出角点
void  MySusan(Mat imageGray, vector<Point2f>& corners)
{ long int Imagewidth=imageGray.cols;long int Imageheight=imageGray.rows;//得到图像高宽cout<<"Imagewidth="<<Imagewidth<<"      Imageheight=" <<Imageheight<<endl;int threshold = 50;       //判断灰度相近的阈值(可调)long int i,j,c=0,u=0,g=0,max=0;int usan[(Imagewidth-6)*(Imageheight-6)]; // 当前像素和窗体内像素差别在t以下的个数,即相似的个数(一维)int imgn[Imageheight-6][Imagewidth-6];  // 当前像素和窗体内像素差别在t以下的个数,即相似的个数(二维)uchar *p1,*p2,*p3;//  计算以像素为中心的窗体内包含的
//  包含37个像素的圆窗口,面积为12*pi=37,因此是以sqrt(12)为半径的原
//  没有在外围扩展图像,最终图像会缩小for(i=3;i<Imageheight-3;i++)  {p1=imageGray.ptr<uchar>(i);for(j=3;j<Imagewidth-3;j++)  {  //从原图中截取7*7的区域再在其中挑选圆窗Rect rect(j-3, i-3, 7,7);Mat image_tmp = imageGray(rect);//c表示灰度值相近的程度,越大越相近c=0;for(int p=0;p<7;p++){p2=image_tmp.ptr<uchar>(p);for(int q=0;q<7;q++){//在7*7的区域中选取圆窗包含的像素if((pow(p-3,2)+pow(q-3,2))<=12){// 判断灰度是否相近,t是自己设置的if(abs(p1[j]-p2[q])<=threshold){c++;    }}}     }usan[u++]=c;}}cout<<"usansize="<<(Imagewidth-6)*(Imageheight-6)<<endl;for(i=0;i<(Imagewidth-6)*(Imageheight-6);i++){if(usan[i]>g)   g=usan[i];     //找最大值}
//     相当于进一步调整阈值,在threshold的基础上进一步减少角点个数g=0.5*g;   //g通常取max/2for(i=0;i<(Imagewidth-6)*(Imageheight-6);i++){if(usan[i]<g)   usan[i]=g-usan[i];elseusan[i]=0;}for(i=0;i<Imageheight-6;i++){for(j=0;j<Imagewidth-6;j++){imgn[i][j]=usan[i*(Imagewidth-6)+j];}}
//    非极大抑制//3*3 for(i=1;i<Imageheight-7;i++){for(j=1;j<Imagewidth-7;j++){if(imgn[i][j]>imgn[i-1][j-1]&&imgn[i][j]>imgn[i-1][j]&&imgn[i][j]>imgn[i-1][j+1]&&imgn[i][j]>imgn[i][j-1]&&imgn[i][j]>imgn[i][j+1]&&imgn[i][j]>imgn[i+1][j-1]&&imgn[i][j]>imgn[i+1][j]&&imgn[i][j]>imgn[i+1][j+1]){corners.push_back(cvPoint(j+3,i+3));//之前是从第3行3列开始检测的,这里加上3}}}
}

Paper: SUSAN — A New Approach to Low Level Image Processing

SUSAN角点检测与匹配算法代码(OpenCV)相关推荐

  1. OpenCV与图像处理学习十三——Harris角点检测(含代码)

    OpenCV与图像处理学习十三--Harris角点检测(含代码) 一.角点的概念 二.Harris角点检测的实现过程 三.Harris代码应用 一.角点的概念 角点: 在现实世界中, 角点对应于物体的 ...

  2. SUSAN角点检测实现

    参考:Susan角点检测python实现 (边缘检测.角点检测.重心计算.非极大值抑制) void susan(cv::Mat& src, cv::Mat& dst, float t) ...

  3. Susan角点检测python实现 (边缘检测、角点检测、重心计算、非极大值抑制)

    Susan角点检测(边缘检测.角点检测.重心计算.非极大值抑制) 写在前面 黄宁然--看过你看过的算法,觉得好难. 参考文献镇楼 [1]https://blog.csdn.net/tostq/arti ...

  4. 基于光强的角点检测(SUSAN角点检测、FAST角点检测、FAST-ER角点检测)

    Corner Feature Detector(Intensity-Based) 基于光强比较的角点检测,直接比较光强(像素灰度值),而不计算梯度.所以实时性更好,所需的存储空间更小. SUSAN 角 ...

  5. susan角点检测算法

    SUSAN算法是1997年牛津大学的Smith等人提出的一种处理灰度图像的方法,它主要是用来计算图像中的角点特征.SUSAN算法选用圆形模板(如图1所示).将位于圆形窗口模板中心等待检测的像素点称为核 ...

  6. SUSAN角点检测算法实现(详细版)

    前言 无 一.SUSAN算子是什么? SUSAN ( Small univalue segment assimilating nucleus) 算子是一种基于灰度的特征点获取方法, 适用于图像中边缘和 ...

  7. SUSAN角点检测算法,及其Matlab实现

    1.SUSAN角点检测算法步骤 (1)在图像上放置一个37个像素的圆形模板,模板在图像上滑动,依次比较模板内各个像素点的灰度与模板核的灰度,判断是否属于USAN区域.判别函数如下: 其中,r⃗0{{\ ...

  8. 图像局部特征学习(笔记1之SUSAN角点检测)

    SUSAN(smallest univalue segment assimilating nucleus最小核值相似区) SUSAN是角点检测的一种,其原理跟Harris很相像,Harris是利用一个 ...

  9. harris角点检测c语言程序,Harris角点检测学习(示例代码)

    1.角点的定义与性质 角点是一种局部特征,具有旋转不变性和不随光照条件变化而变化的特点,一般将图像中曲率足够高或者曲率变化明显的点作为角点.检测得到的角点特征通常用于图像匹配.目标跟踪.运动估计等方面 ...

最新文章

  1. 学习java技术有前途吗
  2. 败家玩意儿!Redis 竟然浪费了这么多内存!
  3. The Innovation | Volume 2 Issue3 正式出版
  4. bat脚本登陆ftp服务器
  5. Openstack部署总结:“部署过程Error: Local ip for ovs agent must be set when tunneling is enabled”问题...
  6. 跟我一起学编程—《Scratch编程》第21课:打地鼠
  7. 如何在命令提示符下编译运行含有Package的java文件
  8. 校验金额、大小写字母、大写字母、合法uri、email
  9. Azure 上的网站如何识别不同国家和地区的用户
  10. yii2 调用未定义函数_Python 函数(三) 使用规则
  11. Java学习笔记1.1.1 搭建Java开发环境 - Java概述
  12. 周报(2017.3.19-3.16)
  13. 第一:MySQL+MyBatis实现对测试用例数据的读取(接口自动化落地)
  14. oracle out of bounds,如何通过不具有ArrayIndexOutOfBoundsException的executeBatch获取生成的键?...
  15. java mysql字符串拼接_Oracle与MySQL字符串拼接
  16. Win10命令提示符在哪里 怎么打开命令提示符窗口
  17. CatBoost快速入门
  18. TYPORA主题更换
  19. android格式化外置u盘,Android5.x+ 格式化外部存储(u盘, sdcard)的方法
  20. 企业微信中授权小程序

热门文章

  1. 连锁酒店网络互联解决方案
  2. 17开头的是什么号码?为什么17开头手机号最好不要用
  3. Linux常见压缩工具
  4. 【AUTOSAR】【以太网】 EthIf
  5. Cris 学 SpringMVC(二):使用 servlet 原生 api 作为方法入参
  6. linux下kegg注释软件,工具篇丨GO和KEGG富集不到通路?快试试这个超赞的功能分析工具吧...
  7. python练习题:英汉字典
  8. Java流程控制之do....while 循环的详解,看完你就会
  9. if,while选择结构和while,dowhile,for循环的使用
  10. 关于oracle数据库死锁的解决 以及产生的原因