边缘检测

如何检测边缘

利用差分,设置一个阈值,如果差分得到的数值大于此阈值,就可以视为边缘。

计算过程

  1. 使用相应边缘检测滤波器(如果是卷积核需要进行上下左右翻转);
  2. 按照卷积方式计算边缘检测结果。

常见的边缘检测算子:

  1. Robert算子:
    [ 1 0 0 − 1 ] \begin{bmatrix} 1 & 0\\ 0 & -1 \end{bmatrix} [1001]

    [ 0 1 − 1 0 ] \begin{bmatrix} 0 & 1\\ -1 & 0 \end{bmatrix} [0110]
    类似一维差分,对于图像对应的二维矩阵
    E x = ∂ f ( x , y ) ∂ x = f ( x , y ) − f ( x − 1 , y − 1 ) E_x = \frac{\partial f(x,y)}{\partial x} = f(x,y) - f(x-1,y-1) Ex=xf(x,y)=f(x,y)f(x1,y1)
    E y = ∂ f ∂ y = f ( x − 1 , y ) − f ( x , y − 1 ) E_y = \frac{\partial f}{\partial y} = f(x-1,y) - f(x,y-1) Ey=yf=f(x1,y)f(x,y1)
  2. Sobel算子卷积核:最常用
    [ − 1 0 1 − 2 − 1 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1\\ -2 & -1 & 2\\ -1 & 0 & 1 \end{bmatrix} 121010121

    [ 1 2 1 0 0 0 − 1 − 2 − 1 ] \begin{bmatrix} 1 & 2 & 1\\ 0 & 0 & 0\\ -1 & -2 & -1 \end{bmatrix} 101202101
    ∂ f ( x , y ) ∂ x = [ f ( x − 1 , y − 1 ) + 2 f ( x − 1 , y ) + f ( x − 1 , y + 1 ) ] − [ f ( x + 1 , y − 1 ) + 2 f ( x + 1 , y ) + f ( x + 1 , y + 1 ) ] \frac{\partial f(x,y)}{\partial x} = [f(x-1,y-1) + 2f(x-1,y) + f(x-1,y+1)] - [f(x+1,y-1) + 2f(x+1,y) + f(x+1,y+1)] xf(x,y)=[f(x1,y1)+2f(x1,y)+f(x1,y+1)][f(x+1,y1)+2f(x+1,y)+f(x+1,y+1)]
    ∂ f ( x , y ) ∂ y = [ f ( x − 1 , y + 1 ) + 2 f ( x , y + 1 ) + f ( x + 1 , y − 1 ) ] − [ f ( x − 1 , y − 1 ) + 2 f ( x , y ) + f ( x + 1 , y − 1 ) ] \frac{\partial f(x,y)}{\partial y} = [f(x-1,y+1) + 2f(x,y+1) + f(x+1,y-1)] - [f(x-1,y-1) + 2f(x,y) + f(x+1,y-1)] yf(x,y)=[f(x1,y+1)+2f(x,y+1)+f(x+1,y1)][f(x1,y1)+2f(x,y)+f(x+1,y1)]
    边缘强度:
    M ( x , y ) = E x 2 ( x , y ) + E y 2 ( x , y ) M(x,y) = \sqrt{{E_x}^2(x,y)+{E_y}^2(x,y)} M(x,y)=Ex2(x,y)+Ey2(x,y)
    边缘方向:
    θ ( x , y ) = t a n − 1 ( E y ( x , y ) E x ( x , y ) ) \theta(x,y) = tan^{-1}(\frac{E_y(x,y)}{E_x(x,y)}) θ(x,y)=tan1(Ex(x,y)Ey(x,y))
  3. Laplace算子:
    △ f ( x , y ) = ∇ 2 f ( x , y ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \bigtriangleup f(x,y) = \nabla^2f(x,y) = \frac{\partial ^2f}{\partial x^2} + \frac{\partial ^2f}{\partial y^2} = f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) f(x,y)=2f(x,y)=x22f+y22f=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)
    [ 0 1 0 1 − 4 1 0 1 0 ] \begin{bmatrix} 0 & 1 & 0\\ 1 & -4 & 1\\ 0 & 1 & 0 \end{bmatrix} 010141010

    [ 1 1 1 1 − 8 1 1 1 1 ] \begin{bmatrix} 1 & 1 & 1\\ 1 & -8 & 1\\ 1 & 1 & 1 \end{bmatrix} 111181111
  4. LoG算子
    △ [ G σ ( x , y ) ∗ f ( x , y ) ] = [ △ G σ ( x , y ) ] ∗ f ( x , y ) = L o G ∗ f ( x , y ) \bigtriangleup [G_\sigma(x,y) * f(x,y)] = [\bigtriangleup G_\sigma(x,y)] * f(x,y) = LoG * f(x,y) [Gσ(x,y)f(x,y)]=[Gσ(x,y)]f(x,y)=LoGf(x,y)
    [ − 2 − 4 − 4 − 4 − 2 − 4 0 8 0 − 4 − 4 8 24 8 − 4 − 4 0 8 0 − 4 − 2 − 4 − 4 − 4 − 2 ] \begin{bmatrix} -2 & -4 & -4 & -4& -2\\ -4 & 0 & 8 & 0 & -4\\ -4 & 8 & 24 & 8& -4\\ -4 & 0 & 8 & 0 & -4\\ -2 & -4 & -4 & -4& -2 \end{bmatrix} 24442408044824844080424442

总结

  1. 边缘检测即图像差分
  2. 常见边缘检测算子包括Robert算子,Sobel算子,LoG算子等,其中Sobel算子最为常用
  3. 二维图像的边缘具有强度和方向两个性质,比一维差分多了一个性质

Canny算子

已有方法容易受以下问题影响:噪声;断裂;虚检(渐变灰度)
Canny算子核心优点:边缘可自动连通

算法步骤:

  1. 平滑图像;
  • 使用高斯函数完成平滑,以下以 5 ∗ 5 5*5 55为例:
    G ( x , y ) = 1 2 π σ e x p [ − x 2 + y 2 σ 2 ] G(x,y) = \frac{1}{\sqrt{2\pi}\sigma}exp[-\frac{x^2+y^2}{\sigma^2}] G(x,y)=2π σ1exp[σ2x2+y2]
    K = 1 139 [ 2 4 5 4 2 4 9 12 9 4 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] K = \frac{1}{139} \begin{bmatrix} 2 & 4 & 5 & 4& 2\\ 4 & 9 & 12 & 9 & 4\\ 5 & 12 & 15 & 12 & 5\\ 4 & 9 & 12 & 9 & 4\\ 2 & 4 & 5 & 4& 2 \end{bmatrix} K=1391245424912945121512549129424542
  1. 计算梯度(幅值和方向);
  • 使用Sobel边缘检测算子对平滑图像进行x和y方向的边缘检测,假设得到的结果分别为 E x , E y E_x,E_y Ex,Ey
  • 进一步计算梯度幅值和方向;
    M ( x , y ) = E x 2 ( x , y ) + E y 2 ( x , y ) M(x,y) = \sqrt{{E_x}^2(x,y)+{E_y}^2(x,y)} M(x,y)=Ex2(x,y)+Ey2(x,y)
    θ ( x , y ) = t a n − 1 ( E y ( x , y ) E x ( x , y ) ) \theta(x,y) = tan^{-1}(\frac{E_y(x,y)}{E_x(x,y)}) θ(x,y)=tan1(Ex(x,y)Ey(x,y))
  • 方向离散化:离散化为上下左右和斜45°共四个方向
    在这里插入图片描述
  1. 梯度幅值进行非极大值抑制;
  • 细化梯度幅值图像中的屋脊带,只保留幅值局部变化最大的点:
    使用一个 3 ∗ 3 3*3 33邻域作用于幅值阵列的所有点。在每一点上,邻域的中心像素与沿梯度方向的两个梯度幅值的插值结果进行比较,仅保留极大值点。
  1. 自动边缘连接
  • 对上一步得到的图像使用低、高阈值 τ 1 τ 2 \tau_1\tau_2 τ1τ2阈值化,得到三幅图像
    Γ 1 [ i , j ] ( M ( i , j ) < τ 1 ) Γ 2 [ i , j ] ( τ 1 ≤ M ( i , j ) ≤ τ 2 ) Γ 3 [ i , j ] ( M ( i , j ) > τ 2 ) %\left\{ \begin{array}{rcl} \Gamma_1[i,j] (M(i,j)<\tau_1)\\ \Gamma_2[i,j] (\tau_1\leq M(i,j)\leq\tau_2)\\ \Gamma_3[i,j] (M(i,j)>\tau_2) %\end{array}\right Γ1[i,j](M(i,j)<τ1)Γ2[i,j](τ1M(i,j)τ2)Γ3[i,j](M(i,j)>τ2)
  • Γ 1 \Gamma_1 Γ1对应假边缘,去除
  • Γ 3 \Gamma_3 Γ3对应真边缘,全部保留
  • Γ 2 \Gamma_2 Γ2连接:临接像素中是否有属于 Γ 3 \Gamma_3 Γ3的像素
  • 通过察看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘像素点就可以保留为真实的边缘。

总结

Canny算子的基本优点在于检测准确、对噪声稳健,在实际中广泛应用

程序实例

相关函数

  • Sobel算子边缘检测
dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
  • 拉普拉斯滤波
dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
  • Canny算子
dst = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
  • 形态学滤波
dst = cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
#op:形态学操作,包括MORPH_ERODE,MORPH_DILATE, MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT, MORPH_HITMISS
# iterations: 进行操作的次数 
dst = cv2.getStructuringElement(shape, ksize[, anchor])

实例

import cv2
import numpy as np

def gauss_noise(image, mean = 0, var = 0.001):
    """
    添加高斯噪声
    mean:  均值
    var: 方差
    """
    image = np.array(image/255, dtype = float)
    noise = np.random.normal(mean, var ** 0.5, image.shape)
    out = image + noise
    if out.min() < 0:
        low_clip = -1.
    else:
        low_clip = 0.
    out = np.clip(out, low_clip, 1.0)
    out = np.uint8(out*255)
    # cv.imshow("Gauss_noise", out)
    return out

filename = 'C:/python/img/lena.jpg'
img = cv2.imread(filename, 0)

# Sobel算子边缘检测
sobel = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize = 3)
# Laplacian边缘检测
laplacian = cv2.Laplacian(img, cv2.CV_16S)
# Canny边缘检测,最小阈值50,最大阈值120
canny = cv2.Canny(img, 50, 120)

sobel_show = cv2.convertScaleAbs(sobel) #将18位浮点数转换
lap_show = cv2.convertScaleAbs(laplacian)
cv2.imshow('Sobel', sobel_show)
cv2.imshow('Laplacian', lap_show)
# 显示Canny边缘检测成果
cv2.imshow('Canny', canny)

nimg = gauss_noise(img)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
eroded = cv2.erode(img, kernel)
dilated = cv2.dilate(img, kernel)

opened = cv2.morphologyEx(nimg, cv2.MORPH_OPEN, kernel)
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
#对原始图像先开后闭可以有效去除噪声
#以下分别为原视图像腐蚀、膨胀,以及加噪声开、闭运算结果
cv2.imshow('Noised image', nimg)
cv2.imshow('Eroded image', eroded)
cv2.imshow('Dilated image', dilated)
cv2.imshow('Opened image', opened)
cv2.imshow('Closed image', closed)

#以下分别计算并显示梯度、顶帽和黑帽变换结果
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('Image gradient', gradient)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
bottomhat = cv2.morphologyEx((img, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('Tophat', tophat)
cv2.imshow('Blackhat', bottomhat)
#利用顶帽和黑帽变换进行图像增强,并显示结果
enhanced = img + tophat - bottomhat
cv2.imshow('Enhanced image', enhanced)
#计算击中或击不中(HIT)变换结果并显示
kernel = np.array(([0,1,0], [1,-1,1],[0,1,0]), dtype = 'int')
hmt = cv2.morphologyEx(img, cv2.MORPH_HITMISS, kernel)
cv2.imshow('Hit or miss transform', hmt)

cv2.waitKey()
cv2.destroyAllWindows()

总结

  1. OpenCV提供了Sobel,Canny等函数用于边缘检测
  2. OpenCV提供了MorphologyEx函数用于形态学滤波

数学形态学扩展应用

图像形态学基本操作——边缘梯度(gradient):

形态学定义为灰度膨胀图像与灰度腐蚀图像的插值:
r = ( A ⊕ B ) − ( A ⊙ B ) r = (A\oplus B) - (A\odot B) r=(AB)(AB)

图像形态学基本操作——顶帽与黑帽变换

  • 顶帽变换(tophat)定义为图像与其开运算的插值:
    r = A − ( A ∘ B ) r = A - (A\circ B) r=A(AB)
    顶帽操作适用于原始图像背景是暗的,前景是亮的,其可以将明亮的前景突出出来。
  • 黑帽变换(blackhat)定义为图像闭运算与其自身的插值:
    r = ( A ∙ B ) − A r = (A\bullet B) - A r=(AB)A
    黑帽变换可以将明亮背景中暗色的前景突出出来。

顶帽变换和黑帽变换的结合使用能够应用于灰度图像的对比度增强,常用做法:将源图像加上顶帽变换再减去黑帽变换。

图像形态学基本操作——击中或击不中变换(HMT)

输出图像由所有在 B 1 B_1 B1中匹配的像素(击中)和未在 B 2 B_2 B2中匹配的像素(击不中)组成:
r = ( A ⊖ B 1 ) ∩ ( A C ⊖ B 2 ) r = (A\ominus B_1) \cap (A^C\ominus B_2) r=(AB1)(ACB2)
结构元素 B 1 B_1 B1和原视图像做腐蚀, B 2 B_2 B2与原始图像的补做腐蚀运算。
B 1 B_1 B1 B 2 B_2 B2可合并成一个元素 B B B,如下示例:
[ 0 1 0 1 0 1 0 1 0 ] [ 0 0 0 0 1 0 0 0 0 ] [ 0 1 0 1 − 1 1 0 1 0 ] \begin{bmatrix} 0 & 1 & 0\\ 1 & 0 & 1\\ 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} 0 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} 0 & 1 & 0\\ 1 & -1 & 1\\ 0 & 1 & 0 \end{bmatrix} 010101010000010000010111010
只有比四邻域像素值都小的位置才会保留下来。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值