OpenCV+python------【边缘检测】

实现边缘检测的一般流程:

  1. 使用高斯滤波器,以平滑图像,滤除噪声
  2. 计算图像中每个像素点的梯度强度和方向
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘
  5. 通过抑制孤立的弱边缘最终完成边缘检测

去噪

由于边缘检测很容易受到噪声影响,所以第一步是使用高斯滤波器去除噪声,在这里插入图片描述

计算图像梯度

对平滑后的图像使用 Sobel 算子计算水平方向和竖直方向的一阶导数(图像梯度)(Gx 和 Gy)。根据得到的这两幅梯度图(Gx 和 Gy)找到边界的梯度和方向,
在这里插入图片描述
θ = a r c t a n ( G y / G x ) θ = arctan(Gy/Gx) θ=arctan(Gy/Gx) 求梯度的方向
具体的Sobel算子点这里

非极大值抑制

在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的。
在这里插入图片描述
如上图,我们如果想算A是不是边界点,在相同的梯度方向上,离A最近的分别为B、C,三者进行比较,如果A比B、C都大,就把A的边界(梯度的方向一般总是与边界垂直)保留下来。

双阈值检测

在得到的边界里面,想要确定哪些是真正的边界,此时就需要双阈值minVal和maxVal。

在这里插入图片描述
详细的来说就是,当图像的灰度梯度高于 maxVal 时被认为是真的边界,那些低于 minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃。
我们可以看下上图中的几个点:
A高于maxVal----------->是真正的边界
C低于maxVal但高于minVal且与A相连---------->是真正的边界
B低于maxVal但高于minVal,无真正的边界相连----------->抛弃

在这一步中选择合适的 maxVal和 minVal 对于能否得到好的结果非常重要
高低阈值比在 2 : 1 到 3 : 1 之间

Canny边缘检测

Canny函数
OpenCV中的Canny() 可以完成我们前面所说的几个步骤。

  • 第一个参数 :是输入图像。
  • 第二个参数:minVal
  • 第三个参数:maxVal
  • 第四个参数:是设置用来计算图像梯度的 Sobel卷积核的大小,默认值为 3
  • 第五个参数:L2gradient,用来设定求梯度大小的方程。如果设为 True,就会使用我们上面提到过的方程,否则使用方程: Edge−Gradient (G) = jG2 xj + jG2 yj 代替,默认值为 False。

示例

import cv2
import numpy as np

def cv_show(name,img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
img = cv2.imread('car.png', cv2.IMREAD_GRAYSCALE)

v1 = cv2.Canny(img, 100, 150)
v2 = cv2.Canny(img, 50, 150)

res = np.hstack((v1, v2))
cv2.namedWindow('res', cv2.WINDOW_NORMAL)
cv_show('res', res)

在这里插入图片描述
可以直观的看出来,第一个没有第二个提取的图像丰富,这也是合适的双阈值的重要性。

换张图看看
在这里插入图片描述
也可以创建滑动条来进行调整阈值,更加深刻的理解阈值的重要性。

#  创建滑动条进行调整阈值

minVal, maxVal = 0, 0  # 阈值

def nothing(x):  # 更新图像
    # 获取滑条位置
    minVal = cv2.getTrackbarPos('minVal', 'Canny')
    maxVal = cv2.getTrackbarPos('maxVal', 'Canny')
    canny = cv2.Canny(img, minVal, maxVal)
    cv2.imshow('Canny', canny)
    # cv_show('Canny', canny)


img = cv2.imread('lena.jpg', 0)
cv2.namedWindow('Canny')
# 创建两个滑条
cv2.createTrackbar('minVal', 'Canny', 0, 255, nothing)
cv2.createTrackbar('maxVal', 'Canny', 0, 255, nothing)

while(True):
    #等待关闭
    k=cv2.waitKey(1)&0xFF
    if k==27:
        break

结果如下:
在这里插入图片描述
这个不是出现错误,滑动阈值以后就会显示检测图像。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值