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

写在前面

黄宁然——看过你看过的算法,觉得好难。

参考文献镇楼

[1]https://blog.csdn.net/tostq/article/details/49305615
[2]https://blog.csdn.net/qq_45613931/article/details/117819107
[3]陈丽莉《基于SUSAN算法的角点检测》
[4]王栋、朱明《SUSAN角点探测算法分析改进》

问题来源

an***** xue100: https://bbs.csdn.net/topics/*********?spm=1001.2014.3001.**77
1)如何计算USAN区域的重心?
2)非极大值抑制,指的是若模板中心对应的灰度小于模板内的任意像素灰度,就舍弃该像素点吗?
3)几何门限g如何选取?
因“当前发帖距今超过3年,不再开放新的回复”,故新建帖子。迟到的回复。

1、原理简介

SUSAN(Smallest UnivalueSegment Assimilating Nucleus)使用一个圆形模板,通过检测模板中的像素与中心位置像素的偏离程度,来判断中心位置像素是否为边缘或角点。
模板大小:半径为3.5像素,模板内共计有37个像素。

中心思想:如果周边像素与中心位置像素偏差较小,则认为周边像素与中心位置像素相似,中心位置为非边缘;如果周边像素与中心位置偏差较大,则认为中心位置为边缘或角点。

2、基本实现步骤

(1)相似判断

(式1)
I(r0)为中心位置像素,I( r)为周边位置像素,t像素偏差阈值,c为布尔结果,表示相似或不相似。
关于阈值t:可见,t越大,周边像素越容易与中心位置像素“相似”,越不容易被判定为边缘或角点,即将获得较少的角点。相关文献说,t值影响的是角点检测的数量[1]。

(2)平滑曲线进行相似判断

实际中,使用平滑曲线来求c
(式2)

(3)累计相似度

对于圆形模板区域,共计37个像素,周边36个像素与中心位置像素进行对比,可以得到该中心位置的36个c。对这36个c进行累加,得到该中心位置的累计相似度:
(式3)
显然,n越大,越不可能是边缘、角点。

(4)初始边缘响应/角点

这里,再引入一个阈值g,通过判断n与g的大小,来得到该中心位置属于边缘或角点的可能性。
(式4)
可见,若n大于g,则R为0,表示该中心位置为非边缘(非角点);如果n小于g,R取值为(g-n),含有取负操作。故R值越大,该中心位置为边缘或角点的可能性就越大。

关于阈值g:g的取值越小,对角点检测越挑剔。文献[1]阐述,g影响角点检测的质量。g的取值,文献[1]阐述可以取max(n)的0.75倍;有的程序代码中,直接取值37/2。具体取值,应该需要针对具体场景进行调试。

3、python代码实现

3.1 圆形掩模

def get_susan_mask():mask=np.ones((7,7))mask[0,0]=0;mask[0,1]=0;mask[0,5]=0;mask[0,6]=0;mask[1,0]=0;mask[1,6]=0;mask[5,0]=0;mask[5,6]=0;mask[6,0]=0;mask[6,1]=0;mask[6,5]=0;mask[6,6]=0;return mask

该程序返回的mask如下:

为1的位置,即是圆形模板区域。

3.2 susan角点检测

def susan_corner_detect(img_src,t=10):susan_mask = get_susan_mask()img = img_src.copy()row_s,col_s = 3,3row_e,col_e = img_src.shape[0]-3,img.shape[1]-3n_max = 0n_arr=37*np.ones(img.shape) # 初始认为没有角点for r in range(row_s,row_e):#遍历所有行for c in range(col_s,col_e):#遍历所有列susan_zone = img[r-3:r+3+1,c-3:c+3+1]#获取矩形区域susan_zone = susan_zone[susan_mask!=0]#使用mask截取圆形区域r0 = img[r,c]similarity = np.exp(-((1.0*susan_zone-r0)/t)**6 )n=np.sum(similarity)if n>n_max:n_max = nn_arr[r,c] = ng = n_max /2R = np.zeros(img.shape)index = n_arr<g       #小于g,认为是可能的角点,越小,可能性越大R[index] = g-n_arr[index] # 取反,所以R越大,是角点的可能性越大plt.figure()plt.title("edge")plt.imshow((6.37 * n_arr).astype(np.uint8), cmap=cm.gray)return R

3.3 检测结果

取t=10,g= n_max /2。
主程序中,调用算法:

if __name__ == '__main__':img_src = cv2.imread('susan_input1.png',-1)if len(img_src.shape)==3:img_src = cv2.cvtColor(img_src,cv2.COLOR_BGR2GRAY)corner = susan_corner_detect(img_src)img_show = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show[corner != 0] = (255, 0, 0)plt.figure()plt.title("original corners")plt.imshow(img_show, cmap=cm.gray)plt.show()


4、重心法去除伪角点

从上图的角点检测结果来看,原始角点中存在较多冗余角点,或伪角点。
采用重心法去除。
根据文献1,求取重心
(式5)
上式中,r为位置,实际为(x,y)两轴构成。计算时,先计算x方向重心,再计算y方向重心。对公式的简言之:圆形模板中心位置周边有36个像素,相应的有36个c,在求x方向重心Gx时,将36个位置的x坐标与相应的c相乘后累加,再除以sum( c),即可得到Gx;同理得Gy。另外,对于r0,可假设其位置为(0,0)。
在求得重心后,计算重心与中心位置的距离,根据文献[3]描述,如距离较小,则认为中心位置不是角点。根据文献[4],该距离阈值设置为1.8。本文采用1.5。另,重心法去除伪角点与初始角点的检测,在代码实现时,有些许内容的重复,所以在初始角点检测时,即可同步应用重心法。

4.1重心法代码

def gravity_filter(img_src,corner_src,t=10,F=1.5):x_label = np.zeros((7,7))y_label = np.zeros((7,7))x_label[:,0]=-3;x_label[:,1]=-2;x_label[:,2]=-1;x_label[:, -1] = 3;    x_label[:, -2] = 2;    x_label[:, -3] = 1;y_label[0,:]=-3;y_label[1,:]=-2;y_label[2,:]=-1;y_label[4, :] = 1;y_label[5, :] = 2;   y_label[6, :] = 3;print(x_label,"\r\n",y_label) #查看矩形区域内x、y轴信息img = img_src.copy()row_s, col_s = 3, 3row_e, col_e = img_src.shape[0] - 3, img.shape[1] - 3corner = corner_src.copy()susan_mask = get_susan_mask()for r in range(row_s,row_e):for c in range(col_s,col_e):if corner[r,c] ==0: #对于不是角点的位置,就没必要进行后续计算了continuesusan_zone = img[r-3:r+3+1,c-3:c+3+1]#获取矩形区域r0 = img[r,c]similarity = np.exp(-((1.0*susan_zone-r0)/t)**6 )g_x = np.sum(similarity[susan_mask==1]*x_label[susan_mask==1] )/np.sum(similarity[susan_mask==1])#使用mask截取圆形区域g_y = np.sum(similarity[susan_mask == 1] * y_label[susan_mask == 1]) / np.sum(similarity[susan_mask == 1])#使用mask截取圆形区域distance = np.sqrt(g_x**2+g_y**2)if distance<F:corner[r,c] = 0return corner

4.2 主程序调用

if __name__ == '__main__':img_src = cv2.imread('susan_input1.png',-1)if len(img_src.shape)==3:img_src = cv2.cvtColor(img_src,cv2.COLOR_BGR2GRAY)corner = susan_corner_detect(img_src)img_show = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show[corner != 0] = (255, 0, 0)plt.figure()plt.title("original corners")plt.imshow(img_show, cmap=cm.gray)cor_g = gravity_filter(img_src, corner)img_show2 = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show2[cor_g != 0] = (255, 0, 0)plt.figure()plt.title("corners-gravity ")plt.imshow(img_show2, cmap=cm.gray)plt.show()

4.3 检测结果


与原始角点的局部对比

5、非极大值抑制

非极大值抑制,也可对角点进行剔除。
思想:对于已获取的角点矩阵,使用一3x3的矩形区域进行逐个判断。在3x3的区域中,若中心位置不是最大,则认为该中心位置不是局部极值,即认为该中心位置不是角点,将其抑制。
问题:若3x3区域内,有两个位置的值相等且均为最大,则如何处理?目前,本文2个均保留。
220719更新:该nms代码存在些许不足之处,详见后续的博文,https://blog.csdn.net/xiaohuolong1827/article/details/125859795

5.1 非极大值抑制代码

def corner_nms(corner,kernal=3):out = corner.copy()row_s = int(kernal/2)row_e = out.shape[0] - int(kernal/2)col_s,col_e = int(kernal/2),out.shape[1] - int(kernal/2)for r in range(row_s,row_e):for c in range(col_s,col_e):if corner[r,c]==0: #不是可能的角点continuezone = corner[r-int(kernal/2):r+int(kernal/2)+1,c-int(kernal/2):c+int(kernal/2)+1]index = corner[r,c]<zone(x,y) = np.where(index==True)if len(x)>0 : #说明corner[r,c]不是最大,直接归零将其抑制out[r,c] = 0else:out[r,c] = 255return out

5.2 主程序调用

if __name__ == '__main__':img_src = cv2.imread('susan_input1.png',-1)if len(img_src.shape)==3:img_src = cv2.cvtColor(img_src,cv2.COLOR_BGR2GRAY)corner = susan_corner_detect(img_src)img_show = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show[corner != 0] = (255, 0, 0)plt.figure()plt.title("original corners")plt.imshow(img_show, cmap=cm.gray)cor_g = gravity_filter(img_src, corner)img_show2 = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show2[cor_g != 0] = (255, 0, 0)plt.figure()plt.title("corners-gravity ")plt.imshow(img_show2, cmap=cm.gray)cor_g_nms = corner_nms(cor_g)img_show3 = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_show3[cor_g_nms != 0] = (255, 0, 0)plt.figure()plt.title("corners-gravity-nms ")plt.imshow(img_show3, cmap=cm.gray)plt.show()

5.3 检测结果


与重心法处理后的局部对比

6. 源码下载:

https://download.csdn.net/download/xiaohuolong1827/85030525

7. 其他

2022.03.22,黄宁然:“SUSAN,你竟然在看这个,我以前用过,你信不信”。呃,我当然信。

Susan角点检测python实现 (边缘检测、角点检测、重心计算、非极大值抑制)相关推荐

  1. 目标定位和检测系列:交并比(IOU)和非极大值抑制(NMS)的python与C/C++实现

    Python实现 交并比(Intersection over Union)和非极大值抑制是(Non-Maximum Suppression)是目标检测任务中非常重要的两个概念.例如在用训练好的模型进行 ...

  2. Shi-tomasi角点检测python实现及基于opencv实现 (角点检测、非极大值抑制)

    写在前面: 已经是七月中旬,黄宁然,你依然在这里. 参考文献镇楼: [1]龚思宇宙,基于平面模板的摄像机标定及相关技术研究 [2]汪洋,扫地机器人定位算法设计与嵌入式系统实现 [3]Denny#,[o ...

  3. FAST角点检测算法(二)- 非极大值抑制筛选fast特征点

    FAST角点检测算法(二)- 非极大值抑制筛选fast特征点 author@jason_ql(lql0716) http://blog.csdn.net/lql0716 fast角点检测算法参考文章& ...

  4. 目标窗口检测算法-NMS非极大值抑制

    1. NMS(non maximum suppression)的定义和算法步骤 NMS(non maximum suppression),中文名非极大值抑制,在很多计算机视觉任务中都有广泛应用,如:边 ...

  5. array python 交集_NMS原理(非极大值抑制)+python实现

    1.先解释什么叫IoU(intersection-over-union).IoU表示(A∩B)/(A∪B) 即交并比. 非极大值抑制:图一 --> 图二 ,剔除同一个目标上的重叠建议框,最终一个 ...

  6. 非极大值抑制(nms)算法详解[python]

    一.起源 目标检测在使用了基于深度学习的端到端模型后效果斐然.目前,常用的目标检测算法,无论是One-stage的SSD系列算法.YOLO系列算法还是Two-stage的基于RCNN系列的算法,非极大 ...

  7. NMS(非极大值抑制)的python,cpu,gpu实现

    必要性 NMS(非极大值抑制)是目标检测中用来确定最佳检测框的手段,根据目标检测流程,若果没有NMS步骤,其每个检测框都会有大量重叠度很高的预测框表示同一个目标.如下图: 左图为经过NMS的预测结果, ...

  8. 在Python中用cupy实现IoU(交并比)和NMS(非极大值抑制)的GPU加速

    1. 前言 IoU(交并比)和NMS(非极大值抑制)的计算在目标检测任务中可以说是必不可少的,但是当需要计算的bounding box的数量级很大的时候,cpu就吃不消了.例如在对Faster RCN ...

  9. 计算机视觉入门-梯度、算子、Canny边缘检测、非极大值抑制、双门限法

    第二章 边缘检测 边缘:信号突变的地方.能够紧凑描述图片的内容信息 边缘检测的几种类型: 表面不连续 深度不连续 表面颜色不连续 投影不连续 可以根据求导来判断是否为断点(边缘) x方向(为简便操作 ...

最新文章

  1. 本地如何使用phpstudy环境搭建多站点
  2. Tomcat 启动卡住
  3. 当表格列数太多时,怎么实现表格的横向滚动
  4. 【Android 组件化】路由组件 ( 生成 Root 类记录模块中的路由表 )
  5. 学习笔记Hive(九)—— 实例:航空客户价值分析数据预处理
  6. 【机器学习】异常检测算法之(HBOS)-Histogram-based Outlier Score
  7. ElasticSearch创建、修改、获取、删除、索引Indice mapping和Index Template案例
  8. 【uva 1395】Slim Span(图论--最小生成树+结构体快速赋值 模版题)
  9. 四大科技支撑大健康生态 360保险输出标准化、定制化两大核心力
  10. Python的filter、map、reduce与lambda结合使用
  11. pytorch 入门学习使用逻辑斯蒂做二分类-6
  12. dorado7.x控制显示隐藏
  13. PyQt5中打开网址方法
  14. fanq15/FSOD-code 的环境配置及运行
  15. 怎么修改图片尺寸大小?电脑上怎么图片改大小?
  16. linux配置dhcp超级作用域,Linux DHCP服务器 超级作用域
  17. WebRTC和APP互通连麦直播
  18. ESP32-C3 SPI salve示例错误
  19. archive 归档解归档
  20. 辗转取余数php算最小公约数,JS取得最小公倍数与最大公约数

热门文章

  1. 一、C++语法基础(浅谈)
  2. phoenix启动 Unable to load native-hadoop library for your platform... using builtin-java classes wher
  3. harbor企业级镜像仓库搭建
  4. 做设计用什么笔记本电脑好?
  5. 用什么方式推广莆田鞋最好?C原版本真的能买吗
  6. 关于uni-app的iPhonex底部安全区域解决方案
  7. open-falcon之HBS
  8. python分析股票支撑压力_python+requests接口压力测试500次,查看响应时间的实例
  9. 值得销售人员看的书籍
  10. 2019-3-8-win10-uwp-渲染原理-DirectComposition-渲染