本节是非微分边缘检测算子——Canny算子

边缘是图像中灰度有阶跃变化,或屋顶变化的像素的结合。

 

1、  Canny算子边缘检测基本原理

该算子功能比前面几种都要好,但是它实现起来较为麻烦,Canny算子是一个具有滤波,增强,检测的多阶段的优化算子,在进行处理前,Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny分割算法采用一阶偏导的有限差分来计算梯度幅值和方向,在处理过程中,Canny算子还将经过一个非极大值抑制的过程,最后Canny算子还采用两个阈值来连接边缘。

2、  Canny算子算法步骤

第一步:用高斯滤波器平滑图像。

见链接:https://blog.csdn.net/m0_37957160/article/details/119377528

第二步:计算整个图像的每一个像素的梯度幅值和梯度方向。

数字图像处理中提供了好多种算子,计算图像的梯度和梯度方向。比如Sobel算子。

比如下边是使用Sobel算子计算的整个图像中每一个像素的梯度和方向:

现在边太粗了需要变细。

第三步:对梯度幅值进行非极大值抑制。

Canny算法论文里边是这样介绍的:在上述梯度矩阵(包含大小和方向 ),这个梯度方向有可能不是离散的,是连续的。那么论文里边假设我就关注如下的4个轴即4个方向 ,

假设只关注4个方向,

比如说某一个梯度的方向是30度,那么在0到45度之间他是离45度方向比较近,那么就规定他为45度。就是查看他在上述方向划分的模式下,离哪一个比较近就把他的方向归并到哪一个方向上。

因为图像的像素分布是离散的,如果把其中一个像素的8邻域按照上述模式盖上去,

上述的NMS是Canny论文里边的思路,有后人改进的思想:用亚像素去线性差值的方法去进行非极大值抑制。

第四步:用双阈值算法检测和连接边缘。(阈值A和阈值B)

(PS:如果只是单一阈值的话,你这个阈值调的比较高,那整个图像里边一些细微的边缘(即非极大值抑制之后他那些梯度比较小的边)很可能就直接被扔掉了,但是呢,如果把阈值设置的比较低,好多杂乱无章的边也会包含进来,所以引进了双阈值)

如果做完NMS的梯度值小于阈值A的话,那么该点直接扔掉,比如说赋值为0;如果这个值比我设置的B值还要大的话,那么就认为该点是边缘点;如果在A和B之间的点叫做中庸点,对待中庸点会分两种情况:第一种情况就是该中庸点与已经确定的边缘点所组成的边有关系(就是相连,该中庸点与确定的边界相连),那么就认为该中庸点也是一个边缘点(置为255),如果该中庸点在一条边上那么该边也被认为是一条边界边。反之那么认为该中庸点是非边缘点。

3 、 Canny算子python实现

import cv2
import numpy as np
import mathdef Canny(img, threshold1, threshold2):# 高斯滤波gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)new_gray = cv2.GaussianBlur(gray, (5, 5), 1)gaussian_result = np.uint8(np.copy(new_gray))cv2.imshow('gaussian',gaussian_result)# 算梯度幅值W1, H1 = new_gray.shape[:2]dx = np.zeros([W1 - 1, H1 - 1])dy = np.zeros([W1 - 1, H1 - 1])d = np.zeros([W1 - 1, H1 - 1])ddgree = np.zeros([W1 - 1, H1 - 1])for i in range(1, W1 - 1):for j in range(1, H1 - 1):dx[i, j] = new_gray[i - 1, j - 1] + 2 * new_gray[i, j - 1] + new_gray[i + 1, j - 1] - \new_gray[i - 1, j + 1] - 2 * new_gray[i, j + 1] - new_gray[i + 1, j + 1]dy[i, j] = new_gray[i - 1, j - 1] + 2 * new_gray[i - 1, j] + new_gray[i - 1, j + 1] - \new_gray[i + 1, j - 1] - 2 * new_gray[i + 1, j] - new_gray[i + 1, j + 1]d[i, j] = np.sqrt(np.square(dx[i, j]) + np.square(dy[i, j]))  # 图像梯度幅值作为图像强度值ddgree[i, j] = math.degrees(math.atan2(dy[i, j], dx[i, j]))if ddgree[i, j] < 0:ddgree += 360d_r = np.uint8(np.copy(d))cv2.imshow('tidu', d_r)# 非极大值抑制W2, H2 = d.shapeNMS = np.copy(d)NMS[0, :] = NMS[W2 - 1, :] = NMS[:, 0] = NMS[:, H2 - 1] = 0for i in range(1, W2 - 1):for j in range(1, H2 - 1):if d[i, j] == 0:NMS[i, j] = 0else:g1 = Noneg2 = Noneif (ddgree[i, j] <= 22.5 and ddgree[i, j] >= 0) or (ddgree[i, j] >= 337.5):g1 = NMS[i, j - 1]g2 = NMS[i, j + 1]elif (ddgree[i, j] <= 67.5 and ddgree[i, j] > 22.5) or (ddgree[i, j] <= 337.5 and ddgree[i, j] > 292.5):g1 = NMS[i - 1, j + 1]g2 = NMS[i + 1, j - 1]elif ddgree[i, j] <= 112.5 and ddgree[i, j] > 67.5 or (ddgree[i, j] <= 292.5 and ddgree[i, j] > 247.5):g1 = NMS[i - 1, j]g2 = NMS[i + 1, j]elif (ddgree[i, j] <= 157.5 and ddgree[i, j] > 112.5) or (ddgree[i, j] <= 247.5 and ddgree[i, j] > 202.5):g1 = NMS[i - 1, j - 1]g2 = NMS[i + 1, j + 1]else:g1 = NMS[i, j - 1]g2 = NMS[i, j + 1]if NMS[i, j] < g1 or NMS[i, j] < g2:NMS[i, j] = 0nms_r = np.uint8(np.copy(NMS))cv2.imshow('nms', nms_r)# 双阈值算法检测、连接边缘W3, H3 = NMS.shapeDT = np.zeros([W3, H3], dtype=np.uint8)# 定义高低阈值TL = min(threshold1, threshold2)TH = max(threshold1, threshold2)for i in range(1, W3 - 1):for j in range(1, H3 - 1):if (NMS[i, j] < TL):DT[i, j] = 0elif (NMS[i, j] > TH):DT[i, j] = 255else:if NMS[i - 1, j] > TH or NMS[i - 1, j - 1] > TH or NMS[i - 1, j + 1] > TH or NMS[i, j - 1] > TH \or NMS[i, j + 1] > TH or NMS[i + 1, j] > TH or NMS[i + 1, j - 1] > TH or NMS[i + 1, j + 1] > TH: \DT[i, j] = 255return DTimg = cv2.imread('test.jpg')
cv2.imshow('src', img)
result = Canny(img, 60, 120)
cv2.imshow('dst', result)
cv2.waitKey(0)

结果如下:

4、扩展部分

(1)边缘检测算子比较:

(2)边缘提取和边缘跟踪:

Canny算子B站讲解:https://space.bilibili.com/580742386?spm_id_from=333.788.b_765f7570696e666f.1

参考链接:https://www.cnblogs.com/wj-1314/p/9800272.html

https://www.bilibili.com/video/BV1U4411277i?from=search&seid=16066791906732345516

数字图像处理:(5)非微分算子在数字图像处理中的应用相关推荐

  1. 实验1 数字图像处理的MATLAB基础,《数字图像处理(实验部分)》实验1_数字图像处理中MATLAB使用基础...

    <数字图像处理(实验部分)>教案 实验一:数字图像处理中MATLAB使用基础实验 一. MATLAB软件安装 二. 进入MATLAB运行环境 三. MATLAB编程基础 3.1.变量 预定 ...

  2. 数字图像处理学习笔记4:图像增强之空间滤波2(一阶微分锐化滤波(梯度),二阶微分锐化(拉普拉斯),非锐化掩蔽)

    文章目录 前言 一.一阶微分和二阶微分的定义 二.一阶微分锐化滤波:梯度 1.梯度 2.sobel算子及MATLAB代码 二.二阶微分锐化滤波:拉普拉斯算子 1.拉普拉斯算子 2.拉普拉斯算子MATL ...

  3. matlab 图像处理 ppt,第五章 matlab在数字图像处理中的应用.ppt

    1.第五章 matlab在数字图像处理中的应用,数字图像的读入,A=imread(filename,fmt): 将文件名为filename,扩展名为fmt(图像文件格式)表示的图像文件中的数据读到矩阵 ...

  4. 《数字图像处理》自学笔记(一)

    学习目标:数字图像处理 学习内容: MOOC课 武汉大学 <数字图像处理>自学 https://www.icourse163.org/learn/WHU-1002332010?tid=14 ...

  5. 数字图像处理学习--导数运算与锐化空间滤波

    引言 本文内容是老猿学习冈萨雷斯<数字图像处理>后的学习总结和感悟,中文版在介绍本文内容时翻译存在比较多的问题,本文是对中文版的完善.补充以及学习感悟的总结.在学习过程中对一些细节进行了一 ...

  6. 数字图像处理知识点总结概述

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 1.直方图:一幅图像由不同灰度值的像素组成,图像中灰度的分布情况是 ...

  7. 数字图像处理-知识体系概括

    转载自:http://blog.csdn.net/hitwengqi/article/details/8292675 目录 一.数字图像基础... 3 二.数字图像存储与显示... 3 三.图像变换. ...

  8. 数字图像处理知识体系小结(转)

    在浏览博客是看到一篇文章,对图像处理领域的算法和理论总结的很到位,便转载了过来. 本文转自 http://blog.csdn.net/hitwengqi/article/details/8292675 ...

  9. 数字图像处理知识体系小结

    http://blog.csdn.net/hitwengqi/article/details/8292675 目录(?)[+] 一数字图像基础 二数字图像存储与显示 三图像变换 四形态学图像处理 五图 ...

最新文章

  1. Android 自定义圆形图片
  2. C++与C# 中static 成员变量的区别
  3. linux下的open的注意事项
  4. C#集合类型总结和性能分析
  5. Ext Designer Preview生成代码在html上显示步骤
  6. 前端做聊天软件的功能难点
  7. oracle数据库如何写翻页_ORACLE翻页SQL语句
  8. jQuery基础集锦——插件开发
  9. 使用wget下载KITTI数据集
  10. 在线计算机免费课程表,Simple课程表
  11. 回溯法——最大团问题c
  12. c++直方图匹配终极版,支持任意通道数(opencv版本)
  13. 一加5t Android 第三方系统上BL锁
  14. 决策树在机器学习的理论学习与实践
  15. php 生成excel表格,PHP 生成Excel表格两种方法
  16. Python爬取当当网APP数据
  17. Scratch与物理·天文:模拟中国嫦娥探月工程,探索月球的背面!
  18. 【Solr】——搜索引擎的部署及使用
  19. 高群耀:移动电影院2.0四大功能实现了用户“观影社交化”
  20. RabbitMQ(Java操作工作队列-按劳分配方式)

热门文章

  1. 2021年大数据Hadoop(十四):HDFS的高可用机制
  2. 2021年大数据Hadoop(二):Hadoop发展简史和特性优点
  3. [JS][dp]题解 | #打家劫舍(一)#
  4. C++实现九九乘法表
  5. 微信小程序 文字换行
  6. vue 搭建脚手架 的教程
  7. INSTALL_FAILED_TEST_ONLY
  8. PyTorch 笔记(18)— torch.optim 优化器的使用
  9. Python 程序员常见错误
  10. 导入drupal中文语言包