canny算子_Canny边缘检测算法

4730898c21438972ffc11dba3b3bc187.png

PS:计算机视觉课程的一项大作业,作为门外汉,在网上查找资料学习和复现时踩了一些坑,在完成作业后分享一下,希望后面的小白同学少走弯路。

1.问题描述

在计算机视觉/机器视觉领域,图像分割的应用十分普遍,它是指将数字图像细分为多个图像子区域的过程。图像分割的目的是简化或改变图像的表示形式,使得图像更容易理解和分析。它的基本形式通常为定位图像中的物体和边界,结果是图像上子区域或轮廓线的集合。图像分割方法主要包括阈值处理(二值化)、聚类法、边缘检测和区域生长等。对于图像分割问题的求解没有统一范式,通常要与领域知识充分结合,才能更为有效地解决。

边缘检测是基于灰度突变来分割图像的常用方法,其实质是提取图像中不连续部分的特征。目前常见边缘检测算子有差分算子、Roberts算子、Sobel算子、Prewitt算子、Log算子以及Canny算子等。其中,Canny算子是由计算机科学家John F. Canny于1986年提出的一种边缘检测算子,是目前理论上相对最完善的一种边缘检测算法。在MATLAB、OpenCV等常用图像处理工具中已有内置的Canny算子API,本次大作业将依据Canny算子的算法原理在MATLAB环境中进行复现,并与MATLAB内置Canny算子的效果进行对比。

2.算法原理

基于Canny算子的边缘检测主要有5个步骤,依次是高斯滤波、像素梯度计算、非极大值抑制、滞后阈值处理和孤立弱边缘抑制。

(1) 高斯滤波

高斯滤波使用的高斯核是具有

两个维度的高斯函数,且两个维度上标准差一般取相同,形式为:

高斯滤波,即使用即使用某一尺寸的二维高斯核与图像进行卷积。由于数字图像的数据形式为离散矩阵,高斯核是对连续高斯函数的离散近似,通过对高斯曲面进行离散采样和归一化得出。例如,尺

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来给你讲一下使用Canny算子进行图像边缘检测的步骤。 Canny算子是一种常用的边缘检测算法,其步骤如下: 1. 对图像进行灰度化处理,将彩色图像转换为灰度图像。 2. 对灰度图像进行高斯滤波,以平滑图像,去除噪声。 3. 计算图像中每个像素点的梯度值和方向,采用Sobel算子计算梯度值和方向。 4. 对梯度值进行非极大值抑制,即在梯度方向上,只保留局部极大值点,其余点置零。 5. 对非极大值抑制后的图像进行双阈值处理,即将图像中的像素点分为强边缘点、弱边缘点和非边缘点三类,采用两个阈值进行划分。 6. 对双阈值处理后的图像进行边缘连接处理,即将弱边缘点沿着强边缘点连接起来,形成完整的边缘。 最终,我们可以得到一张二值图像,其中白色表示检测到的边缘,黑色表示背景。 Python中实现Canny算子边缘检测的代码如下: ```python import cv2 # 读取图像 img = cv2.imread('img.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯滤波 blur = cv2.GaussianBlur(gray, (3, 3), 0) # 计算梯度值和方向 sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3) sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3) gradient = cv2.sqrt(sobelx**2 + sobely**2) theta = cv2.atan2(sobely, sobelx) # 非极大值抑制 rows, cols = gradient.shape for i in range(1, rows - 1): for j in range(1, cols - 1): if (theta[i, j] >= -np.pi/8 and theta[i, j] < np.pi/8) or (theta[i, j] >= 7*np.pi/8 and theta[i, j] < np.pi) or (theta[i, j] >= -np.pi and theta[i, j] < -7*np.pi/8): if (gradient[i, j] >= gradient[i, j-1]) and (gradient[i, j] >= gradient[i, j+1]): pass else: gradient[i, j] = 0 elif (theta[i, j] >= np.pi/8 and theta[i, j] < 3*np.pi/8) or (theta[i, j] >= -7*np.pi/8 and theta[i, j] < -5*np.pi/8): if (gradient[i, j] >= gradient[i-1, j-1]) and (gradient[i, j] >= gradient[i+1, j+1]): pass else: gradient[i, j] = 0 elif (theta[i, j] >= 3*np.pi/8 and theta[i, j] < 5*np.pi/8) or (theta[i, j] >= -5*np.pi/8 and theta[i, j] < -3*np.pi/8): if (gradient[i, j] >= gradient[i-1, j]) and (gradient[i, j] >= gradient[i+1, j]): pass else: gradient[i, j] = 0 else: if (gradient[i, j] >= gradient[i-1, j+1]) and (gradient[i, j] >= gradient[i+1, j-1]): pass else: gradient[i, j] = 0 # 双阈值处理 high_threshold = np.max(gradient) * 0.3 low_threshold = high_threshold * 0.2 rows, cols = gradient.shape for i in range(rows): for j in range(cols): if gradient[i, j] >= high_threshold: gradient[i, j] = 255 elif gradient[i, j] >= low_threshold and gradient[i, j] < high_threshold: gradient[i, j] = 50 else: gradient[i, j] = 0 # 边缘连接处理 for i in range(1, rows - 1): for j in range(1, cols - 1): if gradient[i, j] == 50: if (gradient[i-1, j-1] == 255) or (gradient[i-1, j] == 255) or (gradient[i-1, j+1] == 255) or \ (gradient[i, j-1] == 255) or (gradient[i, j+1] == 255) or (gradient[i+1, j-1] == 255) or \ (gradient[i+1, j] == 255) or (gradient[i+1, j+1] == 255): gradient[i, j] = 255 else: gradient[i, j] = 0 # 显示边缘检测结果 cv2.imshow('Canny Edge Detection', gradient) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这样就可以通过Canny算子对图像进行边缘检测了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值