SUSAN USAN C++ OPENCV
前日晚上导师布置了一个新作业:
了解角点检测原理,并实现SUSAN角点检测算法。自己昨天赶忙上网搜索资料,寻找相关的代码,在自己的一番努力下,终于捣鼓出来了,下面就直接贴出代码,以供大家参考。
SUSAN角点简介
SUSAN算法是1997年牛津大学的Smith等人提出的一种处理灰度图像的方法,它主要是用来计算图像中的角点特征。本人在实际运行中效果并不是特别好,猜测可能是 thresholdthresholdthreshold,ggg 值的选择有问题,待本人后续多进行几次测试,再给出准确的解答。
SUSAN角点实现
上图为我们寻找灰度相似的矩阵所用的 MaskMaskMask,如果Mask内有与中心像素灰度值相似的像素,则将其寻找出来,具体函数如下所示:
c(r,r0)=1,if∣I(r)+I(r0)∣<=thresholdc(r, r_0)=1,\quad if\quad |I(r)+I(r_0)|<=thresholdc(r,r0)=1,if∣I(r)+I(r0)∣<=threshold
c(r,r0)=0,if∣I(r)+I(r0)∣>thresholdc(r, r_0)=0,\quad if\quad |I(r)+I(r_0)|>thresholdc(r,r0)=0,if∣I(r)+I(r0)∣>threshold
接下来统计 MaskMaskMask内与中心像素灰度相似的像素的个数,具体函数如下:
n(r0)=∑r∈D(r0)c(r,r0)n(r_0)=\sum_{r\in D(r_0)}c(r, r_0)n(r0)=r∈D(r0)∑c(r,r0)
其中,D(r0)D(r_0)D(r0) 表示以 r0r_0r0 为中心的圆形Mask区域。
得到 n(r0)n(r_0)n(r0) 后,根据其数量我们可以进行判断,如下图所示(这里假设图像为二值图像):
1、n(r0)=36n(r_0)=36n(r0)=36,所以此中心点属于背景或者目标区域。
1、18<n(r0)<3618<n(r_0)<3618<n(r0)<36,所以此中心点可能属于背景或者目标区域的角点。
1、n(r0)=18n(r_0)=18n(r0)=18,所以此中心点属于背景或者目标区域的边缘。
1、0<n(r0)<180<n(r_0)<180<n(r0)<18,所以此中心点可能属于背景或者目标区域的角点。
在实际过程中,我们会在这里认为设置一个阈值 ggg,大小为 n(r0)n(r_0)n(r0) 最大值的一半左右。
最后,我们还需要进行非极大值抑制,目的是取出具有代表性的角点,剔除掉那些不具有代表性的点。
SUSAN角点代码
void My_SUSAN(Mat& src, Mat& dst)
{if (src.empty()){std::cout << "Failed to open file!!!" << std::endl;}//用来存储转换后的灰度图Mat grayImg;//copy原图像,用来显示角点dst = src.clone();cvtColor(src, grayImg, COLOR_BGR2GRAY);//模版 x 和 y的坐标的偏移量int OffSetX[37] ={-3, -3, -3,-2, -2, -2, -2, -2,-1, -1, -1, -1, -1, -1, -1,0, 0, 0, 0, 0, 0, 0,1, 1, 1, 1, 1, 1, 1,2, 2, 2, 2, 2,3, 3, 3};int OffSetY[37] ={-1, 0, 1,-2, -1, 0, 1, 2,-3, -2, -1, 0, 1, 2, 3,-3, -2, -1, 0, 1, 2, 3,-3, -2, -1, 0, 1, 2, 3,-2, -1, 0, 1, 2,-1, 0, 1};用来寻找最适合阈值//int max = 0, min = 255;//for (int i = 0; i < grayImg.rows; i++)//{// for (int j = 0; j < grayImg.cols; j++)// {// if (grayImg.at<uchar>(i, j) > max)// {// max = grayImg.at<uchar>(i, j);// }// if (grayImg.at<uchar>(i, j) < min)// {// min = grayImg.at<uchar>(i, j);// }// }//}//std::cout << "Max gray: " << max << std::endl;//std::cout << "Min gray: " << min << std::endl;//int threshold = (max - min) / 10;//可选取其他方法//定义USAN中近似像素数量的阈值,g越小,角点挑选越苛刻,角点数量越少int t=25;int g = 18;int val = 0;Mat grayImg_padded;//对灰度图像进行填充copyMakeBorder(grayImg, grayImg_padded, 3, 3, 3, 3, BORDER_REFLECT);for (int i = 3; i < grayImg_padded.rows - 3; i++){for (int j = 3; j < grayImg_padded.cols - 3; j++){//same表示近似像素的数量int same = 0;int sum = 0;for (int k = 0; k < 37; k++){if (abs(grayImg_padded.at<uchar>(i + OffSetX[k], j + OffSetY[k]) - grayImg_padded.at<uchar>(i, j)) < t)same++;}if (same > val){val = same;}//g值可改 if (same < g){grayImg_padded.at<uchar>(i, j) = g - same;}else{grayImg_padded.at<uchar>(i, j) = 0;}}}std::cout << val << std::endl;//非极大值抑制int x[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };int y[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };for (int i = 3; i < grayImg_padded.rows - 3; i++){for (int j = 3; j < grayImg_padded.cols - 3; j++){int flag = 0;for (int k = 0; k < 8; k++){if (grayImg_padded.at<uchar>(i, j) <= grayImg_padded.at<uchar>(i + x[k], j + y[k])){//如果邻域内存在近似像素的值比中心位置的近似像素的值高,则进行极大值抑制flag = 1;break;}}if (flag == 0){//在原图像中的角点位置做标记//绘制横线line(dst, Point(j - 9, i - 3), Point(j + 3, i - 3), Scalar(255, 0, 255), 2, 8);//绘制竖线line(dst, Point(j - 3, i - 9), Point(j - 3, i + 3), Scalar(255, 0, 255), 2, 8);//grayImg_padded.at<uchar>(i, j) = 255;}/*else{grayImg_padded.at<uchar>(i, j) = 0;}*/}}
}
SUSAN角点结果
输入
1、不进行平滑预处理的检测结果
2、进行高斯平滑(3×3)预处理的检测结果( ttt 和 ggg 的值都没有改变)
由于时间原因,暂时不对SUSAN的原理进行说明,等之后有时间再回来补上……出去办事了,拜拜了,您嘞!
深夜更新,其过程实属不易,不过内容总算是趋于完整。人贵有持,希望大家都能有所收获吧!
————————————————————————————————
2021.09.26更新:
由于源代码测试效果并不是很好,所以在研读了论文之后有了一些思考。
1、对于不同的图片,ttt 和 ggg 都需要进行调整以获取比较好的效果。
2、SUSAN角点对尺度还是比较敏感的,也就是说当一个角被放大后,其可能无法被检测出来。
3、对于某些图片,在做SUSAN检测之前进行适当的平滑滤波,效果会出奇的好。
SUSAN USAN C++ OPENCV相关推荐
- SUSAN角点检测与匹配算法代码(OpenCV)
SUSAN角点检测与匹配算法 测试环境Ubuntu+OpenCV2.4.3 SUSAN角点检测代码 SUSAN(Small univalue segment assimilating nucleus) ...
- SUSAN边缘检测算法,及其Matlab和OpenCV实现
1.SUSAN边缘检测计算步骤 (1)在图像上放置一个37个像素的圆形模板,模板在图像上滑动,依次比较模板内各个像素点的灰度与模板核的灰度,判断是否属于USAN区域.判别函数如下: 其中,r⃗0{{\ ...
- 使用Visual Studio+OpenCV进行的Susan算子边缘检测及数米粒图像处理实验
一.实验内容 用计算机视觉的方法数米粒. 二.实验目的及意义 计算机视觉的应用非常广泛,本实验就是让同学们对计算机视觉技术的应用有一个简单的了解. 1.了解计算机视觉的实验环境.本实验选用的是 VS+ ...
- (原创)基于matlab和c++混合实现的SUSAN特征检测
/ //简述:用MATLAB获取圆周模板,自定义封装susan的特征提取函数(GetUSAN),实现对图像的SUSAN特征检测, // 关于SUSAN特征的原理请参考:https://blog.csd ...
- 图像特征描述子——Susan
1.Susan: SUSAN(Smallest Univalue Segment Assimilating NucleusSUSAN)算子的模板和常规卷积算法的正方形模板不同,它使用一种近似圆形的模板 ...
- 【OpenCV十六新手教程】OpenCV角检测Harris角点检测
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...
- OpenCV角点检测之Harris角点检测
本篇文章中,我们一起探讨了OpenCV中Harris角点检测相关的知识点,学习了OpenCV中实现Harris角点检测的cornerHarris函数的使用方法.此博文一共有两个配套的麻雀虽小但五脏俱全 ...
- susan算子的运用
SUSAN 算法 1997 年英国牛津大学的 S.M.smith 和 J.M.Brady 人提出了一种用于低层次图像 处理的最小核值相似区(即 Smallest Univalue Segment As ...
- opencv角点检测学习总结
学习opencv 角点检测 如果一个点在两个正交方向上都有明显的导数,则我们认为此点更倾向于是独一无二的,所以许多可跟踪的特征点都是角点. 一下为角点检测中用到的一些函数 cvGoodFeatures ...
最新文章
- hive load data inpath 空目录_走近大数据之Hive进阶(一、Hive数据的导入)
- leetcode算法题--增量元素之间的最大差值
- 暴力解决:InvocationException: GraphViz‘s executables not found
- 【软考】2017年11月软件设计师上午真题1-4题答案解析
- 贴片电容耐压值一般都是多少?
- HTML5链接tcpUDP,UDP/TCP协议 网络调试工具源码(C#)
- 【绝对干货】TEASER前传之QUASAR:基于四元数的存在外点Wahba问题的可证明最优解
- 自定义附加属性在XAML中的表示方法以及绑定的注意事项
- 如何优化java反射,如何有效地使用Java反射
- c语言汉诺塔递归算法
- matlab 去除最大值,TRIMMEAN 应用(求去掉最大或和最小值后的平均值的方法)
- android仿美团评论
- 游戏类型英文简称/全称对照表
- 面试必备--手写Promise.all与.race
- 互联网+医疗解决方案
- [leetcode]322. 零钱兑换(Coin Change )C++代码实现
- 王者荣耀:从程序员的角度解密王者荣耀,专业术语把院长看懵了
- 杨绛谈读书:乐在其中,读书好比串门儿
- java 格式化日期到毫秒_关于日期:Java – SimpleDateFormat格式化程序,以毫秒为单位返回纪元时间...
- 认识VF--Visual FoxPro 漫谈