0
点赞
收藏
分享

微信扫一扫

探索 Python HTTP 的瑞士军刀:Requests 库

树下的老石头 2024-11-13 阅读 29

文章目录

空间滤波

基础知识
线性空间滤波原理

线性空间滤波需要有一个滤波核,具体原理即滤波核的中心对齐原图像素点进行滑动,新图像像素值由滤波核系数与对应窗口的原图像素值逐个相乘累加,直到核的中心遍历完原图的所有像素点。如果是非线性滤波,那就是要乘滤波核系数的平方或取对数等等非线性操作。

一般而言,大小为 m × n m\times n m×n的核对大小为 M × N M×N M×N的图像的线性空间滤波可以表示为
g ( x , y ) = ∑ s = − a a ∑ t = − b b w ( s , t ) f ( x + s , y + t ) g(x, y)=\sum_{s=-a}^{a} \sum_{t=-b}^{b} w(s, t) f(x+s, y+t) g(x,y)=s=aat=bbw(s,t)f(x+s,y+t)
image-20241112111324041

滤波核要求

一般而言,滤波核的尺寸 m m m n n n应满足 m = 2 a + 1 , n = 2 b + 1 m=2a+1,n=2b+1 m=2a+1,n=2b+1,这样保证 m m m n n n都为奇数,因为只有行列都为奇数时才能找到滤波核的中心位置

图像填充

当滤波核的中心延原图像素滑动时,我们会发现,在图像边界的地方,滤波核覆盖范围可能会超过原图像范围,这时一般我们要对原图进行填充(padding),常用填充方法有4种,在Matlab中有padarray函数也定义了四种填充方式:

  • 0:通过补零来扩展图像。
  • ‘symmetric’:通过镜像反射外边界的值来扩展图像;
  • ‘replicate’:通过复制外边界的值来扩展图像;
  • ‘circular’ :将图像看成二维周期函数的一个周期来扩展;

一般要填充的像素值的行列数(单边,双边乘2即可)的计算方式是:
p a d d i n g _ r o w s = m − 1 2 , p a d d i n g _ c o l u m n s = n − 1 2 , padding\_rows = \frac {m-1} 2,\quad padding\_columns = \frac {n-1} 2, padding_rows=2m1,padding_columns=2n1,
推导方式很简单,其实就是填充滤波核的一半,画个图很容易就能看出来。

image-20241112112310667

相关和卷积
相关

相关操作其实和上面的线性空间滤波是一样的,都是滤波核与对应窗口的原图像素相乘累加。

image-20241112125606087

我们会发现,一个滤波核与一个离散冲击组成的图像做相关的结果会导致得到滤波核的一个副本,但该副本是滤波核旋转180°(等价于先按行再按列翻转或先按列再按行翻转)的样子,如果我们希望得到滤波核的非旋转版本,就要使用卷积来达到目的。

卷积

卷积操作的定义是和相关反着来的,即滤波核的系数要和该系数中心对称的系数所对应的原图像素相乘累加,公式如下:
g ( x , y ) = ∑ s = − a a ∑ t = − b b w ( s , t ) f ( x − s , y − t ) g(x, y)=\sum_{s=-a}^{a} \sum_{t=-b}^{b} w(s, t) f(x-s, y-t) g(x,y)=s=aat=bbw(s,t)f(xs,yt)
实际上,这样是不方便的,我们可以换个思路,直接把滤波核预先旋转得到一个旋转版本的滤波核,再将该滤波核与原图做一个相关操作。这样是等价的效果。

image-20241112130236659

为什么要使用卷积,事实上因为卷积具有比较良好的性质,如下:

image-20241112130315025

可以看到卷积具有交换律、结合律以及分配率,而相关操作仅具备分配率。

在Matlab中可以使用conv2函数实现卷积操作。

可分离滤波器核

可分离核指的是能够表示为两个向量的乘积的矩阵,比如 3 × 3 3\times 3 3×3的核:
w = [ 1 2 1 2 4 2 1 2 1 ] w=\left[\begin{array}{lll} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{array}\right] w= 121242121
是可分离的,因为它可以表示为两个向量的乘积:
c r T = [ 1 2 1 ] [ 1 2 1 ] \boldsymbol c \boldsymbol r^T=\left[\begin{array}{l} 1 \\ 2 \\ 1 \end{array}\right] \left[\begin{array}{lll} 1 & 2 & 1 \end{array}\right] crT= 121 [121]
实际上,经过证明,一个列向量和一个行向量的乘积,等于这两个向量的二维卷积

那么根据卷积的交换律结合律,如果有一个核 w w w,它可以分解为两个更简单的核并且满足 w = w 1 ⋆ w 2 w=w_{1} \star w_{2} w=w1w2(星星表示卷积),有如下公式:
w ⋆ f = ( w 1 ⋆ w 2 ) ⋆ f = ( w 2 ⋆ w 1 ) ⋆ f = w 2 ⋆ ( w 1 ⋆ f ) = ( w 1 ⋆ f ) ⋆ w 2 w \star f=\left(w_{1} \star w_{2}\right) \star f=\left(w_{2} \star w_{1}\right) \star f=w_{2} \star\left(w_{1} \star f\right)=\left(w_{1} \star f\right) \star w_{2} wf=(w1w2)f=(w2w1)f=w2(w1f)=(w1f)w2
公式表明,一个可分离核与一幅图像卷积等价于先用 w 1 w_1 w1 f f f卷积,再对结果用 w 2 w_2 w2卷积。

这个性质的最大用处就是简化计算,假如我们有 M × N M\times N M×N的图像和 m × n m \times n m×n的卷积核,则实很容易计算实现普通卷积所需乘法和加法的次数是 M N m n MNmn MNmn次,而使用可分离卷积核,那么第一次卷积需要 M N m MNm MNm次乘法和加法运算,第二次卷积需要 M N n MNn MNn次乘法和加法运算,那么总运算次数就是 M N ( m + n ) MN(m+n) MN(m+n)次。

那么如何确定一个核是否是可分离的,如果是可分离的如何计算两个分离向量?

根据线性代数理论,一个列向量和一个行向量相乘得到的矩阵,其秩总是1。根据定义,可分离核就是由这样的一个乘积构成的。因此,要确定一个核是否可分离,只需确定其秩是否为 1。确定矩阵的秩为1后,就很容易求出两个分离向量,包括以下3个步骤:

  1. 在核中找到任何一个非零元素,并将其值表示为E。
  2. 形成向量 c \boldsymbol c c r \boldsymbol r r,它们分别等于核中包含步骤1中找到的元素的那一行和那一列。
  3. 最后将 r / E \boldsymbol r/E r/E作为第二个分离向量。

image-20241112195324339

能够使用这个简单的三步方法的原因是,秩为1的矩阵的行和列是线性相关的。也就是说,各行只差一个常数倍,各列也只差一个常数倍。

空域平滑滤波(低通)
盒式滤波器

盒式滤波器是一种最简单的低通滤波器,滤波核的所有系数都相同并且有一个归一化常数,一个 3 × 3 3 \times 3 3×3的盒式滤波器如下:

image-20241112200920181

盒式滤波器的核越大,则平滑的效果越明显,图像也越模糊,下图a为原图,bcd分别使用大小为 3 × 3 3\times3 3×3 11 × 11 11\times11 11×11 21 × 21 21\times21 21×21的盒式核进行低通滤波。

image-20241112201059567

高斯滤波器

高斯核是由二维的高斯函数给出的,已经经过证明,高斯核是唯一可分离的圆对称核(各向同性,它们的响应与方向无关,不懂什么意思…)

高斯核形式如下:
w ( s , t ) = G ( s , t ) = K e − s 2 + t 2 2 σ 2 w(s, t)=G(s, t)=K \mathrm{e}^{-\frac{s^{2}+t^{2}}{2 \sigma^{2}}} w(s,t)=G(s,t)=Ke2σ2s2+t2
r = ( s 2 + t 2 ) 1 2 r=(s^2+t^2)^{\frac 1 2} r=(s2+t2)21,则可将上式改写为:
G ( r ) = K e − r 2 2 σ 2 G(r)=K \mathrm{e}^{-\frac{r^{2}}{2 \sigma^{2}}} G(r)=Ke2σ2r2
这个形式提醒我们该函数是圆对称的,即函数值仅与到中心点的距离有关,下图显示了几个不同大小的核的 r r r值:

image-20241112203441133

高斯核的生成就是通过设定上面公式中 K K K σ \sigma σ的值后( K K K通常设定为1)再根据核的系数位置到核中心的距离计算得到的, σ \sigma σ的值对于高斯核有如下什么影响:

σ \sigma σ增大时,高斯核的模糊效果会增强,这一点通过高斯函数的图像形式也很容易理解,当 σ \sigma σ增大,高斯函数图像变得矮胖,这意味着周边像素在计算平均时有更高的权重,模糊效果也更明显。

直观上来说,与盒式滤波器相同,核越大,模糊效果越明显,但对于高斯核来说,当核的大小大于 6 σ 6\sigma 6σ时,核再增大其实用处并不大,原因是当距离中心的距离非常大时,其实高斯核的函数值会非常小,相当于边缘像素的贡献会非常小,所以当核继续增大,效果并没有太大变化。下图是一个示例

image-20241112204640584

最后再给出一个 3 × 3 3\times 3 3×3的高斯核的示例(前面是归一化系数):

image-20241112204730497

空域锐化滤波(高通)

锐化的作用是突出灰度中的过渡,增强图像的边缘部分甚至是噪声,图像边缘也是图像的细节部分,因此锐化也是高通滤波。

一阶导数和二阶导数

下面介绍的锐化滤波器是基于一阶导数和二阶导数的,因此首先讨论这两个概念。

数学函数的导数是用差分来定义的,同样可以在图像中定义差分,但一阶导数的定义需要满足以下条件:

  1. 恒定灰度区域的一阶导数必须为
  2. 灰度台阶斜坡开始处的一阶导数必须非零
  3. 灰度斜坡上的一阶导数必须非零

二阶导数的定义需要满足以下条件:

  1. 恒定灰度区域的二阶导数必须为
  2. 灰度台阶斜坡的开始处和结束处的二阶导数必须非零
  3. 灰度斜坡上的二阶导数必须为

如此,我们便可以定义一维函数 f ( x ) f(x) f(x)的一阶导数为差分:
∂ f ∂ x = f ( x + 1 ) − f ( x ) \frac{\partial f}{\partial x}=f(x+1)-f(x) xf=f(x+1)f(x)
这里使用偏导是为了和后面图像需要处理二维数据也用偏导保持一致。

f ( x ) f(x) f(x)的二阶导数定义为差分:
∂ 2 f ∂ x 2 = f ( x + 1 ) + f ( x − 1 ) − 2 f ( x ) \frac{\partial^{2} f}{\partial x^{2}}=f(x+1)+f(x-1)-2 f(x) x22f=f(x+1)+f(x1)2f(x)
下图给出一个数据点、一阶导和二阶导的图像帮助理解:

image-20241113130517076

从左到右遍历剖面时,我们首先会遇到一个恒定灰度的区域,两个导数都是零。接着遇到的是一个灰度斜坡(Ramp),随后遇到的是一个台阶(Step),我们注意到,在斜坡和台阶的开始处,一阶导数非零;类似地,在斜坡和台阶的开始处和结束处,二阶导数非零。最后,我们看到一阶导数在斜坡上非零,二阶导数在斜坡上是零。注意,二阶导数的符号在台阶或斜坡的开始处和结束处会发生变化。事实上,如上图©所示,在台阶过渡中,连接这两个值的直线穿过了两个极值中间的水平轴。这个过零点性质对于定位边缘非常有用。

数字图像中的边缘在灰度上通常类似于斜坡过渡,这时图像的一阶导数会产生较宽的边缘,因为斜坡上的导数非零。另一方面,二阶导数会产生宽度为1像素并由零分隔的双边缘。由此得出的结论是,与一阶导数相比,二阶导数可增强更精细的细节,因此是适合于锐化图像的一个理想特性。

拉普拉斯核

业已证明,最简单的各相同性导数算子(核)是拉普拉斯,对于双变量函数,也即图像 f ( x , y ) f(x,y) f(x,y),它定义为:
∇ 2 f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^{2} f=\frac{\partial^{2} f}{\partial x^{2}}+\frac{\partial^{2} f}{\partial y^{2}} 2f=x22f+y22f
由于任意阶的导数都是线性算子,所以拉普拉斯也是线性算子,这就意味这可以用一个线性滤波核来表示,接下来就可以对这个公式进行离散化以构建一个线性滤波核。

对于 x x x方向(固定 y y y),有:
∂ 2 f ∂ x 2 = f ( x + 1 , y ) + f ( x − 1 , y ) − 2 f ( x , y ) \frac{\partial^{2} f}{\partial x^{2}}=f(x+1, y)+f(x-1, y)-2 f(x, y) x22f=f(x+1,y)+f(x1,y)2f(x,y)
对于 y y y方向(固定 x x x),有:
∂ 2 f ∂ y 2 = f ( x , y + 1 ) + f ( x , y − 1 ) − 2 f ( x , y ) \frac{\partial^{2} f}{\partial y^{2}}=f(x, y+1)+f(x, y-1)-2 f(x, y) y22f=f(x,y+1)+f(x,y1)2f(x,y)
那么两个变量的离散拉普拉斯很容易可以写出,把两个二阶偏导相加即可:
∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \nabla^{2} f(x, y)=f(x+1, y)+f(x-1, y)+f(x, y+1)+f(x, y-1)-4 f(x, y) 2f(x,y)=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)
当然除了水平方向和垂直方向的差分,如有需要,我们还可以用到对角方向的差分。下面是几个拉普拉斯核的示例

image-20241113133240095

拉普拉斯是导数算子,因此会突出图像中的急剧灰度过渡,并且不强调缓慢变化的灰度区域。这往往会产生具有灰色边缘线和其他不连续性的图像,它们都叠加在暗色无特征背景上。将拉普拉斯图像与原图像相加,就可“恢复”背景特征,同时保留拉普拉斯的锐化效果。上段说过,记住使用拉普拉斯的哪个定义很重要。如果所用的定义有一个负中心系数,那么从原图像中减去拉普拉斯图像可以得到锐化后的结果。因此,我们使用拉普拉斯锐化图像的基本方法是:
g ( x , y ) = f ( x , y ) + c [ ∇ 2 f ( x , y ) ] g(x, y)=f(x, y)+c\left[\nabla^{2} f(x, y)\right] g(x,y)=f(x,y)+c[2f(x,y)]
f ( x , y ) f(x,y) f(x,y) g ( x , y ) g(x,y) g(x,y)分别是输入图像和锐化后的图像,若使用上图(a)或(b)中的拉普拉斯核,则 c = − 1 c=-1 c=1,©(d)中的拉普拉斯核则使用 c = 1 c=1 c=1

但采取上面的算法我们有两步操作,就是先要计算出拉普拉斯图像再和原图相加,我们可不可以直接合成为1个滤波操作呢?(正确性待定)

实际上对原图采用一个中心为1,其他系数为0的核滤波等于原图本身,所以只需要把这个核与拉普拉斯核进行相加得到一个新核,然后用新核直接对原图进行滤波即可得到最后的锐化图像。

image-20241113134317581

观察上面4个拉普拉斯核,我们发现核的系数之和为0,基于卷积的滤波实现乘积之和,因此,当导数核通过图像中的一个恒定区域时,这个位置的卷积结果必为0。可以证明,一幅图像与一个系数之和为零的核的卷积结果中,像素之和也为0,这就意味着用这些核滤波后的图像具有负值,需要采取归一化、零截断等操作才可以得到合适的视觉效果。

参考链接

[1] https://www.bilibili.com/video/BV1yBvke6EgX?spm_id_from=333.788.videopod.sections&vd_source=bac8ddf04ec0b6386d58110f67353bc7

[2] 数字图像处理_冈萨雷斯(第四版)

举报

相关推荐

0 条评论