Roxy's Library

Back

Images as Functions#

在计算机视觉中,我们把图像定义为一个从R2R^2映射到RMR^M的函数ff,其中f(x,y)f(x,y)给出了位置(x,y)(x,y)处的像素值(范围[0,255][0,255])。对于灰度图像,M=1M=1,而对于彩色图像,M=3M=3(分别对应RGB三个通道,此时(x,y)(x,y)处的像素值是一个三维向量)

对于连续函数,我们可以定义它的梯度f(x,y)=(fx,fy)\nabla f(x,y) = \left( \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right),它表示函数在位置(x,y)(x,y)处的变化率。但是由于图像是离散的,我们需要使用有限差分来替代梯度:

fxx=x0f(x0+1,y0)f(x01,y0)2\frac{\partial f}{\partial x} |_{x=x_0} \approx \frac{f(x_0+1,y_0) - f(x_0-1,y_0)}{2}

图像的梯度指向了图像中灰度变化最快的方向

Images Gradient

Filters#

现实中的图像往往包含噪声,这些噪声可能会干扰我们后续的处理,因此需要进行平滑化处理

Filter(滤波)是一种常用的图像处理技术,它可以用于提取图像中有用的信息(比如边缘,拐角),也可以用于修改或增强图像的质量(超分,去噪)

一种滤波的方式是使用卷积运算,下面我们看一个一维滤波的例子

1D Convolution

这个例子里面,把每个点的值替换成了它自己和它左右各两个点的平均值,这样就达到了平滑化的效果

经过上面的处理后,每个部分的噪声都减小了,但是每个部分之间的变化也被模糊了。我们可以更改一下滤波器的权重,使得中心点的权重更大,这样就可以在平滑化的同时保留更多的细节

weighted convolution

注意到我们上面做的两种滤波都是对原来的值进行线性组合的,这样的滤波器被称为线性滤波器(linear filter),满足L(af+bg)=aL(f)+bL(g)L(a\cdot f+b\cdot g)=a\cdot L(f)+b\cdot L(g),因此可以用卷积来实现

2D Filters#

与一维的滤波器类似,我们只是把卷积核换成了一个二维的矩阵,这样就可以在图像上进行卷积操作了。

对于之前的平均滤波器,我们可以把它表示成一个3×33\times 3的卷积核:

19[111111111]\frac{1}{9} \begin{bmatrix} 1 & 1 & 1\\ 1 & 1 & 1\\ 1 & 1 & 1\\ \end{bmatrix}

用这个卷积核对图像进行卷积操作,每次计算3x3的区域内的像素值的平均值,来替换中心点的像素值

2D Convolution

除了上面提到的线性滤波器之外,还有一些非线性的滤波器,比如:

h[m,n]={1,f[m,n]>τ0,otherwiseh[m,n]= \left\{ \begin{array}{l} 1,\quad f[m,n]>\tau \\ 0,\quad otherwise\\ \end{array} \right.

可以将像素值大于τ\tau的部分设置为11,其他部分置为00,这样就实现了二值化的效果

Edge Detection#

从物理意义上讲,边缘通常对应着物体边界、表面朝向的突变、阴影或者是光照强度的变化。为了能够更好检测到边缘,我们需要给边缘一个数学上的定义:

在图像中,沿图像一个方向的像素值有显著变化(或具有高对比度),而沿其正交方向的像素值几乎没有变化(或低对比度)的区域

根据这个定义,我们注意到边界的梯度值往往比较大,因此我们可以通过计算图像的梯度来检测边界

edge derivative

但是问题又来了,由于噪声的存在,图像的梯度值在噪点处也可能比较大,这样就会导致错误。这里就需要先进行平滑化处理

edge smoothing

之前我们已经提到过一些滤波器,而最常用的平滑滤波器是高斯滤波器,这里我们先考虑一维的

g(x)=12πσex22σ2g(x) = \frac{1}{\sqrt{2\pi}\sigma} e^{-\frac{x^2}{2\sigma^2}}

高斯滤波器的形状是一个钟形曲线,可以看到这个曲线主要位于00附近,因此是低通滤波器,可以用于做平滑处理。σ\sigma控制了滤波器的宽度,σ\sigma越大,滤波器越宽,平滑效果越强,但也会导致边缘模糊和定位精度下降

NMS#

有了经过平滑化和求导之后的图像,我们可以通过一些方法,比如筛选出一些梯度大于某个threshold的点,来检测边缘。但这些边缘可能比较宽(梯度方向上有多个点)。为了得到精细的边缘,保留局部最大值,我们可以使用非极大值抑制(Non-Maximal Suppression,NMS)来进一步细化边缘

具体的实现步骤:

  • 对于每个边缘像素点,计算它的梯度方向
  • 沿着梯度方向延申出两条线段(长度一般取11),分别指向正负两个方向,得到rrpp两个点
  • 通过双线性插值计算出rrpp两个点的梯度值
  • 如果当前点的梯度值大于rrpp两个点的梯度值,则保留当前点,否则抑制掉

non-maximal suppression

注意这里面rrpp两个点实际上可能不存在于图像的像素位置上,因此需要通过双线性插值来计算出它们的梯度值

此外我们还可以简化一下NMS的计算过程,直接把梯度方向分类为4个主要方向(0°45°45°90°90°135°135°,比如用是否大于22.5°22.5°来划分0°45°45°),只需要对比八个相邻点中的两个点即可,不需要双线性插值

Hysteresis Thresholding#

经过NMS后,我们得到了一个比较细的边缘图,但是这些边缘之间可能存在一些断点(由于噪声或者是边缘本身的特性),我们可以通过双阈值连接(Hysteresis Thresholding)来把这些边缘连接起来。

Hysteresis Thresholding设置了两个阈值:maxVal和minVal(都是超参数)。对于边缘图中的每个像素点,如果它的梯度值大于maxVal,记为强边缘;如果它的梯度值小于minVal,则抑制掉该点;如果它的梯度值介于minVal和maxVal之间,记为弱边缘

对于强边缘,分别检查沿着边缘方向(垂直于梯度方向)的两个相邻像素点。如果是弱边缘,且梯度和中间点在同一个方向上(这里的要求可以比较宽,只需要方向在同一个范围内就行),且符合NMS要求,则该点成为一个强边缘

反复做直到没有强边缘再出现为止。

Canny Edge Detector#

Canny Edge Detector是一个经典的边缘检测算法,包含了上面提到的所有步骤:

  • 使用高斯滤波器对图像进行平滑化处理,减少噪声的影响
  • 计算图像的梯度,得到边缘的强度和方向
  • 使用非极大值抑制(NMS)来细化边缘,保留局部最大值
  • 使用双阈值连接(Hysteresis Thresholding)来连接边缘
Classic Vision I
https://astro-pure.js.org/blog/cvintro_03_11
Author GreyRat
Published at March 14, 2026
Comment seems to stuck. Try to refresh?✨