图像分析:边缘检测中的梯度算子

边缘检测是基于边界的图像分割方法的第一步,边缘是两个不同的相邻区域之间灰度值不连续或突变的地方。所以检测边缘就是灰度变化明显的地方。通过计算灰度的微分,可以检测出边缘位置灰度的明显变化。通常使用一阶微分和二阶微分来检测边缘。在边缘位置,一阶微分的幅值会有局部极值,二阶微分的幅值会有过零点。本文主要介绍边缘检测中的一阶微分算子——梯度算子,包括Roberts、Prewitt和Sobel。

如果要计算梯度图,就必须设计模板卷积。第一,计算时一定要了解图像的坐标系。许多博客文章对应的模板与坐标系不匹配。我们在卷积运算中主要使用计算坐标系。

左边摄像师使用的坐标系经常用于图像计算。它的坐标原点在左上角,X轴水平向右延伸。y是垂直的,向下延伸。它不仅可以表示这个图像,还可以表示坐标上像素的值。

屏幕显示经常使用右边的Lena坐标系,因为屏幕扫描是从左到右,从上到下进行的。原点在图像的左上角,纵轴标记图像的行,横轴标记图像的列。它不仅可以表示这个图像,还可以表示行和列的交点处的图像值。

我们首先需要知道的是,梯度是一个向量。如果它是一个向量,它就有方向和大小。梯度方向指向函数变化最快的方向,大小就是它的模和最大变化率。对于二元函数,它在该点的梯度是,或者,它是:

其中,该梯度向量的振幅和方向角为

下图显示了灰度贴图的数学表达式。一个像素的灰度值是它有八个邻域。

图像在该点的梯度为

在…之中

即图像对应的水平方向,即水图像对应的垂直方向。

要了解渐变图的生成,首先要了解模板卷积的过程。

模板卷积是模板操作的一种方式,其步骤如下:

(1)在输入图像中漫游模板,并将模板的中心与图像中的像素位置重叠;

(2)将模板上的每个系数与模板下每个对应像素的灰度相乘;

(3)将所有乘积相加(为了保持灰度范围,往往将结果除以模板系数之和,如果梯度算子的模板和为0则不必除法);

(4)将上述运算结果(模板的响应输出)赋给输出图像中模板中心位置对应的像素。

其实梯度图的生成和模板卷积是一样的,只是不同的是,生成梯度图需要计算模板卷积完成后该点梯度的幅度,以该幅度作为像素值,从而完成计算。。

下图显示了用于生成渐变图的水平模板和垂直模板:

例如,如果只想生成水平方向的渐变图,那么只计算水平方向的渐变,渐变图上对应点的灰度值为

一般水平方向用一个模板,垂直方向用一个模板,然后合并,那么该点的渐变图灰度值为

就是我们上面说的梯度的幅度,以2为范数计算,对应的是欧氏距离。因为涉及平方和和平方根运算,所以计算量比较大。如何简化计算?改成近似的计算方法!!!)

在计算实际坡度图输出时,采用了一种简单的计算方法,定额为1(对应于市区距离),即

另一个简单的方法是取为规范(对应于棋盘距离),即

首先了解下梯度算子的设计,一般是横平竖直。水平模板转置后对折,就是垂直方向。

其本质是一个对角梯度算子,对应的水平和垂直梯度为

输出渐变图的灰度值为

优点:边缘定位准确

缺点:(1)没有描述水平和垂直方向的灰度变化,只关注对角线方向,容易造成遗漏。(2)鲁棒性差。由于点本身参与梯度计算,不能有效地抑制噪声干扰。

适用于边缘明显、噪点较少的图像。

Prewitt算子是典型的模板,其模板中心对应需要梯度的原始图像坐标,对应的8邻域像素灰度值如下表所示:

通过Prewitt算子的水平模板卷积后,对应的水平梯度为

通过Prewitt算子的垂直模板进行卷积后,对应的垂直梯度为

输出渐变图的灰度值为

Prewitt算子引入了类似于局部平均的运算,对噪声有平滑作用,比Roberts算子更能抑制噪声。

通过Prewitt算子的水平模板卷积后,对应的水平梯度为

通过Prewitt算子的垂直模板进行卷积后,对应的垂直梯度为

输出渐变图的灰度值为

Sobel算子引入了类似于局部加权平均的运算,其边缘定位比优于Prewitt算子。

Python调用OpenCV接口实现Sobel算子边缘检测。