首页 科技正文

七台河论坛:高通滤波法、微分算子法、神经网络方式实现边缘检测

admin 科技 2020-05-16 39 0

边缘检测(Edge detection)是图像处置和盘算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度转变显著的点。本文使用多种差异的方式,实现对 Lena 肖像的边缘检测,研究剖析各算法的效果和优缺点。所涉及的方式如下:

  • 高通滤波法

    • 理想高通滤波器
    • Butterworth 高通滤波器
    • 指数高通滤波器
  • 微分算子法

    • Roberts 算子
    • Sobel 算子
    • Laplacian 算子
    • Canny 算子
  • 神经网络方式

    • HED 算法

高通滤波法

图像中的边缘或线条等细节部门与图像频谱的高频分量相对应,因此接纳高通滤波让高频分量顺遂通过,使图像的边缘或线条细节变得清晰,实现边缘提取和图像锐化。

常见的高通滤波器包罗:理想高通滤波器、Butterworth 高通滤波器、指数高通滤波器等。

理想高通滤波器

理想高通滤波器的传递函数 \(H(u, v)\) 知足下式:

\[H(u,v) = \begin{cases} 1, &D(u,v)>D_0 \cr 0, &D(u,v) \leq D_0 \end{cases} \]

理想高通滤波器只是一种理想状态下的滤波器,不能用现实的电子器件实现。

Butterworth 高通滤波器

Butterworth 高通滤波器的传递函数 \(H(u,v)\) 如下:

\[H(u,v)=\frac{1}{1+[D_0/D(u,v)]^{2n}} \]

式中,\(n\) 为阶数,\(D_0\) 为截止频率。

Butterworth 高通滤波器在崎岖频率间的过渡对照平滑,以是由其获得的输出图像的振铃征象不显著。

指数高通滤波器

指数高通滤波器的传递函数 \(H(u,v)\) 如下:

\[H(u,v)=\exp\{-[\frac{D_0}{D(u,v)}]^n\} \]

式中,变量 \(n\) 控制从原点算起的传递函数 \(H(u,v)\) 的增长率。

指数高通滤波器的另一种常用的传递函数如下式所示:

\[H(u,v)=\exp\{[\ln(\frac{1}{\sqrt 2})][\frac{D_0}{D(u,v)}]^n\} \]

代码实现

为了在频率域中实现高通滤波,先通过傅里叶变换获得图像的频谱,凭据差异滤波器的差异传递函数,对频率举行响应的过滤,最后再对其举行傅里叶反变换,获得滤波后的图像。

傅里叶变换

img = plt.imread('images/lena.bmp')
fft_shift = np.fft.fftshift(np.fft.fft2(img))	# 变换后将零频分量移到频谱中央
fft_img = np.log(np.abs(fft_shift))				# 可视化

实现三种滤波器

def distance(shape):		# 盘算每个像素到中央原点的距离
    n, m = shape
    u = np.arange(n)
    v = np.arange(m)
    u, v = np.meshgrid(u, v)
    return np.sqrt((u - n//2)**2 + (v - m//2)**2)
    
def ideal_filter(shape, d0):
    d = distance(shape)
    mask = d > d0
    return mask.astype(int)

def butterworth_filter(shape, d0, order=1):
    d = distance(shape)
    mask = 1 / (1 + (d0 / d)**(2 * order))
    return mask

def exponential_filter(shape, d0, order=1):
    d = distance(shape)
    mask = np.exp(-(d0 / d)**order)
    return mask

滤波后举行傅里叶反变换

ifft_shift = np.fft.ifftshift(fft_shift * mask)
ifft_img = np.abs(np.fft.ifft2(ifft_shift))

运行效果及剖析

下图中,从上到下依次展示了使用理想高通滤波器、Butterworth 高通滤波器和指数高通滤波器对 Lena 举行边缘检测,在差异的截止频率 \(D_0\) 下(10、20、40、80)所获得的频谱图以及滤波后的图像输出。

通过对比可以发现,使用理想高通滤波器获得的效果有显著的振铃征象,而 Butterworth 高通滤波器和指数高通滤波器的效果相近,均具有较好的效果。从频谱图中也可以看出,理想高通滤波器对频率的截断异常陡峭,在临界点发生了突变,尔后两者的滤波对照平滑,是一种在崎岖频率间逐渐过渡的历程。

微分算子法

针对由于平均或积分运算而引起的图像模糊,可用微分运算来实现图像的锐化。微分运算是求信号的转变率,有增强高频分量的作用,从而使图像轮廓清晰。

常见的边缘检测算子包罗:Roberts 算子、Sobel 算子、Laplacian 算子、Canny 算子等。种种算子的存在就是对这种导数支解原理举行的实例化盘算,是为了在盘算历程中直接使用的一种盘算单元。现实使用时,通常用种种算子对应的模板对原图举行卷积运算,从而提取出图像的边缘信息。

上述各算子的详细界说就不睁开赘述了,详细可以参考相关书籍或文章。这里通过一张表对这些算子举行简要的先容和对照。

算子 先容及优缺点对照
Roberts 一种最简朴的算子,接纳对角线偏向相邻两像素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘,定位精度高,然则对噪声敏感,对具有陡峭边缘且含噪声少的图像效果较好。
Sobel 凭据像素点上下左右四邻域灰度加权差检测边缘,类似局部平均运算,因此对噪声具有平滑作用,对灰度渐变和噪声较多的图像处置效果对照好,对边缘定位对照准确。
Laplacian 属于二阶微分算子,在只思量边缘点的位置而不思量周围的灰度差时适适用该算子举行检测。对噪声异常敏感,只适用于无噪声图像。存在噪声的情况下,使用该算子检测边缘之前需要先举行低通滤波,因此通常把 Laplacian 算子和平滑算子结合起来天生一个新的模板。
Canny 该算子功效比前面几种都要好,不容易受噪声的滋扰,能够检测到真正的弱边缘,然则实现起来较为贫苦,是一个具有滤波、增强、检测的多阶段的优化算子。在举行处置前,Canny 算子先行使高斯平滑滤波器来平滑图像以除去噪声。Canny 支解算法接纳一阶偏导的有限差分来盘算梯度幅值和偏向,在处置历程中,该算子还将经由一个非极大值抑制的历程,最后接纳两个阈值来毗邻边缘。

代码实现

Roberts、Sobel 以及 Laplacian 算子方式均为手工实现:先凭据差异算子对应的模板,划分界说对单个像素块的卷积运算函数,然后在图像上滑动模板,挪用该函数盘算每一个卷积块,最终获得经由各算子微分后的输出图像。对于 Canny 算子,由于其实现历程对照复杂,这里选择直接挪用 OpenCV 中的 Canny() 函数。

实现前三种算子

def roberts_operator(block):
    kernel1 = np.array([[1,0], [0,-1]])
    kernel2 = np.array([[0,-1], [1,0]])
    return np.abs(np.sum(block[1:,1:] * kernel1)) + np.abs(np.sum(block[1:,1:] * kernel2))

def sobel_operator(block, orientation):		# 水平和垂直两个偏向
    if orientation == 'horizontal':
        kernel = np.array([[-1,-2,-1], [0,0,0], [1,2,1]])
    elif orientation == 'vertical':
        kernel = np.array([[-1,0,1], [-2,0,2], [-1,0,1]])
    else:
        raise('Orientation Error')
    return np.abs(np.sum(block * kernel))

def laplacian_operator(block):
    kernel = np.array([[0,-1,0], [-1,4,-1], [0,-1,0]])
    return np.abs(np.sum(block * kernel))

滑动盘算卷积块

def operator_process(img, operator_type, orientation=None):
    n, m = img.shape
    res = np.zeros((n, m))
    for i in range(1, n-1):
        for j in range(1, m-1):
            if operator_type == 'roberts':
                res[i][j] = roberts_operator(img[i-1:i+2, j-1:j+2])
            elif operator_type == 'sobel':
                res[i][j] = sobel_operator(img[i-1:i+2, j-1:j+2], orientation)
            elif operator_type == 'laplacian':
                res[i][j] = laplacian_operator(img[i-1:i+2, j-1:j+2])
            else:
                raise('Operator Type Error')
    return res

挪用 OpenCV 中的 Canny 算子

canny_res = cv2.Canny(img, threshold1, threshold2)		# 设置崎岖阈值参数

运行效果及剖析

使用 Roberts 算子、Laplacian 算子以及水平和垂直两个偏向的 Sobel 算子举行边缘检测所获得的效果如下图所示:

可以看到,Roberts 算子简朴但有用,已经能实现对照好的边缘检测效果;而 Laplacian 算子的效果相对较差,边缘不是很清晰,还泛起了许多噪点;Sobel 算子整体显示也较好,可以显著地看出水平和垂直两个偏向上效果的差异,前者对水平边缘响应最大(如眼眶、嘴唇、下巴处),后者对垂直边缘响应最大(如鼻梁、两侧面颊处)。

下图显示了使用 OpenCV 自带的 Canny 算子在差异阈值下的输出效果,其中低阈值 threshold1 依次取 30、50、80、120、150,而高阈值 threshold2 凭据 Canny 算法的推荐,均取为 threshold1 的 3 倍。

低于 threshold1 的像素被以为不是边缘,高于 threshold2 的像素被以为是边缘,介于二者之间的则会凭据相邻的像素点进一步确定。从图中也可以看出,阈值设置得越高,对边缘的过滤就越严酷,输出效果中的边缘线条也越发希罕。

噪声测试

为了进一步研究在有噪声的情况下各算子的边缘检测效果,首先使用 skimage 库中的函数,对 Lena 加入高斯噪声和椒盐噪声。

img_noise1 = skimage.util.random_noise(img, mode='gaussian')
img_noise2 = skimage.util.random_noise(img, mode='s&p')

然后划分在这两张有噪声的图像上应用 Roberts 算子、Sobel 算子(水平偏向)、Laplacian 算子和 Canny 算子,获得的效果如下:

其中,第一行是加入高斯噪声后各算子的输出,第二行是加入椒盐噪声后各算子的输出。

可以发现,Roberts 算子和 Sobel 算子都有一定的抗噪声能力,从图中依然可以看出部门边缘信息,而在 Laplacian 算子则对噪声异常敏感,其输出效果完全看不出任何边缘。对于 Canny 算子,需要将阈值设置得很高,才气获得对照好的效果,否则大量噪点也会被以为是边缘。经由多次实验,最终将 threshold1 设为 180,将 threshold2 设为 3 * threshold1,获得了上图中最后一列的效果。

实验历程中还发现,在相同的阈值条件下,Canny 算子对高斯噪声的抵制能力比对椒盐噪声的抵制能力强。下图展示了当 threshold1 取值为 100、120、140、160、180 时,Canny 算子对加入了高斯噪声和椒盐噪声的图像的边缘检测效果:

HED 算法

2015年,Saining Xie 等人提出了一种基于卷积神经网络的边缘检测算法——Holistically-Nested Edge Detection(HED)算法。模子使用 VGG-16 作为主干网络举行多尺度多层级的特征学习。其中 Holistically 的意思是”整体地“,示意该算法试图训练一个 image-to-image 的网络;Nested 则强调在天生的输出历程中,通过不停的集成和学习,获得更正确的边缘展望图。

HED 算法具有许多优点。单就展望历程来说,对一张图片举行边缘检测的速率是很快的。使用时,凭据图片的现实内容,可以通过调整合适的超参数从而获得最优尺度的边缘信息。另外,由于 HED 自己就是基于神经网络的,因而可以很方便地嵌入其他网络模子中,直接参与种种学习义务的训练历程。

在效果上,HED 算法也具有优越性。论文中,作者把 HED 和传统 Canny 算法举行对比。如下图所示,可以看到 HED 的效果显著优于 Canny 算法。关于 HED 算法的更多内容请参考论文原文。

代码实现

这里接纳的是 HED 算法的另一个 PyTorch 实现版本,直接使用了作者提供的预训练模子举行展望。

运行效果及剖析

模子在彩色 Lena 图像上的运行效果如下图所示:

在添加了高斯噪声和椒盐噪声后的图像上,运行效果划分如下所示:

添加高斯噪声后的 HED 输出图像 添加椒盐噪声后的 HED 输出图像

可见,虽然 HED 算法的边缘线条对照粗,但整体显示照样相当优异的,尤其是在存在噪声的情况下,该算法的效果比前述几种基于微分算子的方式都要好。

总结

本文通过使用高通滤波法、微分算子法、神经网络方式三大类,共计 8 种差异的方式对 Lena 图像举行了边缘检测,将种种方式获得的效果举行横向对照,并对它们的优缺点和适用场景举行了一定的讨论。对于具有参数的算法,进一步凭据参数取值的差异举行了纵向对照,考察参数对于输出效果的影响。此外,还通过对原图像添加高斯噪声和椒盐噪声举行噪声测试,研究各算法对两种噪声的敏感性。

实验效果表明,差异算法由于原理或焦点函数的差异,均具有各自的优缺点和适用场景。使用时应凭据图像内容和现实需求举行选择取舍,并通过调整相关参数从而到达最佳的效果。

完整源码请见 GitHub 堆栈

参考资料

  1. 王一丁,李琛,王蕴红.《数字图像处置》.西安电子科技大学出版社
  2. Xie, Saining, and Zhuowen Tu. "Holistically-nested edge detection." Proceedings of the IEEE international conference on computer vision. 2015.
  3. PyTorch-HED:https://github.com/sniklaus/pytorch-hed
  4. 互联网上的一些博客、文章、资料
,

诚信在线官网

诚信在线官网(现:阳光在线官网)现已开放诚信在线手机版、诚信在线电脑客户端下载。诚信在线娱乐游戏公平、公开、公正,用实力赢取信誉。

版权声明

本文仅代表作者观点,
不代表本站Allbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论