空间域图像增强:图像梯度之Sobel算子
0.综述
Sobel
算子是提取图像梯度信息的经典算子之一,图像的梯度信息是图像的最原始特征信息,对梯度信息进行进一步的处理就可以生成一些比较高级的特征来表示一张图像,这些高级的特征可以用于基于图像特征的匹配以及图像分类等应用。
2.Sobel算子原理分析
Sobel
算子的本质是基于图像空间域卷积,它背后的思想是图像的一阶导数算子的理论支持。
2.1 图像梯度介绍
设
f
(
x
,
y
)
f(x,y)
f(x,y)为连续图像函数,
G
x
,
G
y
G_x,G_y
Gx,Gy分别为
x
,
y
x,y
x,y方向的梯度,且在点
(
x
,
y
)
(x,y)
(x,y)处的梯度可以表示为一个矢量,并有其梯度定义:
G
(
f
(
x
,
y
)
)
=
[
∂
f
(
x
,
y
)
∂
x
∂
f
(
x
,
y
)
∂
y
]
T
(1)
G(f(x,y))= \left[ \begin{matrix} {\frac {\partial f(x,y)}{\partial x}} &{\frac {\partial f(x,y)}{\partial y}} \\ \end{matrix} \right] ^T\tag{1}
G(f(x,y))=[∂x∂f(x,y)∂y∂f(x,y)]T(1)
该梯度矢量在点
(
x
,
y
)
(x,y)
(x,y)处的梯度幅值定义为:
G
(
x
,
y
)
=
G
x
2
+
G
y
2
(2)
G(x,y)=\sqrt[]{{G_x}^2+{G_y}^2}\tag{2}
G(x,y)=Gx2+Gy2(2)
其中
(
1
)
(1)
(1)的幅值计算对应于欧氏距离,实际上常用两个分量的绝对值之和或者最大值来近似梯度幅值,即:
G
4
(
x
,
y
)
=
∣
G
x
∣
+
∣
G
y
∣
(3)
G_4(x,y)=|G_x|+|G_y|\tag{3}
G4(x,y)=∣Gx∣+∣Gy∣(3)
或者:
G
8
(
x
,
y
)
≈
m
a
x
(
∣
G
x
∣
,
∣
G
y
∣
)
(4)
G_8(x,y)\approx max(|G_x|,|G_y|)\tag{4}
G8(x,y)≈max(∣Gx∣,∣Gy∣)(4)
梯度的方向由梯度矢量的幅角表示,是函数
f
(
x
,
y
)
f(x,y)
f(x,y)增加最快的方向,它定义为:
ϕ
(
x
,
y
)
=
a
r
c
t
a
n
(
G
y
/
G
x
)
(5)
\phi(x,y)=arctan(G_y/G_x)\tag{5}
ϕ(x,y)=arctan(Gy/Gx)(5)
对于上述的
(
2
)
(
3
)
(
4
)
(2)(3)(4)
(2)(3)(4)三个式子,求偏导数需要对每一个像素位置进行计算,而实际中是用模板,也就是卷积算子进行计算的,经典的算子有Roberts
算子、Sobel
算子、Prewitt
算子等。
2.2Sobel算子原理分析
由向量的分析我们可以知道,梯度向量一般就是指图像
f
f
f在
(
i
,
j
)
(i,j)
(i,j)处的最大变化率,因此Sobel
算子是3x3的,其在点
(
i
,
j
)
(i,j)
(i,j)处的梯度幅值表达式为:
G
(
i
,
j
)
=
G
x
2
+
G
y
2
(6)
G(i,j)=\sqrt[]{{G_x}^2+{G_y}^2}\tag{6}
G(i,j)=Gx2+Gy2(6)
该表达式可以近似化为:
G
(
i
,
j
)
=
∣
G
x
∣
+
∣
G
y
∣
(7)
G(i,j)=|G_x|+|G_y|\tag{7}
G(i,j)=∣Gx∣+∣Gy∣(7)
其中
G
x
,
G
y
G_x,G_y
Gx,Gy 是3x3的卷积窗口中心的像素在
x
x
x,
y
y
y 方向上的梯度,也就是说利用Sobel
算子得到的是边缘检测结果图像中与3x3卷积窗口的中心点
(
i
,
j
)
(i,j)
(i,j)对应的那个位置处的像素值。
G
x
G_x
Gx,
G
y
G_y
Gy定义如下:
G
x
=
[
f
(
i
−
1
,
j
+
1
)
+
2
f
(
i
,
j
+
1
)
+
f
(
i
+
1
,
j
+
1
)
]
−
[
f
(
i
−
1
,
j
−
1
)
+
2
f
(
i
,
j
−
1
)
+
f
(
i
+
1
,
j
−
1
)
]
G_x=[f(i-1,j+1)+2f(i,j+1)+f(i+1,j+1)]-[f(i-1,j-1)+2f(i,j-1)+f(i+1,j-1)]
Gx=[f(i−1,j+1)+2f(i,j+1)+f(i+1,j+1)]−[f(i−1,j−1)+2f(i,j−1)+f(i+1,j−1)]
G
y
=
[
f
(
i
+
1
,
j
−
1
)
+
2
f
(
i
+
1
,
j
)
+
f
(
i
+
1
,
j
+
1
)
]
−
[
f
(
i
−
1
,
j
−
1
)
+
2
f
(
i
−
1
,
j
)
+
f
(
i
−
1
,
j
+
1
)
]
G_y=[f(i+1,j-1)+2f(i+1,j)+f(i+1,j+1)]-[f(i-1,j-1)+2f(i-1,j)+f(i-1,j+1)]
Gy=[f(i+1,j−1)+2f(i+1,j)+f(i+1,j+1)]−[f(i−1,j−1)+2f(i−1,j)+f(i−1,j+1)]
则
x
,
y
x,y
x,y两个方向梯度对应的卷积核为:
[
−
1
0
1
−
2
0
2
−
1
0
1
]
\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0& 1 \end{matrix} \right]
⎣⎡−1−2−1000121⎦⎤
[
−
1
−
2
−
1
0
0
0
−
1
−
2
−
1
]
\left[ \begin{matrix} -1 & -2 & -1 \\ 0 & 0 & 0\\ -1 & -2& -1 \end{matrix} \right]
⎣⎡−10−1−20−2−10−1⎦⎤
Sobel
边缘检测算子的另一种形式是
G
(
i
,
j
)
=
m
a
x
(
∣
G
x
∣
,
∣
G
y
∣
)
G(i,j) = max(|G_x|,|G_y|)
G(i,j)=max(∣Gx∣,∣Gy∣)
利用Sobel
边缘检测算子进行边缘检测的方法是:分别利用上述两个模板对图像进行逐像素卷积,将2个卷积结果值相加,然后判别该相加结果是否大于或等于某个阈值,如果满足条件,则将其作为结果图像中对应于模板中心位置
(
i
,
j
)
(i,j)
(i,j) 处的像素值;如果不满足条件,则给结果图像中对应于模板中心位置
(
i
,
j
)
(i,j)
(i,j) 处的像素赋0值。
Sobel
边缘检测算子在较好地检测图像边缘特征的同时,并对图像的噪声也具有一定的平滑作用,它可以减小对噪声的敏感性。但Sobel
边缘检测算子检测的边缘比较粗,也会检测出一些伪边缘,所以边缘检测精度比较低。
3.Sobel算子OpenCV API介绍
OpenCV中
的Sobel API
如下:
void Sobel( InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
int ksize = 3,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT );
其中ddepth
为图像深度,一般为CV_32F
。dx
,dy
分别为X方向和Y方法的一阶导数,一般都为1。ksize
为卷积窗口大小,默认为3,也就是3x3的卷积核。scale
是放缩比率,一般为1,表示不变。delta
是对输出结果图像中的像素值加上一个常量值,默认为0.
4.Sobel算子代码实践
Mat sobel_x, sobel_y;
Sobel(input,sobel_x,CV_32F,1,0,3,1,0,BORDER_DEFAULT);
Sobel(input, sobel_y, CV_32F, 0, 1, 3, 1, 0, BORDER_DEFAULT);
convertScaleAbs(sobel_x, sobel_x);
convertScaleAbs(sobel_y, sobel_y);
imshow("sobel_x", sobel_x);
imshow("sobel_y", sobel_y);
运行结果: