前日晚上导师布置了一个新作业:

  了解角点检测原理,并实现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相关推荐

  1. SUSAN角点检测与匹配算法代码(OpenCV)

    SUSAN角点检测与匹配算法 测试环境Ubuntu+OpenCV2.4.3 SUSAN角点检测代码 SUSAN(Small univalue segment assimilating nucleus) ...

  2. SUSAN边缘检测算法,及其Matlab和OpenCV实现

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

  3. 使用Visual Studio+OpenCV进行的Susan算子边缘检测及数米粒图像处理实验

    一.实验内容 用计算机视觉的方法数米粒. 二.实验目的及意义 计算机视觉的应用非常广泛,本实验就是让同学们对计算机视觉技术的应用有一个简单的了解. 1.了解计算机视觉的实验环境.本实验选用的是 VS+ ...

  4. (原创)基于matlab和c++混合实现的SUSAN特征检测

    / //简述:用MATLAB获取圆周模板,自定义封装susan的特征提取函数(GetUSAN),实现对图像的SUSAN特征检测, // 关于SUSAN特征的原理请参考:https://blog.csd ...

  5. 图像特征描述子——Susan

    1.Susan: SUSAN(Smallest Univalue Segment Assimilating NucleusSUSAN)算子的模板和常规卷积算法的正方形模板不同,它使用一种近似圆形的模板 ...

  6. 【OpenCV十六新手教程】OpenCV角检测Harris角点检测

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

  7. OpenCV角点检测之Harris角点检测

    本篇文章中,我们一起探讨了OpenCV中Harris角点检测相关的知识点,学习了OpenCV中实现Harris角点检测的cornerHarris函数的使用方法.此博文一共有两个配套的麻雀虽小但五脏俱全 ...

  8. susan算子的运用

    SUSAN 算法 1997 年英国牛津大学的 S.M.smith 和 J.M.Brady 人提出了一种用于低层次图像 处理的最小核值相似区(即 Smallest Univalue Segment As ...

  9. opencv角点检测学习总结

    学习opencv 角点检测 如果一个点在两个正交方向上都有明显的导数,则我们认为此点更倾向于是独一无二的,所以许多可跟踪的特征点都是角点. 一下为角点检测中用到的一些函数 cvGoodFeatures ...

最新文章

  1. hive load data inpath 空目录_走近大数据之Hive进阶(一、Hive数据的导入)
  2. leetcode算法题--增量元素之间的最大差值
  3. 暴力解决:InvocationException: GraphViz‘s executables not found
  4. 【软考】2017年11月软件设计师上午真题1-4题答案解析
  5. 贴片电容耐压值一般都是多少?
  6. HTML5链接tcpUDP,UDP/TCP协议 网络调试工具源码(C#)
  7. 【绝对干货】TEASER前传之QUASAR:基于四元数的存在外点Wahba问题的可证明最优解
  8. 自定义附加属性在XAML中的表示方法以及绑定的注意事项
  9. 如何优化java反射,如何有效地使用Java反射
  10. c语言汉诺塔递归算法
  11. matlab 去除最大值,TRIMMEAN 应用(求去掉最大或和最小值后的平均值的方法)
  12. android仿美团评论
  13. 游戏类型英文简称/全称对照表
  14. 面试必备--手写Promise.all与.race
  15. 互联网+医疗解决方案
  16. [leetcode]322. 零钱兑换(Coin Change )C++代码实现
  17. 王者荣耀:从程序员的角度解密王者荣耀,专业术语把院长看懵了
  18. 杨绛谈读书:乐在其中,读书好比串门儿
  19. java 格式化日期到毫秒_关于日期:Java – SimpleDateFormat格式化程序,以毫秒为单位返回纪元时间...
  20. 认识VF--Visual FoxPro 漫谈

热门文章

  1. 杰理之对箱 TWS 通话有回音,噗噗声,卡顿问题【篇】
  2. kafka请求队列模块
  3. 基于redis生成日期订单编号
  4. 核心网upf作用_5G核心网UPF硬件加速技术
  5. 1159. Electrical Outlets
  6. word页码自增、页眉页脚的增长
  7. wp8 导出短信 到android,如何从outlook同步联系人头像以及管理短信呢
  8. 离散数学题目总结归纳
  9. 回忆 | 奔跑在昔日
  10. shader实现星空效果