Canny边缘检测(高斯滤波,计算图像的梯度和梯度方向,非极大值抑制NMS,双阈值筛选边缘)

 Canny边缘检测:

计算机如何识别边缘?

肉眼识别即颜色变化强度大的地方,对于计算机而言就是像素点梯度方向像素变化率很大的地方。

 

1.高斯滤波:高斯滤波的就是先找到高斯滤波核然后再进行卷积

   1.1高斯噪声

首先我们先说一下,什么是高斯噪声?高斯噪声就是它的概率密度函数服从高斯分布(即正态分布)的一类噪声。在图像当中常表现为能引起较强视觉效果的孤立像素点或像素块。噪声的出现会给图像带来干扰,让图像变得不清楚。

高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。消除图像在数字化过程中产生或者混入的噪声。

   1.2高斯滤波核计算

作用:高斯滤波核是用来去噪的,去掉图像中灰灰的点,留下非黑即白可用0,1表示的点。

二维高斯分布:

假定中心点的坐标是(0,0),那么取距离它最近的8个点坐标,为了计算,需要设定σ的值。假定σ=1,则高斯滤波核计算如下:

   将坐标带入高斯分布得到:

有表中数据可得到结论:中心的值最大,越往外侧值约小。

再归一化处理:我们还要确保这九个值加起来为1(高斯滤波核的特性),这9个点的权重总和等于0.7792,因此给上面9个值还要分别除以0.7792,得到最终的高斯滤波核的值。

     1.3卷积

具体计算方法:

对应位相乘得到结果为1.58左右则将原来3的位置改为1。然后依次向左向下移动小橘框与滤波核进行计算。(加外围一排的原因是为了保持计算完后)

最终结果:

注:在原图加一层的做法是为了使在计算后得到与原图大小相同的图。通俗的讲就是,原图大小是5x5的,在外围加了一层变为了6x6,计算结束后又变成了原图5x5的大小。

高斯滤波的作用:原图的灰度强度变化是很大的(225旁边是2,4,差值很大)通过高斯滤波之后,差值变小了,说明图变平滑多了

 

2.计算图像的梯度和梯度方向

 

Sobel计算方法大致与高斯相同,对应位相乘,但计算卷积因子Gx,Gy是固定不变的。

举例:

与Gx对应位相乘,中间一竖行不起作用,其余位与Gx相乘会发现是右边一列的值减去左边一列的值。即   +   ,即算出水平方向的梯度dx,同样方法算出垂直方向的梯度dy。最终梯度及其方向计算方法如图:

                                              

具体计算方法如下(对应位相乘):

梯度值最终结果为:

(两红框之间表示的是边界,与原图相比边界太宽)

一共有两个表,一个存梯度值,另外一个用来存梯度方向。

 

3.非极大值抑制NMS

非极大值抑制就是是一种去除非极大值的算法,常用于计算机视觉中的边缘检测、物体识别等。可以将sobel计算的边界变细。

思想:梯度方向是边的垂直方向,只保留梯度方向变化率最大的点,即使边界边细。

在中心像素点的梯度方向方向选三个点,(8领域表示法,表示中间像素的8个方向)如果中间点值最大则暂且认为其是边缘点,如果中间点值不是最大则此是边缘点。举例:若选择一个中间点,其梯度方向为了90°,则看图中4,2,5三个点,比较2是否是局部最大值(极值点),如果是则2为边缘点,如果不是则不是边缘点。因为是在sobel的基础上选择领域中最大的,因此边界变细。 

 

举例:g1,g2,g3,g4,c都为离散的像素点(c点的8邻域),如何判断c点是其中最大的像素点?

 

 

在c点的梯度方向(边的垂直方向)做一条线,交点可能没有像素点,则设两个交点为dTmp1,dTmp1,用线性差值法算出两交点像素值,与c点像素值比较,如果c点是最大值则保留c点,否则抛弃。

 

4.双阈值筛选边缘

阈值minvalue, 阈值maxvalue(一般minvalue设为50,maxvalue为3倍的minvalue)

若像素小于阈值minvalue或者大于阈值maxvalue的点扔掉。

若介于minvalue与maxvalue之间,需要分情况,如果像素点在主边缘上则保留,如果与主边缘没有相连则扔掉。

# 读入图像
import cv2
img = cv2.imread("E:/PycharmProjects/doutula/baidutup/pic/lixian_2.jpg")
lenna = cv2.imread("E:/PycharmProjects/doutula/baidutup/pic/lixian_2.jpg",0)
cv2.imshow("lixian", img)
cv2.imshow("huidu", lenna)
# 图像降噪
lenna = cv2.GaussianBlur(lenna, (5, 5), 0)

# Canny边缘检测,低阈值50,高阈值150
canny = cv2.Canny(lenna, 50, 150)
cv2.imshow("canny", canny)
cv2.waitKey()

结果显示:

 

5.边缘的连接

用栈来完成,确定出一定是边的像素点,然后遍历这些一定是边的像素点的8邻域,看是否存在灰度值在minvalue与maxvalue之间可能是边的像素点。如果此像素点可能是边并且又在肯定是边的像素点的8邻域内,则将其标记为一定是边的像素点,压入栈中。将这些一定是边的像素点连接起来就是边缘。

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值