一、Canny边缘提取步骤

文中用python实现canny算子,Canny算子的步骤为:

  • 1)图像灰度预处理
  • 2)对每个像素求梯度
  • 3)求每个点处最大梯度的编码
  • 4)非极大值抑制,保证梯度编码的唯一性。
  • 5)通过阈值,将边缘像素抽取出来;

二、高斯平滑算子代码

在jupyter-notebook下,通过下列代码学习,可以了解canny算子全过程;并按自己的理解进行修改学习:

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import cv2img = plt.imread('d:/images/mchine.jpg')%matplotlib inline
sigma1 = sigma2 = 1
sum = 0
gaussian = np.zeros([5, 5])
for i in range(5):for j in range(5):gaussian[i, j] = math.exp(-1 / 2 * (np.square(i - 2) / np.square(sigma1)  # 生成二维高斯分布矩阵+ (np.square(j - 2) / np.square(sigma2)))) / (2 * math.pi * sigma1 * sigma2)sum = sum + gaussian[i, j]gaussian = gaussian / sum
sns.heatmap( gaussian )plt.show()

显示高斯平滑算子的热图。

三、三通道图转换成灰度图

def rgb2gray(rgb):return np.dot(rgb[..., :3], [0.299, 0.587, 0.114])
gray = rgb2gray(img)
W, H = gray.shape
sns.heatmap( gray )

灰度变换后,图像的热图:

四、生成梯度图

new_gray = cv2.GaussianBlur(gray, (5, 5), 0)
# step2.增强 通过求梯度幅值
W1, H1 = new_gray.shape
dx = np.zeros([W1 - 1, H1 - 1])
dy = np.zeros([W1 - 1, H1 - 1])
d  = np.zeros([W1 - 1, H1 - 1])
for i in range(W1 - 1):for j in range(H1 - 1):dx[i, j] = new_gray[i, j + 1] - new_gray[i, j]dy[i, j] = new_gray[i + 1, j] - new_gray[i, j]d[i, j]  = np.sqrt(np.square(dx[i, j]) + np.square(dy[i, j]))  # 图像梯度幅值作为图像强度值
sns.heatmap( d)

梯度图:

五、非极大值抑制

5.1 canny算子的双阈值原理

1) canny算子设定有两个阈值,低阈值 和 高阈值

2) canny算子使每个像素点位置上能够算出一个梯度值,称为“实际梯度”

3)当 “实际梯度 > 高阈值” 该点被录取为“边缘点”

4)当 “实际梯度 < 低阈值” 该点被录取为“非边缘点(也叫背景点)”

5)当    “低阈值< 实际梯度低< 高阈值 ”  情况复杂了,需要判别

            如果周围相邻的点都没有大于低阈值,该点被录取为背景点(非边缘点)。

            如果周围相邻的点都有大于低阈值的,就比较那个相邻点和该点梯度,凡梯度大者被录取为边缘点。

( 不知以上叙述是否清楚?下图,因为所有梯度都取绝对值,因此,梯度最小为0 )

程序如下:

W2, H2 = d.shape
NMS = np.copy(d)
NMS[0, :] = NMS[W2 - 1, :] = NMS[:, 0] = NMS[:, H2 - 1] = 0
for i in range(1, W2 - 1):for j in range(1, H2 - 1):if d[i, j] == 0:NMS[i, j] = 0else:gradX = dx[i, j]gradY = dy[i, j]gradTemp = d[i, j]# 如果Y方向幅度值较大if np.abs(gradY) > np.abs(gradX):weight = np.abs(gradX) / np.abs(gradY)grad2 = d[i - 1, j]grad4 = d[i + 1, j]# 如果x,y方向梯度符号相同if gradX * gradY > 0:grad1 = d[i - 1, j - 1]grad3 = d[i + 1, j + 1]# 如果x,y方向梯度符号相反else:grad1 = d[i - 1, j + 1]grad3 = d[i + 1, j - 1]# 如果X方向幅度值较大else:weight = np.abs(gradY) / np.abs(gradX)grad2 = d[i, j - 1]grad4 = d[i, j + 1]# 如果x,y方向梯度符号相同if gradX * gradY > 0:grad1 = d[i + 1, j - 1]grad3 = d[i - 1, j + 1]# 如果x,y方向梯度符号相反else:grad1 = d[i - 1, j - 1]grad3 = d[i + 1, j + 1]gradTemp1 = weight * grad1 + (1 - weight) * grad2gradTemp2 = weight * grad3 + (1 - weight) * grad4if gradTemp >= gradTemp1 and gradTemp >= gradTemp2:NMS[i, j] = gradTempelse:NMS[i, j] = 0# plt.imshow(NMS, cmap = "gray")# step4. 双阈值算法检测、连接边缘
W3, H3 = NMS.shape
DT = np.zeros([W3, H3])
# 定义高低阈值
TL = 0.31 * np.max(NMS)
TH = 0.4 * np.max(NMS)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] = 255elif ((NMS[i - 1, j - 1:j + 1] < TH).any() or (NMS[i + 1, j - 1:j + 1]).any()or (NMS[i, [j - 1, j + 1]] < TH).any()):DT[i, j] = 255
# newDT = DT.astype(np.uint8)cv2.imshow( "gray",DT)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite("parts4.jpg",DT)

三、结果展示

图像处理:python实现canny算子相关推荐

  1. Python实现Canny算子

    Canny算子 Canny算子是提取图像边缘的经典算法,在之前的基础学习过程中写过关于canny的python代码,最近的项目中需要用到才发现当初学的有所缺陷. Canny算子的基本步骤: 使用高斯滤 ...

  2. 图像处理:推导Canny边缘检测算法

    目录 概述 最优边缘检测 算法实现的步骤 1.灰度化与高斯滤波 2.计算图像的梯度和梯度方向 3.非极大值抑制 4.双阈值筛选边缘 5.利用滞后的边界跟踪 6.在图像中跟踪边缘 数学推导 Opencv ...

  3. 边缘检测Sobel、laplacian、canny算子

    1.图像边缘检测 图像边缘检测对于分析图像中的内容.实现图像中物体的分割.定位等具有重要的作用.边缘检测大大减少了源图像的数据量,剔除了与目标不相干的信息,保留了图像重要的结构属性.常用的图像边缘检测 ...

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

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

  5. c#用canny算子做边缘提取_【图像处理】边缘检测

    边缘检测 sobel sobel是最常见也是最常用的边缘检测算子.一般来说,当我们想要获取图像的边缘时,首先想到的就是像素值发生突变的位置,而如何用数学表达来刻画"突变",一个很好 ...

  6. c++gdal如何在大图像中截取小图像并获取其图像信息_【图像处理】OpenCV系列十 --- 边缘检测之Canny算子...

    上一篇我们学习了图像处理形态学相关知识点,相信大家学习之后已经对形态学有了足够的理解了,那么接下来,我们一起来学习一下图像处理中的边缘检测吧!我们将会重点学习边缘检测各种算子和滤波器 --- Cann ...

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

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

  8. 图像处理——Canny算子

    首先感谢以下两位的渊博知识: (1)爱鱼         https://www.cnblogs.com/mightycode/p/6394810.html (2)mitutao   https:// ...

  9. canny算子的python实现以及pytorch实现

    canny算子的python实现以及pytorch实现 canny的python实现 canny的pytorch实现 canny的python实现 参考Canny边缘检测算法(python 实现) i ...

最新文章

  1. 数据通信技术(二:交换机配置管理)
  2. Python:Bug 官网不要了,全迁去 GitHub
  3. python读取输入流_Python读取实时数据流教程
  4. Hyper-V 内存管理必须知道的
  5. 基于 Spring Boot 的 Restful 风格实现增删改查
  6. 基于SEAL库实现PSI-报错实录1
  7. python实现二分查找算法_python实现二分查找算法
  8. Django输入日期返回第几天time
  9. What code you will get when you create a wcf library
  10. kafka 脚本发送_Kafka笔记归纳(第五部分:一致性保证,消息重复消费场景及解决方式)...
  11. 【OSGI】Error osgi xx Invalid value for DynamicImport-Package dynamic.import.pack
  12. 适合初学者的sql_适用于初学者SQL多重连接示例
  13. java怎样才算高级_怎样才算是一名java高手?
  14. 【医疗影像处理】Erosion and Dilation of medical images masks using scipy.ndimage in python
  15. python with as有什么好处?
  16. 关于vscode CloudMusic 插件无法登陆
  17. python hello world程序代码_第一个python程序 helloworld
  18. python猜数字十次、猜对输出猜了多少次_python-猜数字小练习
  19. python无限循环一段句子,python无限循环语句如何实现
  20. 常见外贸英文术语(下)

热门文章

  1. 线性代数笔记:Kronecker积
  2. Spring 的 BeanUtils 踩坑记,你是不是遇到过这些问题?
  3. matlab从入门到精通-常用的几种缺失值处理方法
  4. R语言实战应用精讲50篇(十四)-R语言构建层次分析模型
  5. MATLAB实战系列(四)-导入txt文件技巧大全
  6. MATLAB实战系列(三)- 如何将MATLAB直接转成C/C++代码
  7. hadoop学习--K-Means(聚类算法)
  8. python爬虫分析大学排名_Python爬虫获得国内高校排名,python,获取,大学排名
  9. idea console中文乱码_Python3的字符编码乱码问题解决思路
  10. Hadoop put file 错误:fs.FSInputChecker: Found checksum error