提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen
CV小白从0开始学数字图像处理

43 Canny 边缘检测:第三步——滞后阈值

在这里进行 Canny 边缘检测的最后一步。

在这里我们将通过设置高阈值和低阈值来将梯度幅值二值化。

  1. 如果梯度幅值edge(x,y)大于高阈值的话,令edge(x,y)=255;
  2. 如果梯度幅值edge(x,y)小于低阈值的话,令edge(x,y)=0;
  3. 如果梯度幅值edge(x,y)介于高阈值和低阈值之间并且周围8邻域内有比高阈值高的像素点存在,令edge(x,y)=255;

在这里,我们使高阈值为100,低阈值为30。顺便说一句,我们只需要在查看结果时判断阈值。

上面的算法就是 Canny 边缘检测算法了。

代码如下:

1.引入库

CV2计算机视觉库

import cv2
import numpy as np
import matplotlib.pyplot as plt

2.读入数据

img = cv2.imread("imori.jpg").astype(np.float32)
H, W, C = img.shape

3.灰度化

gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]

4.Gaussian Filter

K_size = 5
sigma = 1.4

5.补0

pad = K_size // 2
gau = np.zeros((H + pad*2, W + pad*2), dtype=np.float32)
#gau[pad:pad+H, pad:pad+W] = gray.copy().astype(np.float32)
gau = np.pad(gray, (pad, pad), 'edge')
tmp = gau.copy()

6.Kernel

K = np.zeros((K_size, K_size), dtype=np.float32)
for x in range(-pad, -pad+K_size):for y in range(-pad, -pad+K_size):K[y+pad, x+pad] = np.exp( -(x**2 + y**2) / (2* (sigma**2)))
K /= (sigma * np.sqrt(2 * np.pi))
K /= K.sum()for y in range(H):for x in range(W):gau[pad+y, pad+x] = np.sum(K * tmp[y:y+K_size, x:x+K_size])## Sobel vertical
KSV = np.array(((-1., -2., -1.), (0., 0., 0.), (1., 2., 1.)), dtype=np.float32)
## Sobel horizontal
KSH = np.array(((-1., 0., 1.), (-2., 0., 2.), (-1., 0., 1.)), dtype=np.float32)gau = gau[pad-1:H+pad+1, pad-1:W+pad+1]
fy = np.zeros_like(gau, dtype=np.float32)
fx = np.zeros_like(gau, dtype=np.float32)
K_size = 3
pad = K_size // 2for y in range(H):for x in range(W):fy[pad+y, pad+x] = np.sum(KSV * gau[y:y+K_size, x:x+K_size])fx[pad+y, pad+x] = np.sum(KSH * gau[y:y+K_size, x:x+K_size])fx = fx[pad:pad+H, pad:pad+W]
fy = fy[pad:pad+H, pad:pad+W]# Non-maximum suppression
edge = np.sqrt(np.power(fx, 2) + np.power(fy, 2))
fx[fx == 0] = 1e-5
tan = np.arctan(fy / fx)
## Angle quantization
angle = np.zeros_like(tan, dtype=np.uint8)
angle[np.where((tan > -0.4142) & (tan <= 0.4142))] = 0
angle[np.where((tan > 0.4142) & (tan < 2.4142))] = 45
angle[np.where((tan >= 2.4142) | (tan <= -2.4142))] = 95
angle[np.where((tan > -2.4142) & (tan <= -0.4142))] = 135for y in range(H):for x in range(W):if angle[y, x] == 0:dx1, dy1, dx2, dy2 = -1, 0, 1, 0elif angle[y, x] == 45:dx1, dy1, dx2, dy2 = -1, 1, 1, -1elif angle[y, x] == 90:dx1, dy1, dx2, dy2 = 0, -1, 0, 1elif angle[y, x] == 135:dx1, dy1, dx2, dy2 = -1, -1, 1, 1if x == 0:dx1 = max(dx1, 0)dx2 = max(dx2, 0)if x == W-1:dx1 = min(dx1, 0)dx2 = min(dx2, 0)if y == 0:dy1 = max(dy1, 0)dy2 = max(dy2, 0)if y == H-1:dy1 = min(dy1, 0)dy2 = min(dy2, 0)if max(max(edge[y, x], edge[y+dy1, x+dx1]), edge[y+dy2, x+dx2]) != edge[y, x]:edge[y, x] = 0# Histeresis threshold
HT = 100
LT = 30
edge[edge >= HT] = 255
edge[edge <= LT] = 0_edge = np.zeros((H+2, W+2), dtype=np.float32)
_edge[1:H+1, 1:W+1] = edge## 8 - Nearest neighbor
nn = np.array(((1., 1., 1.), (1., 0., 1.), (1., 1., 1.)), dtype=np.float32)for y in range(1, H+2):for x in range(1, W+2):if _edge[y, x] < LT or _edge[y, x] > HT:continueif np.max(_edge[y-1:y+2, x-1:x+2] * nn) >= HT:_edge[y, x] = 255else:_edge[y, x] = 0edge = _edge[1:H+1, 1:W+1]out = edge.astype(np.uint8)

7.保存结果

cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

8.结果

数字图像处理100问—43 Canny 边缘检测:第三步——滞后阈值相关推荐

  1. 数字图像处理100问—40 JPEG 压缩——第四步:YCbCr+离散余弦变换+量化

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 40 JPEG 压缩--第四步:YCbCr+离散余弦 ...

  2. 数字图像处理100问—03二值化(Thresholding)

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 03二值化(Thresholding) 把图像进行二 ...

  3. 数字图像处理100问—33 傅立叶变换——低通滤波

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 33 傅立叶变换--低通滤波 将imori.jpg灰 ...

  4. 数字图像处理100问—02灰度化(Grayscale)

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 02灰度化(Grayscale) 将图像灰度化,通过 ...

  5. 数字图像处理100问—23 直方图均衡化( Histogram Equalization )

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 23 直方图均衡化( Histogram Equal ...

  6. 数字图像处理100问—18 Emboss 滤波器

    提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 18 Emboss 滤波器 Emboss 滤波器可以 ...

  7. 图像处理 100 问!!

    图像处理 100 问!! 参考链接地址:https://github.com/gzr2017/ImageProcessing100Wen English is here (KuKuXia transl ...

  8. Matlab数字图像处理 实验3、图像边缘检测的计算机实现

    子曰:桃李不言,下自成蹊. 图 像 边 缘 检 测 的 计 算 机 实 现 图像边缘检测的计算机实现 图像边缘检测的计算机实现 P a r t . 0 实 验 目 的 仅 限 于 学 习 交 流 Pa ...

  9. 数字图像处理---LOG算子和CANNY算子边缘提取(matlab)

    LOG算子和CANNY算子边缘提取 边缘的含义: 在数字图像中,边缘是指图像局部变化最显著的部分,边缘主要存在于目标与目标,目标与背景之间,是图像局部特性的不连续性,如灰度的突变.纹理结构的突变.颜色 ...

最新文章

  1. ATS中的RAM缓存简介
  2. html学习文档-3、HTML元素
  3. 搞懂正则表达式之基础篇
  4. DDPG-强化学习算法
  5. 【数据结构与算法】之深入解析“K个一组翻转链表”的求解思路与算法示例
  6. 洛谷 - P3391 【模板】文艺平衡树(Splay-区间反转)
  7. 为什么码农要了解业务呢?网友:不是敲代码就好了吗?
  8. jupyternotebook虚拟环境无法连接服务_详解pycharm连接远程linux服务器的虚拟环境的方法_python...
  9. 海康9800平台linux的sdk,流媒体项目外包海康9800平台sdk适配
  10. Windows安装python,以及python的集成开发环境Pycharm
  11. C++|Java混合实验-java搭建get方法靶场,Qt发送请求获取数据
  12. Springboot+Mybatis+PageHelper 分页、排序
  13. c++ vector,list,deque,map,set,hash_map 特点及区别
  14. 3D建模与处理软件简介 刘利刚 中国科技大学
  15. C语言日志库zlog基本使用
  16. 移动端车牌识别sdk-手机拍照识别车牌技术
  17. 国仁网络资讯:抖音如何利用Dou+推广引流;dou+推广需要注意什么?
  18. 米家 智能 服务器,为什么一谈到智能家居 都是小米米家?
  19. 三层交换机也不贵:自己动手做三层交换机
  20. 「写论文」“常用关联词”汇总

热门文章

  1. 自动控制原理--线性系统的微分方程
  2. 计算机网络第六章 链路层和局域网
  3. hadoop 学习路线
  4. rospy基础--001_talker_listener
  5. 什么是STAR原则?
  6. 消费者洞察:数据化闭环洞察消费者
  7. Cision与Brandwatch达成收购协议,整合公关、社交媒体管理和数字消费者洞察
  8. 使用python编写多普勒频移函数,绘制多普勒频移随速度变化的曲线,给出代码并举例,代码以markdown格式给出...
  9. 同构图异构图二部图区别
  10. nginx配置域名访问/禁止ip访问