一. 数字图像处理基础

发布时间 2023-06-01 23:18:30作者: Beasts777

一. 数字图像处理基础

1.1 图像表示

图像就是矩阵,在python中表示为数组形式。

1.2 图像模型

1.2.1 RGB模型

  • R:红,【0,255】
  • G:绿
  • B:蓝

EG:#FF255255255:以两位为跨度,前两位为透明度,随后依次为:R、G、B

模型如下:

image-20230601105252489

1.2.2 HSI模型

  • H(Hue,色调):与光波的波长有关,表示人的感官对不同颜色的感 受,如红色、绿色、蓝色等。
  • S(saturation,饱和度):表示颜色的纯度,纯光谱色是完全饱和的,加入白光会稀释饱和度。饱和度越大,颜色看起来就会越鲜艳, 反之亦然。
  • I(intensity,亮度):对应成像亮度和图像灰度,是图像的明亮程度与图像的彩色信息无关

模型如下:

image-20230601105325146

1.3 图像数字化

1.3.1 采样

思路:将图像分割成一个个小区域(像素),每个小区域用一个值来表示,关键在于:

  • 采样间隔:反应原连续图像的程度。采样间隔越小,图像像素数量越多,分辨率越高。
  • 采样孔径:有不同的形状,包括:圆、正方形、长方形、椭圆。

1.3.2 量化

就是将像素值转换离散整数值的过程。存在以下指标:

  • 灰度级:像素量化后的值称为像素的灰度级(或灰度值/灰值),反映了像素的明暗程度

  • 灰度级数(G):

    • 意义:一副数字图像中不同灰度级的个数,代表了一副数字图像的层次。G越大,图像越丰富,视觉效果越好。

    • EG:一副[0,255]的100*100灰度图像中,数据量为:100*100*8bit,0表示最暗,255表示最亮。

1.3.3 分辨率

分为两种:

  • 图像分辨率:取决于采样间隔。同一幅图,采样间隔越小,图像像素数量越多,分辨率越高。
  • 灰度分辨率:取决于G的大小。同一幅图,G越大,灰度分辨率越高,图像层次丰富,数据量越大。G过下则会造成虚假轮廓现象。

1.3.4 函数表示

三种情况下的函数形式

  1. 设二维图像中任意像点的亮度为 ? ,则 ? 与像素点的空间 位置 ?, ? 、光线的波长 ? 和时间 ? 有关,其数学表达为:

    \[g=f(x,y,?,t) \]

  2. 当只考虑光的能量而不考虑其波长,图像视觉上表现为灰 度图像,其表达为

\[g=f(x,y,t) \]

  1. 若为静态图像,数字图像的表示 :

    \[g=f(x,y) \]

图像分类:

根据灰度级数区分不同类别的图像:

  1. 黑白图像:像素值只有黑和白,即0和1。
  2. 灰度图像:灰度级数>2,但不包含彩色信息。
  3. 彩色图像:每个像素颜色由R、G、B三个分量表示,图片由三个矩阵描述。

1.4 像素间的关系

1.4.1 相邻性

三种相邻性:

  1. 四邻域(\(N_4(p)\)):上下左右四个像素与中心像素4相邻。
  2. D邻域(\(N_D(p)\)):左上、左下、右上、右下与中心像素D相邻。
  3. 8邻域:\(N_8(p)=N_4(p)+N_D(p)\)

1.4.2 连通性

作用:是用于描述区域边界的重要概念。

两像素连接的必要条件:

  • 位置相邻。

  • 两个像素的灰度值均满足特定的相似性准则V,即:

    \[p,q\in V,其中V={v_1,v_2,...} \]

    就是说两个像素的灰度值都在某个灰度集合里面。

三种连接:

  • 四连接:

    像素p和q的灰度级满足相似性准则,且q在\(N_4(p)\)内,则两个像素是4-连接的。

  • 八连接(包括了四连接):

    像素p和q的灰度级满足相似性准则,且q在\(N_8(p)\)内,则两个像素是8-连接的。

  • m连接:满足以下两种情况中的一个时,m连接成立:

    • p和q是四连接。

    • p和q是m-连接,且p和q的四连接的交集没有满足相似性准则的像素。

      EG:

      \[\begin{bmatrix} 0 & p & 0 \\ 0 & q & r \\ 0 & 0 & 0 \end{bmatrix} \]

      其中p、q、r满足相似性准则V,那么:

      p和q:4连接、m-连接

      q和r:4连接、m-连接

      p和r:8连接,因为二者的四连接交集为q且q满足相似性准则V,所以不构成m-连接。

1.4.3 距离

主要使用的距离公式分为三种。以像素p(x,y)和q(s,t)为例:

  • 欧式距离:

    \[D_e(p,q)=\sqrt{(x-s)^2+(y-t)^2} \]

    就是平方差。

  • 城市距离:

    \[D_4(p,q)=|x-s|+|y-t| \]

    image-20230601112847138
  • 棋盘距离:

    \[D_8(p,q)=max\{|x-s|,|y-t|\} \]

    image-20230601113005663

1.5 图像运算

输入两个图像A(x,y)、B(x,y),输出图像C(x,y)

1.5.1 加法运算

定义:

\[C(x,y)=A(x,y)+B(x,y) \]

主要用途:

  • 去除叠加性噪声:

    如果某一图像被一加性随机噪声污染,那可以通过对多个该情境下的图像求平均值来降噪。

  • 生成图像叠加效果。

    \[C(x,y)=\frac{1}{2}\alpha(x,y)+\frac{1}{2}\beta(x,y) \\ 其中:(\alpha+\beta=1) \]

1.5.2 减法运算

定义:

\[C(x,y)=A(x,y)+B(x,y) \]

主要用途:

显示两幅图像之间的变化;检测同一场景下两幅图像之间的变化。如:视频中运动目标检测、图像差异检测。

  • 图像差异检测(运动目标检测)。
  • 去除不需要的叠加性图案。

1.5.3 乘法运算

定义:

\[C(x,y)=A(x,y)\times B(x,y) \]

主要用途:

图像的局部显示。

EG:用二值模板图像与原图像做乘法运算。

1.6 图像的坐标变换(重点)

思路:通过变换矩阵,对图像进行变换:

\[\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} t_{11} & t_{12} & t_{13} \\ t_{21} & t_{22} & t_{23} \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} \]

那么:

\[x'=t_{11}x+t_{12}y+t_{13} \\ y'=t_{21}x+t_{22}y+t_{23} \\ 1 = 0 + 0 + 1 \]

由此,可以衍生出:尺度、旋转、平移等变换。

1.6.1 平移

变换矩阵如下:

\[\begin{bmatrix} 1 & 0 & t_{x} \\ 0 & 1 & t_{y} \\ 0 & 0 & 1 \end{bmatrix} \]

那么变换后的坐标:

\[\begin{cases} x' = x+t_x \\ y'=y+t_y \end{cases} \]

注意:变换后画布扩大的,否则会失去信息。

image-20230601170802805

1.6.2 图像的尺度变换

变换矩阵如下:

\[\begin{bmatrix} t_x & 0 & 0 \\ 0 & t_y & 0 \\ 0 & 0 & 1 \end{bmatrix} \]

变换后的坐标:

\[\begin{cases} x' = t_xx \\ y' = t_yy \end{cases} \]

注意:由于采样间隔并没有改变,也就是说像素点的大小没有变化,那么所谓缩放其实就是像素点数量的变化,因此我们需要对多出来的像素点的灰度级进行计算,这就涉及到了插值算法,下面会讲。

1.6.3 图像的旋转变化

变换矩阵如下:

\[\begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1 \end{bmatrix} \]

变换后的坐标如下:

\[\begin{cases} x' = x\cos{\theta}-y\sin{\theta} \\ y' = x\sin{\theta}+y\cos{\theta} \end{cases} \]

公式推导:

如果原坐标\(x=P\cos{\alpha},y=P\sin{\alpha}\),假设逆时针旋转\(\alpha\)角度,那么变化后的坐标为

\[\begin{align*} x'&=P\cos{(\alpha+\theta)} \\ &=P\cos{\alpha}\cos{\theta}-P\sin{\alpha}\sin{\theta} \\ &=x\cos{\theta}-y\sin{\theta} \\ y'&=P\sin{(\alpha+\theta)} \\ &=P\sin{\alpha}\cos{\theta}+P\cos{\alpha}\sin{\theta} \\ &=x\sin{\theta}+y\cos{\theta} \end{align*} \]

注意:

  • 图像旋转后,会出现许多空白点(像素),对于这些空白点,必须赋予灰度值,否则图片效果会很差,这里同样用到插值算法
  • 这里的旋转适用的坐标轴是以左下角为矩阵,向右为x,向上为y的坐标轴,与openCV中矩阵坐标轴不一致,因此需要坐标轴变换。此外,还需要考虑旋转后图像的大小是否发生变化。映射的流程在空间坐标映射中体现:

1.6.4 空间坐标映射

根据顺序,存在两种映射方式:

  • 前向映射:根据\((x,y)\) 推导出\((x',y')\)
    • 缺点:可能多个点映射为一个点,也可能存在一些位置没有点映射过来。
  • 后向映射,由坐标值\((x',y')\)经过反向变换\(T^{-1}\)得到原先对应的坐标\((x,y)\),随后采用插值算法确定\(g(x',y')\)(即\((x',y')的灰度值\))。

二维图像的旋转映射

  • 前向映射:

现在有图像Image,shape为(height,weight),其中有一点像素为P(m,n),我们将图像逆时针旋转\(\theta\)度,得到Image',shape为(height',weight'),求新的像素位置。

步骤如下:

  1. 我们先为坐标系命名:

    • M为矩阵坐标系,左上角为坐标原点,向下为x的正方向,向右为y的正方向。M为计算机下图像的坐标系。
    • N为常用数学坐标系,左下为坐标原点,向右为x的正方向,向上为y轴的正方向。N下变换矩阵生效。
  2. 变换坐标系:因为题目中的坐标均为M坐标系下,而我们计算像素旋转都是在N坐标系下,因此需要对像素位置进行变换。转换公式为:

    \[若P_M(x,y),则: \\ P_N(x',y')= \begin{cases} x'= y \\ y'= height-x-1 \end{cases} \]

    因此\(P_N=P_N(n,height-m-1)\),记作\(P_N(x,y)\)

  3. 中心旋转:接下来就是选择相对于哪一点进行旋转,因为旋转前后图像的大小会发生变化,因此我们最好不要相对于边角进行旋转,一般选择中心进行旋转,中心坐标为\(O(\frac{weight-1}{2},\frac{height-1}{2})\),记作\(O(o_x,o_y)\)。旋转的步骤如下:

    1. 因为旋转公式是相对于原点的,因此将图片的中心移动到坐标原点,那么\(P_N(x,y)\)的坐标变换为:

      \[\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & -o_x \\ 0 & 1 & -o_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} \]

      得到了\(P'(x',y')\)

    2. 开始旋转:

      \[\begin{bmatrix} x'' \\ y'' \\ 1 \end{bmatrix} = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} \]

      得到旋转后的像素位置:\(P_N''(x'',y'')\)

    3. 将图像的中心点移动回原来的位置:

      \[\begin{bmatrix} x''' \\ y''' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & o_x' \\ 0 & 1 & o_y' \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x'' \\ y'' \\ 1 \end{bmatrix} \]

      注意:因为图像旋转后宽和高发生了变换,因此移动的尺度也发生了变化,现在是相对于旋转后的图像中心进行移动。

      得到旋转后的像素点:\(P_N'''(x''',y''')\)

  4. 将N坐标系变换回M坐标系,变换公式如下:

    \[若P_N(x,y),那么:\\ P_M(x',y')= \begin{cases} x'= height'-y-1\\ y'= x \end{cases} \]

    注意:因为变换后宽和高发生了变换,这里使用的是旋转后的宽和高。

    得到结果\(P_M'(height'-y'''-1,x''')\)

  • 后向映射:就是将上述步骤反过来,注意旋转前后图像宽和高的变化。

EG1:

现在有图像矩阵如下:

image-20230601213144980

图像大小为(4,5),像素点P(2,1),将图像旋转90°,求旋转后的像素点的坐标。

  1. 转化为一般直角坐标系:

\[P_N(x,y) \begin{cases} x = 1\\ y = 4-2-1=1 \end{cases} \\ P_N(x,y)=P_N(1,1) \]

  1. 相对于中心点旋转:

  2. 将中心点移动到原点:

    \[\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & -2 \\ 0 & 1 & -1.5 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} = \begin{bmatrix} -1 \\ -0.5 \\ 1 \end{bmatrix} \]

  3. 将图像逆时针旋转90°:

    \[\begin{bmatrix} x'' \\ y'' \\ 1 \end{bmatrix} = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} -1 \\ -0.5 \\ 1 \end{bmatrix} = \begin{bmatrix} 0.5 \\ -1 \\ 1 \end{bmatrix} \]

  4. 重新将图像移动回去:这里要注意,新的图像维度为(5,4),因此移动的尺度为(1.5, 2):

    \[\begin{bmatrix} x''' \\ y''' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1.5 \\ 0 & 1 & 2 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0.5 \\ -1 \\ 1 \end{bmatrix} = \begin{bmatrix} 2 \\ 1 \\ 1 \end{bmatrix} \]

得到\(P_N'''(2,1)\)

  1. 再将常用坐标系变换回矩阵坐标系:注意旋转后矩阵的大小发生了变化:

\[ P_M(x,y)= \begin{cases} x = height'''-y-1=3 \\ y = x'''=2 \end{cases} \]

因此变换后的像素位置为(3,2)。

image-20230601214649112

EG2:将上述过程逆向,得到逆向映射:

  1. 变换为常用坐标:

\[ P_N(x,y)=(2,5-1-3)=(2,1) \]

  1. 顺时针旋转90°,也就是逆时针旋转270°:

  2. 中心移动到坐标原点:

    \[\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & -1.5 \\ 0 & 1 & -2 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 2 \\ 1 \\ 1 \end{bmatrix} = \begin{bmatrix} 0.5\\ -1 \\ 1 \end{bmatrix} \]

  3. 逆时针旋转270°

    \[\begin{bmatrix} x'' \\ y'' \\ 1 \end{bmatrix} = \begin{bmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0.5 \\ -1 \\ 1 \end{bmatrix} = \begin{bmatrix} -1 \\ -0.5 \\ 1 \end{bmatrix} \]

  4. 中心移动回去:注意矩阵的大小发生变化

    \[\begin{bmatrix} x''' \\ y''' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 2 \\ 0 & 1 & 1.5 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} -1 \\ -0.5 \\ 1 \end{bmatrix} = \begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} \]

  5. 再将坐标系由常用直角坐标系变换为矩阵坐标系:

\[ P_N(4-1-1, 1)=P(2,1) \]

1.6.5 像素灰度插值

原因:

图像中的像素只有整数坐标,坐标值\((x',y')\)经过反向映射得到的原坐标值\((x,y)\)很可能并不是整数,那么我们如何确定\(g(x',y')\)这里就需要泳道灰度插值算法。

常用的有三种办法

  • 最邻近插值算法

    • 原理:跟左上、左下、右上、右下四个像素点,哪个最近就用哪个的灰度值。

      image-20230601172727191
    • 优点:简单,效果还行。

    • 缺点:校正后图像会有明显的锯齿状,且灰度不连续。

  • 双线性插值

    • 原理:就是对像素点在x、y的方向上分别进行一次单线性插值。具体如下:

      image-20230601173436894
      • 先在x维度上进行第一次单线性插值,得到\(R_1\) 的灰度值\(R_2\)

        \[R_1 = \frac{x_2-x}{x_2-x_1}Q_{21}+\frac{x-x_1}{x_2-x_1}Q_{11} \\ R_2 = \frac{x_2-x}{x_2-x_1}Q_{22}+\frac{x-x_1}{x_2-x_1}Q_{12} \]

      • 再在y维度上进行一次单线性插值,得到P的灰度值:

        \[P=\frac{y_2-y}{y_2-y_1}R_1+\frac{y-y_1}{R_2-R_1}R_2 \]

        由此可得g(p)

    • EG:

      假设\(P'(x',y')\)经过反向映射得到的原坐标为\(P(x,y)\)为(12.8, 15.3),那么周边四个点分别为:\(N_1(12,15),N_2(12,16),N_3(13,15),N_4(13,16)\)那么:

      \[R_1 = \frac{16-15.3}{16-15}N_1+\frac{15.3-15}{16-15}N_2=0.7N_1+0.3N_2 \\ R_2 = \frac{16-15.3}{16-15}N_3+\frac{15.3-15}{16-15}N_4=0.7N_3+0.3N_4 \\ \begin{align*} g(P)&=\frac{13-12.8}{13-12}R_1+\frac{12.8-12}{13-12}R_2 \\ &=0.2R_1+0.8R_2 \\ &=0.2*0.7*N_1+0.2*0.3N_2+0.8*0.7N_3+0.8*0.3N_4 \end{align*} \]

      简单来说:根据四个点与像素点P的距离,为不同的像素分配不同的灰度,在双线性中成对角形式。

      假设像素点四个临近点依次为:左上、右上、左下、右下\(N_1,N_2,N_3,N_4\),对应坐标的绝对值差值依次为\((\Delta{x_1},\Delta{y_1}),(\Delta{x_2},\Delta{y_2}),(\Delta{x_3},\Delta{y_3}),(\Delta{x_4},\Delta{y_4})\),那么:

      \[g(P) = \Delta{x_4}*\Delta{y_4}*N_1 \\ \qquad +\Delta{x_3}*\Delta{y_3}*N_2 \\ \qquad +\Delta{x_2}*\Delta{y_2}*N_3 \\ \qquad +\Delta{x_1}*\Delta{y_1}*N_4 \]

  • 三次内插法: