赞
踩
- 点击上方“小白学视觉”,选择加"星标"或“置顶”
- 重磅干货,第一时间送达
Author:louwill
Machine Learning Lab
从本文开始,笔者计划花一些时间对传统的图像分割算法进行一个系统的梳理,叙述方式仍然是以原理阐述和代码实现为主。
谈到图像分割算法,现在基本上言必称深度学习。这也无可厚非,毕竟大环境和研究趋势如此。但回过头来,我们有必要对传统的图像处理算法有一个基本的了解。本文的主要内容是对基于边缘检测的图像分割算法进行介绍。主要叙述内容包括图像滤波、边缘检测原理与思想、基础边缘检测梯度算子和高级边缘检测梯度算子。
在数字图像处理领域,图像滤波是一个重要是知识点。关于滤波的相关知识,不是本文的重点所在,这里我们重点说一下图像滤波与边缘检测之间的关系。
图像滤波一般有两个目的,一个是用于图像特征的提取,这一点跟深度学习中的卷积核原理是一样的。另外一个则是通过滤波做一些去噪相关的预处理工作。与深度学习中的卷积核一样,边缘检测也是基于图像特征的思路,用于图像关键特征的提取。
图1 图像滤波与图像扭曲
边缘检测是一种基于图像灰度突变和不连续性来分割图像的方法。而检测这种灰度突变和不连续性正是依靠滤波器来实现。下面,我们先引入图像梯度的概念,然后再介绍基本的图像梯度算子。
为了达到寻找图像边缘的目的,检测灰度变化可以用梯度来实现。图像梯度定义如下,给定一幅图像,其在位置的图像梯度可定义为:
该向量有一个重要的几何性质,即指出了在位置处的最大变化率的方向。
由上式可知,要得到一幅图像的梯度,需要在图像每个像素处计算偏导数和:
上述两个公式对所有的和的有关值可以用图2的一维模板通过对的滤波来执行。
图2 图像梯度一维模板
类似于图2这种用于计算图像梯度的滤波器模板,也称为梯度算子或者边缘算子。基于不同的滤波器模板,我们可以提取图像不同的特征,从而得到不同的边缘检测效果。
基础的边缘检测梯度算子包括Roberts算子、Prewitts算子以及Sobel算子等。
图3 一幅图像的3*3区域
Roberts算子也叫交叉梯度算子,用于提取图像对角线的边缘特征。当我们对图像对角线边缘信息感兴趣时,可以使用该算子。如图3所示的区域,Roberts算子以求对角像素之差为基础。
可以看到,Roberts算子实际上用的是模板。如果对于大小的模板来给出偏导数的数值近似,有:
在上式子中,区域的第三行与第一行之差近似为方向的梯度,第三列和第一列之差近似为方向的导数,这种梯度算子即Prewitts算子。
如果我们对上式做一些轻微的变化,将中间值的系数改为,如下式所示:
对中间位置加一个的系数能够起到平滑图像的作用,这种算子即Sobel算子。
Roberts算子、Prewitts算子和Sobel算子用到的梯度模板如图4所示。
图4 基础边缘检测算子模板
Roberts算子、Prewitts算子和Sobel算子这些基础梯度算子都有一定的边缘检测效果,但都是完全基于滤波器的检测方法,没有对图像特性和图像噪声采取预防措施,所以会限制其检测能力。一些高级的边缘检测梯度算子会在考虑图像特性和图像噪声的基础上,对初级的边缘检测算法进行改进。典型的高级边缘检测梯度算子包括Canny算子和Marr-Hildreth算子。
Canny算子是一种多级边缘检测算法,本身也是一种基于滤波器的检测算法,但是在滤波的基础上加了非极大值抑制和双阈值处理。
Canny认为,一个好的边缘检测算法,应该有如下三个特征:
低错误率。即所有边缘都能被找到,并且伪边缘点最少。
好的定位。定位的边缘要与真实边缘尽可能的接近。
单一响应。对于真实的边缘点,检测算法仅能返回一个点。
Canny算子的设计逻辑主要是将上述三个原则进行数学化的规约和设计。Canny算子的基本步骤如下:
对输入图像使用高斯滤波器进行平滑处理
对平滑后的图像计算梯度幅值图像和角度图像
对梯度幅值图像应用非极大值抑制
对非极大值抑制之后的图像进行双阈值处理
下面我们来看一下Canny算子每个步骤的具体操作过程。令为输入图像,为二维高斯函数,有:
用对进行高斯滤波处理即可。假设经过高斯滤波平滑后的图像为,有:
然后基于计算梯度幅值图像和角度图像,计算公式如下:
其中,,。
上一步得到的梯度幅值图像可能会存在边缘粗宽、弱边缘干扰等问题。所以接下来就是对梯度幅值图像进行非极大值抑制,找到图像的局部最大值,将局部非极大值设为0。最后再补充一个双阈值处理,用来减少伪边缘点。主要思路是设定两个阈值,一个低阈值,一个高阈值,将小于低阈值的点作为假边缘设为0,将大于高阈值的点作为强边缘设为1。
基于opencv的Canny边缘检测示例如下代码所示。
- import numpy as np
- import cv2
- from matplotlib import pyplot as plt
-
- img = cv2.imread('kobe.jpg', 0)
- edges = cv2.Canny(img, 40, 80)
- plt.subplot(121), plt.imshow(img, cmap='gray')
- plt.title('Original Image'), plt.xticks([]), plt.yticks([])
- plt.subplot(122), plt.imshow(edges, cmap='gray')
- plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
- plt.show();
图5 Canny算子检测效果
Marr和Hildreth通过研究证明了:
图像的灰度变化与尺寸无关,所以需要使用不同尺寸的算子。
灰度的突然变化会在一阶导数上体现为波峰或波谷,在二阶导数上产生零交叉。
两人又通过研究论证,满足上述两个条件的最好的检测算子为,其中为拉普拉斯算子,为标准差为的二维高斯函数:
由上式可得的表达式为:
整理各项后可得到如下表达式:
上式称为高斯拉普拉斯(LoG),因为其形状像一个草帽,所以也叫墨西哥草帽算子,如图6所示。
图6 高斯拉普拉斯
所以,Marr-Hildreth算子是对输入图像做LoG滤波处理,然后在输出图像中寻找零交叉来确定边缘位置。
本文在介绍图像滤波器的基础上,介绍了图像梯度的概念。继而介绍了基本的边缘检测算子,包括Roberts算子、Prewitts算子以及Sobel算子等。但基础的边缘检测算子都有其局限性,在实际应用中,Canny算子和Marr-Hildreth算子等典型的高级边缘检测梯度算子具备更好的应用效果和泛化性能。
[1] 数字图像处理
[2] https://learnopencv.com/edge-detection-using-opencv/
好消息!
小白学视觉知识星球
开始面向外开放啦
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。