边缘检测算法总结及其python实现——二阶检测算子

二阶检测算子
Laplacian算子,Marr-Hildreth(LOG),高斯差分DoG。
1.Laplacian边缘检测
拉普拉斯算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度(▽f)的散度(▽·f)。拉普拉斯算子也是最简单的各向同性微分算子,具有旋转不变性,即将原图像旋转后进行滤波处理给出的结果与先对图像滤波然后再旋转的结果相同。一个二维图像的拉普拉斯算子定义为:
在这里插入图片描述
因为任意阶微分都是线性操作,所以拉普拉斯变换也是一个线性算子。为了以离散形式描述这一公式,在x方向将公式描述成:
在这里插入图片描述
同理,在y方向将公式描述成:
在这里插入图片描述
遵循这三个公式,两个变量的离散拉普拉斯算子为:
在这里插入图片描述
Laplacian常用的算子模板:
4邻域:
在这里插入图片描述
8邻域:
在这里插入图片描述

代码:

import numpy as np
from skimage import data,color,filters
import matplotlib.pyplot as plt

original_img=data.chelsea()
gray_img=color.rgb2gray(original_img)

#using system function
edeg_img=filters.laplace(gray_img,ksize=3)

#self codes
w,h = gray_img.shape
ori_pad = np.pad(gray_img,((1,1),(1,1)),'constant')  #在灰度图像的四周填充一行/一列0

lap4_filter = np.array([[0,1,0],[1,-4,1],[0,1,0]])  #4邻域laplacian算子
lap8_filter = np.array([[0,1,0],[1,-8,1],[0,1,0]])  #8邻域laplacian算子

#4邻域
edge4_img = np.zeros((w,h))
for i in range(w-2):
    for j in range(h-2):
        edge4_img[i,j]=np.sum(ori_pad[i:i+3,j:j+3]*lap4_filter)
        if edge4_img[i,j] < 0:
            edge4_img[i,j] = 0  #把所有负值修剪为0

#8邻域
edge8_img = np.zeros((w,h))
for i in range(w-2):
    for j in range(h-2):
        edge8_img[i,j]=np.sum(ori_pad[i:i+3,j:j+3]*lap8_filter)
        if edge8_img[i,j] < 0:
            edge8_img[i,j] = 0

figure=plt.figure()
plt.subplot(231).set_title('original_img')
plt.imshow(original_img)
plt.subplot(232).set_title('gray_image')
plt.imshow(gray_img)
plt.subplot(233).set_title('edge_image')
plt.imshow(edeg_img)
plt.subplot(234).set_title('edge4_image')
plt.imshow(edge4_img)
plt.subplot(235).set_title('edge8_image')
plt.imshow(edge8_img)
plt.show()

结果(用封装的函数求出来的结果可能存在一些问题,会继续找问题的所在):
在这里插入图片描述
2.Log边缘检测
拉普拉斯边缘检测算子没有对图像做平滑处理,所以对噪声很敏感。因此可以想到先对图像进行高斯平滑处理,然后再与Laplacian算子进行卷积。这就是高斯拉普拉斯算子(laplacian of gaussian)。

下式中G为标准差为 σ \sigma σ(有时 σ \sigma σ也称为空间常数)的二维高斯函数(省略了常数)
在这里插入图片描述
为求 ∇ 2 G \nabla ^{2}G 2G的表达式,执行如下微分:
∇ 2 G ( x , y ) = ∂ G ( x , y ) ∂ x 2 + ∂ 2 G ( x , y ) ∂ y 2 = ∂ ∂ x [ − x σ 2 e − x 2 + y 2 2 σ 2 ] + ∂ ∂ y [ − y σ 2 e − x 2 + y 2 2 σ 2 ] = [ x 2 σ 4 − x 2 σ 2 ] e − x 2 + y 2 2 σ 2 + [ y 2 σ 4 − 1 σ 2 ] e − x 2 + y 2 2 σ 2 \begin{aligned}\nabla ^{2}G\left( x,y\right) =\dfrac {\partial G\left( x,y\right) }{\partial x^{2}}+\dfrac {\partial ^{2}G\left( x,y\right) }{\partial y^{2}}=\dfrac {\partial }{\partial x} \left[ \dfrac {-x}{\sigma^{2}} e^{-\dfrac {x^{2}+y^{2}}{2\sigma^{2}}}\right] +\dfrac {\partial }{\partial y} \left[ \dfrac{-y}{\sigma^{2}}e^{-\dfrac {x^{2}+y^{2}}{2\sigma^{2}}}\right] \\=\left[ \dfrac {x^{2}}{\sigma^{4}}-\dfrac {x^{2}}{\sigma^{2}}\right]e^{-\dfrac {x^{2}+y^{2}}{2\sigma^{2}}}+\left[ \dfrac {y^{2}}{\sigma^{4}}-\dfrac {1}{\sigma^{2}}\right]e^{-\dfrac {x^{2}+y^{2}}{2\sigma^{2}}}\end{aligned} 2G(x,y)=x2G(x,y)+y22G(x,y)=xσ2xe2σ2x2+y2+yσ2ye2σ2x2+y2=[σ4x2σ2x2]e2σ2x2+y2+[σ4y2σ21]e2σ2x2+y2
整理各项后给出如下最终表达式:
∇ 2 G = [   − x 2 + y 2 − 2 σ 2 σ 4 ] e − x 2 + y 2 2 σ 2 \nabla ^{2}G=\left[ \ {-\dfrac {x^{2}+y^{2}-2\sigma^{2}}{\sigma^{4}}}\right]e^{-\dfrac {x^{2}+y^{2}}{2\sigma^{2}}} 2G=[ σ4x2+y22σ2]e2σ2x2+y2
该式成为高斯拉普拉斯(LoG)
Log边缘检测流程:
在这里插入图片描述
LoG常用的卷积模板是(在实践中,会用该模板的负模板):
在这里插入图片描述
代码:

from skimage import data,color,filters
import matplotlib.pyplot as plt
import numpy as np
original_img=data.chelsea()
gray_img=color.rgb2gray(original_img)

#using system function
g_img=filters.gaussian(gray_img,sigma=0)
system_edge_img=filters.laplace(g_img)
w,h=system_edge_img.shape
for i in range(w):
    for j in range(h):
        if system_edge_img[i][j]<0:
            system_edge_img[i][j]=0

#self codes
g_filter=np.array([[0,0,1,0,0],
                   [0,1,2,1,0],
                   [1,2,16,2,1],
                   [0,1,2,1,0],
                   [0,0,1,0,0]])
self_g_img=np.pad(gray_img,((2,2),(2,2)),'constant')
w,h=self_g_img.shape
for i in range(w-4):
    for j in range(h-4):
        self_g_img[i][j]=np.sum(self_g_img[i:i+5,j:j+5]*g_filter)

lap4_filter = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])  # 4邻域laplacian算子
lap8_filter = np.array([[0, 1, 0], [1, -8, 1], [0, 1, 0]])  # 8邻域laplacian算子

g_pad=np.pad(self_g_img,((1,1),(1,1)),'constant')
# 4邻域
edge4_img = np.zeros((w, h))
for i in range(w - 2):
    for j in range(h - 2):
        edge4_img[i, j] = np.sum(g_pad[i:i + 3, j:j + 3] * lap4_filter)
        if edge4_img[i, j] < 0:
            edge4_img[i, j] = 0  # 把所有负值修剪为0

# 8邻域
edge8_img = np.zeros((w, h))
for i in range(w - 2):
    for j in range(h - 2):
        edge8_img[i, j] = np.sum(g_pad[i:i + 3, j:j + 3] * lap8_filter)
        if edge8_img[i, j] < 0:
            edge8_img[i, j] = 0

figure=plt.figure()
plt.subplot(241).set_title('original_img')
plt.imshow(original_img)
plt.subplot(242).set_title('gray_img')
plt.imshow(gray_img)
plt.subplot(243).set_title('system_g_img')
plt.imshow(g_img)
plt.subplot(244).set_title('self_g_edge')
plt.imshow(self_g_img)
plt.subplot(245).set_title('system_edge')
plt.imshow(system_edge_img)
plt.subplot(246).set_title('edge4_img')
plt.imshow(edge4_img)
plt.subplot(247).set_title('edge8_img')
plt.imshow(edge8_img)
plt.show()

结果:
在这里插入图片描述
3.DoG边缘检测
考虑到灰度变化取决于数值范围的事实,有时所用的过程是使用各种 σ \sigma σ值来对一幅图像进行滤波。然后,所得零交叉边缘图与仅为全部图形保留的公共边缘相结合。这种方法可得到很有用的信息,但由于其复杂性,实践中它多被用做使用单一滤波器选择合适的 σ \sigma σ值的设计工具。
Marr and Hildreth[1980]指出过,使用高斯差分(DoG)来近似LoG滤波器是可能的:
在这里插入图片描述
其中 σ 1 > σ 2 \sigma1>\sigma2 σ1>σ2。实验结果表明,在人的视觉系统中,某些“通道”就方向和频率而论是有选择性的,且可以使用1.75:1的标准差比率来建模。Marr和Hildreth建议过,使用16:1的比率不仅可保持这些观察的基本特性,而且还可对LoG函数提供一个更接近的“工程”近似。为在LoG和DoG之间进行有意义的比较,对于LoG, σ \sigma σ值必须按照以下公式选择,以便LoG和DoG具有相同的零交叉:
在这里插入图片描述
当使用这个 σ \sigma σ值时,尽管LoG和DoG的零交叉相同,但它们的幅度大小会不同。可以通过标定这两个函数使得它们兼容,以便它们在原点处有相同的值。
代码:

from skimage import data,color,filters
import numpy as np
import matplotlib.pyplot as plt
original_img=data.chelsea()
gray_img=color.rgb2gray(original_img)

#先对图像进行两次高斯滤波运算
gimg1=filters.gaussian(gray_img,sigma=2)
gimg2=filters.gaussian(gray_img,sigma=1.6*2)

#两个高斯运算的差分
dimg=gimg2-gimg1

#将差归一化
dimg/=2

figure=plt.figure()
plt.subplot(141).set_title('original_img1')
plt.imshow(original_img)
plt.subplot(142).set_title('LoG_img1')
plt.imshow(gimg1)
plt.subplot(143).set_title('LoG_img2')
plt.imshow(gimg2)
plt.subplot(144).set_title('DoG_edge')
plt.imshow(dimg)
plt.show()

结果:
在这里插入图片描述
各边缘检测算子优缺点比较
在这里插入图片描述

  • 9
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LOG算子是指Laplacian of Gaussian算子,用于进行边缘检测。在Python中,可以使用OpenCV库中的函数来实现LOG算子的应用。[3] 首先,需要导入cv2和matplotlib.pyplot库,并定义一个用于显示图片的函数image_show。然后,读取待处理的灰度图像,可以使用cv2.imread函数,并指定参数为0来读取灰度图像。接下来,可以使用cv2.Laplacian函数来应用Laplacian算子进行边缘检测,指定参数cv.CV_64F表示输出图像的深度为64位浮点数,ksize参数表示Laplacian算子的大小。最后,使用image_show函数显示处理后的图像。[3] 另外,如果想要使用LoG算子Laplacian of Gaussian)进行边缘检测,可以先使用cv2.GaussianBlur函数对图像进行高斯模糊处理,然后再使用cv2.Laplacian函数应用Laplacian算子进行边缘检测。具体代码如下所示:[3] ```python import cv2 as cv import matplotlib.pyplot as plt # 封装图片显示函数 def image_show(image): if image.ndim == 2: plt.imshow(image, cmap='gray') else: image = cv.cvtColor(image, cv.COLOR_BGR2RGB) plt.imshow(image) plt.show() if __name__ == '__main__': # 读取灰度图像 img_desk = cv.imread('desk.png', 0) image_show(img_desk) # Laplacian 算子,进行边缘检测 img_lap = cv.Laplacian(img_desk, cv.CV_64F, ksize=3) # 显示图像 image_show(img_lap) # LoG算子Laplacian of Gaussian 进行边缘检测 img_gaussian = cv.GaussianBlur(img_desk, (3, 3), 1) img_log = cv.Laplacian(img_gaussian, cv.CV_64F, ksize=3) # 显示图像 image_show(img_log) ``` 这段代码首先读取了名为'desk.png'的灰度图像,然后分别应用了Laplacian算子LoG算子进行边缘检测,并使用image_show函数显示处理后的图像。[3]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值