@Canny算子中的非最大值抑制(NMS)实现

canny算子中的非极大值抑制是在对图像进行梯度求取之后,在梯度方向进行的运算,也就是说此处的非极大值抑制是在对图像进行梯度求取后,在生成的梯度矩阵上求取的极大值。
注:canny算法在进行非极大值抑制之前需要先进行滤波和梯度求取。
该算法的实现流程:
假设原始图像A为4*4的矩阵,如下:
A=2346572146965732A= \begin{matrix} 2 & 3 & 4 & 6 \\ 5 & 7 & 2 & 1 \\ 4 & 6 & 9 & 6 \\ 5 & 7 & 3 & 2 \\ \end{matrix} A=2545​3767​4293​6162​

  1. 进行梯度计算,经过梯度求取后B为:
    B=3.16234.12312.828402.23615.09907.071102.23613.16236.708200000B= \begin{matrix} 3.1623 & 4.1231 & 2.8284 & 0 \\ 2.2361 & 5.0990 & 7.0711 & 0 \\ 2.2361 & 3.1623 & 6.7082 & 0 \\ 0 & 0 & 0 & 0 \\ \end{matrix} B=3.16232.23612.23610​4.12315.09903.16230​2.82847.07116.70820​0000​
    计算方法为:
    dx(i,j) = A(i,j+1) - A(i,j);
    dy(i,j) = A(i+1, j) - A(i,j);
    B(i,j) = sqrt(dx(i,j)*dx(i,j) + dy(i,j)*dy(i,j));

代码实现为:

A=[2,3,4,6; 5,7,2,1; 4,6,9,6; 5,7,3,2];
[height, width] = size(A);
dx = zeros(height, width);
dy = zeros(height, width);
d = zeros(height, width);
for i = 1:height-1for j = 1:width-1dx(i,j) = A(i,j+1) - A(i,j);dy(i,j) = A(i+1, j) - A(i,j);d(i,j) = sqrt(dx(i,j)*dx(i,j) + dy(i,j)*dy(i,j));end
end

该算法对于后一列和最后一行没有求取其梯度值。

  1. 非极大值抑制(NMS)
    在梯度矩阵B上进行非极大值运算处理,可以直接比较中心点0,90,45,135四个方向的梯度值,若该点是最大值,则保留。否则为0,即假设在梯度矩阵中的某点为中心点C(i,j),则该点的取值为C(i,j) 是否满足在(C(i,j), C(i,j+1), C(i+1,j), C(i+1, j+1))为最大值,若是保留,否则为0。
    但由于实际图像中的像素点是离散的二维矩阵,处于真正中心位置C出的梯度方向的两侧的点不一定存在,或者说存在一个亚像素点,而这个不存在的点以及这个点的梯度值就必须通过两侧的点插值得到。 这句话我的理解是,以中心点C的梯度方向做一条斜线,用斜线与周围梯度值的交点 和 中心点C的梯度值比较 判断其是否为最大值。
    来个图说明一下:

    C 为中心点,梯度值为d(i,j);
    在x方向的梯度为dx(i,j);
    在y方向的梯度值为:dy(i,j);
    则过C点的梯度方向线共有4中情况:
    1) |dy|>|dx|,且dxdy>0; 2) |dy|>|dx|,且dxdy<0; 3) |dy|<|dx|,且dxdy>0; 4) |dy|<|dx|,且dxdy<0.
    四种情况在图中显示如下所示:

    其中: q1,q2,q3,q4分别代表与在梯度矩阵中与C相关的相邻点。
    当|dy|>|dx|时,共有2种情况:1)和2),此时weight=|dx|/|dy|.
    由线与线之间的相交关系,结合三角形,即可求得:
    d1 = weight*q1+(1-weight)q2;
    d2 = weight
    q3+(1-weight)q4;
    当|dx|>|dy|时,共有2种情况:3)和4),此时weight=|dy|/|dx|.
    同理,d1 = weight
    q1+(1-weight)q2; d2 = weightq3+(1-weight)*q4;
    然后,比较d(i,j)>=d1,且d(i,j)>=d2是否成立,若满足,保留d,否则d=0。
    流程图如下:

    本文以MATLAB库中的图片rice.png为例,结果如下:
    原始图片:

    高斯滤波处理后:

    求梯度后:

    非极大值抑制之后:

    详细代码如下:
clear all; close all; clc
I = imread('rice.png');
% I = rgb2gray(I);
I = im2double(I);
[height, width] = size(I);
figure; imshow(I);title('I')%高斯卷积核
conv = zeros(5, 5);
sigma = 1;
sigma_2 = sigma * sigma;
sum = 0;
for i=1:5for j=1:5conv(i,j) = exp((-(i-3)*(i-3) - (j-3)*(j-3)) / (2*sigma_2))/(2*3.14*sigma_2);sum = sum+conv(i,j);end
end
conv = conv./sum %标准化的高斯卷积核%对图像进行高斯滤波处理
J = conv2(I, conv, 'same');
figure; imshow(J);title('高斯滤波处理');%添加sobel算子
% s=[1 2 1; 0 0 0; -1 -2 -1];
% H = conv2(J1, s,'same');
% V = conv2(J1, s','same');
% J = sqrt(H.*H + V.*V);
% % J1 = uint8(J1);
% figure;imshow(J);title('sobel提取边缘');%求梯度
dx = zeros(height, width);
dy = zeros(height, width);
d = zeros(height, width);
for i = 1:height-1for j = 1:width-1dx(i,j) = J(i,j+1) - J(i,j);dy(i,j) = J(i+1, j) - J(i,j);d(i,j) = sqrt(dx(i,j)*dx(i,j) + dy(i,j)*dy(i,j));end
end
figure;imshow(d*10);title('求梯度后的结果')%局部非极大值抑制
K = zeros(height, width);
for i=2:height-1for j = 2:width-1if d(i,j) == 0K(i,j) = 0;elsegradX = dx(i,j);gradY = dy(i,j);gradTemp = d(i,j);if abs(gradY)>abs(gradX)weight = abs(gradX)/abs(gradY);grad2 = d(i-1,j);grad4 = d(i+1,j);if gradX*gradY>0grad1 = d(i-1,j-1);grad3 = d(i+1,j+1);elsegrad1 = d(i-1,j+1);grad3 = d(i+1,j-1);endelseweight = abs(gradY)/abs(gradX);grad2 = d(i,j-1);grad4 = d(i,j+1);if gradX*gradY>0grad1 = d(i+1, j-1);grad3 = d(i-1, j+1);elsegrad1 = d(i-1, j-1);grad3 = d(i+1, j+1);endendgradTemp1 = weight*grad1 + (1-weight)*grad2;gradTemp2 = weight*grad3 + (1-weight)*grad4;if gradTemp >=gradTemp1 && gradTemp >= gradTemp2K(i,j) = gradTemp;elseK(i,j) = 0;endendend
end
figure;imshow(K*10);title('非极大值自己')
figure;imhist(K);title('直方图')

本文重点介绍了 canny算子中的梯度求取和非极大值抑制的实现过程。该文为作者在学习过程中对该部分的理解,希望对您能有所帮助。如有问题,敬请各位指点。

Canny算子中的梯度求取及非最大值抑制(NMS)实现相关推荐

  1. MTCNN中的重叠度IOU和非极大值抑制NMS原理及Python实现

    MTCNN中的重叠度IOU和非极大值抑制NMS原理及Python实现 一.重叠度iou 从在一张照片上框人脸时,因为图像金字塔的原因可能会把人脸框两次以上,每个框的坐标为[X1,Y1X2,Y2,C], ...

  2. tensorflow频域操作及梯度求取

    tensorflow频域操作及梯度求取 最近尝试使用tensorflow中的傅立叶变换操作,主要涉及的op有tf.complex,tf.fft, tf.fft2d,tf.angle, 涉及的数据类型为 ...

  3. python中Scipy模块求取积分

    python中Scipy模块求取积分的方法: SciPy下实现求函数的积分的函数的基本使用,积分,高等数学里有大量的讲述,基本意思就是求曲线下面积之和. 其中rn可认为是偏差,一般可以忽略不计,wi可 ...

  4. 对梯度幅值进行非极大值抑制

    图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图象边 ...

  5. Batch Normalization函数详解及反向传播中的梯度求导

    摘要 本文给出 Batch Normalization 函数的定义, 并求解其在反向传播中的梯度 相关 配套代码, 请参考文章 : Python和PyTorch对比实现批标准化Batch Normal ...

  6. 机器学习--多标签softmax + cross-entropy交叉熵损失函数详解及反向传播中的梯度求导

    https://blog.csdn.net/oBrightLamp/article/details/84069835 正文 在大多数教程中, softmax 和 cross-entropy 总是一起出 ...

  7. matlab中利用xy求取多项式z,将(x y z)^10展开为多项式,经过合并同类项

    如何在matlab中展开多项式 symssps=((s^2+1))^3*(s+5)^2*(s^4+4*s^2+7)ps1=expand(ps)结果:ps=(s^2+1)^3*(s+5)^2*(s^4+ ...

  8. matlab中利用xy求取多项式z,matlab基础练习题

    3. 求有理分式()()()()3323230.522521x x x R x x x x ++=+-++的商多项式和余多项式 4. 一元多项式42234p x x x =-+,写出表示p 的MATL ...

  9. 【图像处理】——Python图像分割边缘检测算法之一阶梯度算子(Roberts、Prewitt、Sobel、 Kirsch、Canny算子)

    目录 前言 一.边缘检测算法 1.一阶算子 2.二阶算子 二.一阶算子 原图像lena 1.Roberts算子 不同方向的算子模板 梯度的计算 系统代码: 自定义函数代码 结果 2.Prewitt 不 ...

最新文章

  1. 北大华为鹏城联合首次提出视觉 Transformer 后量化算法!
  2. 传统IT和新IT并行推进 EMC两条腿走路助力企业数字化转型
  3. 例题:学习数据库查询。学生信息表的创建,主外键关系,以及45道题的查询实例。主要知识点在讲页45页,和讲页65页...
  4. 按键防抖_单片机用一个IO口采集多个按键信号
  5. 【bzoj1726/Usaco2006 Nov】Roadblocks第二短路——SPFA
  6. win2003下APACHE2.050+PHP5+MYSQL4.0.20+PHPMYADMIN2.57 的简易安装配置
  7. 苹果将明年上半年iPhone出货量目标提高 30%
  8. new blob文件设置编码_前端下载文件amp;下载进度
  9. spark相关原理介绍
  10. 在电脑上如何剪辑音乐?
  11. MAC下切换多个IP的Shell脚本
  12. 5wpa_supplicant程序 --详解
  13. 解决windows下文件名太长无法删除的问题
  14. 计算机网络之DNS面试题
  15. 快桃科技居然给我无条件双倍工资!却又整天瞎搞
  16. 定制联想笔记本一键恢复内容
  17. 无线个人通信(WPAN)-蓝牙
  18. QQ API设计说明书
  19. 疯狂Java讲义(七)----第二部分
  20. python openpyxl 设置表格列宽的自动适应_Python的openpyxl列宽调整大小

热门文章

  1. 数据湖和数据仓库区别介绍
  2. solr引入mysql数据库数据,出现Requests: 1, Fetched: 0, Skipped: 0, Processed: 0
  3. The bean ‘xxx‘ could not be injected as a ‘xxx‘ because it is a JDK dynamic proxy that implements:
  4. Kudu 原理、API使用、代码
  5. android 雷达图 蜘蛛图
  6. [Spark好友推荐]
  7. 【信息资源管理】单选多选,精讲
  8. android自动切换暗色,Android 适配深色模式的总结
  9. Android内存优化(二)之Bitmap的内存申请与回收(Android N和O的对比)
  10. 个人笔记 springboot整合shiro实现权限管理,前端使用vue 10155