前言
边缘(
edge
)是图像中局部亮度、纹理或颜色发生剧烈变化的位置。这些变化往往发生在物体与背景、物体与物体、区域与区域之间的边界上,边缘蕴含了图像中物体的形状信息和场景的结构信息,这些信息在视觉系统中扮演着至关重要的角色。
边缘检测是
图像处理
中用于识别图像中亮度突变区域(如物体边界)的关键技术,其核心原理是通过计算图像梯度或二阶导数来定位像素值剧烈变化的位置。以下是其核心原理和常用公式的详细说明:
边缘检测是图像处理中用于识别图像中亮度突变区域(如物体边界)的关键技术,其核心原理是通过计算图像梯度或二阶导数来定位像素值剧烈变化的位置。
以下是其核心原理和常用公式的详细说明:
一、基本原理
梯度检测边缘处像素灰度值变化剧烈,梯度向量的模(强度)和方向可描述这种变化:
梯度向量:
梯度模(边缘强度):
梯度方向(边缘法向):
二阶导数检测通过拉普拉斯算子检测灰度变化的拐点(零交叉点):
拉普拉斯算子:
二、常用边缘检测算子及公式
- 一阶微分算子
Sobel算子使用两个3×3卷积核分别计算水平和垂直梯度:
梯度计算:
Prewitt算子
类似 Sobel,但权值更简单:
- 二阶微分算子
Laplacian算子离散形式的拉普拉斯卷积核:
边缘位于输出图像的零交叉点处。
- Canny边缘检测(多步骤算法)
高斯滤波:平滑图像以减少噪声。
梯度计算(常用Sobel算子)。
非极大值抑制:保留梯度方向上的局部最大值,细化边缘。
双阈值检测:
高阈值 :确定强边缘。
低阈值 :连接弱边缘(需与强边缘连通)。
三、数学推导示例(Sobel算子)
对图像 ,在点 处的梯度近似为:
Sobel算子通过加权邻域像素提高了抗噪性。
四、关键注意事项
**噪声敏感性:一阶算子对噪声敏感,通常需先高斯滤波(如Canny)。
阈值选择:影响边缘连续性和伪边缘数量(如Canny的双阈值)。
算子选择:
Sobel/Prewitt:简单快速,适合实时系统。
Laplacian:对噪声敏感,但能检测细边缘。
Canny:效果优,但计算复杂度高。**
五、实现边缘检测算法
单独对x轴方向求导的Sobel算法
import cv2 img = cv2.imread('lenna.jpg',0) # 沿着x轴方向的Sobel算子 kx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) # 沿着y轴方向的Sobel算子 ky=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) # # 将结果转换为绝对值并缩放到8位无符号整数(便于显示) kx_abs=cv2.convertScaleAbs(kx) # grad=cv2.addWeighted(kx,0.5,ky,0.5,0) # 显示图像 cv2.imshow('image',kx_abs) cv2.waitKey(0) cv2.destroyAllWindows()
对x轴和y方向求导的Sobel算法
import cv2 img = cv2.imread('lenna.jpg',0) # 沿着x轴方向的Sobel算子 kx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) # 沿着y轴方向的Sobel算子 ky=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) # # 将结果转换为绝对值并缩放到8位无符号整数(便于显示) kx_abs=cv2.convertScaleAbs(kx) ky_abs=cv2.convertScaleAbs(ky) E=kx_abs + ky_abs # 显示图像 cv2.imshow('image',E) cv2.waitKey(0) cv2.destroyAllWindows()
虽然Sobl算子中加入了类似于高斯滤波的算子,使其对图像噪声有一定的抑制性,但是区分图像噪声和边缘本身是一个很困难的任务,特别是图像中常常会存在由杂乱纹理产生的虚假边缘。通过图像平滑能够在一定程度上抑制噪声,但是,平滑也会使得图像变得模糊,降低边缘的强度,所以对图像的平滑程度应当是可以调节的,边缘检测的结果应该也是多尺度的(如
可以调节平滑程度)。接下来,我们介绍一种多尺度边缘检测算法Cany边缘检测算法。
Canny算法可能是
计算机视觉
中使用最广泛的边缘检测算法,它通常通过以下几步实现:
**(1)图像平滑,即抑制噪声:
(2)图像梯度计算:
(3)边缘强度非极大值抑制(non-maximum suppression,NMS):
(4)基于滞后的阔值化(hysteresis-based thresholding)的边缘定位。**
代码实现
import cv2 import numpy as np # 读取图像并转换为灰度图 img = cv2.imread('lenna.jpg', 0) # Canny边缘检测 # 参数说明: # img: 输入图像 # threshold1: 第一个阈值,用于边缘连接 # threshold2: 第二个阈值,用于强边缘检测 # apertureSize: Sobel算子的大小,默认为3 # L2gradient: 是否使用更精确的L2范数计算梯度大小(True),还是使用L1范数(False) edges = cv2.Canny(img, threshold1=100, threshold2=200, apertureSize=3, L2gradient=True) # 显示结果 cv2.imshow('Original', img) cv2.imshow('Canny Edges', edges) cv2.waitKey(0) cv2.destroyAllWindows()
不同参数得到的结果也各不相同

我们发现,当高斯核标准差变大时,边缘检测的结果会对细小纹理的变化更为鲁棒,但是重要的边缘也会丢失。因此,我们需要权衡图像平滑和降低噪声之间的权重。
小结
Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。它结合高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。它对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。
Canny 边缘检测算法是被业界公认的性能最为优良的边缘检测算法之一。Canny算法不是像Roberts、Prewitt、Sobel等这样简单梯度算子或锐化模板,它是在梯度算子基础上,引入了一种能获得抗噪性能好、定位精度高的单像素边缘的计算策略。
评论加载中…