【数字图像处理】图像的几何变换

2023-11-17


包含相同内容的两幅图像可能由于成像角度,透视关系乃至镜头自身原因所造成的几何失真而呈现截然不同的外观。
通过适当的几何变换可以最大程度地消除这些几何失真所产生的负面影响,有利于在后续的处理和识别工作中将注意力集中于图像的内容本身。

图像几何变换的一般思路

一个几何变换需要两部分运算:

首先是空间变换所需的运算,如平移、旋转和镜像等,需要用它来表示输出图像与输入图像之间的映射关系;

此外,还需要使用灰度插值算法,按照这种变换关系进行计算,输出图像的像素可能被映射到输入图像的非整数坐标上。

设原图像 f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0)经过几何变换产生的目标图像为 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1),则该空间变换映射关系可表示为:
x 1 = s ( x 0 , y 0 ) (1) x_1 = s(x_0, y_0) \tag{1} x1=s(x0,y0)(1)

y 1 = t ( x 0 , y 0 ) (2) y_1 = t(x_0, y_0) \tag{2} y1=t(x0,y0)(2)

其中, s ( x 0 , y 0 ) s(x_0, y_0) s(x0,y0) t ( x 0 , y 0 ) t(x_0, y_0) t(x0,y0)为由 f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0) g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1)的坐标变换函数。

比如,当 x 1 = s ( x 0 , y 0 ) = 2 x 0 x_1 = s(x_0, y_0) = 2 x_0 x1=s(x0,y0)=2x0 y 1 = t ( x 0 , y 0 ) = 2 y 0 y_1 = t(x_0, y_0) = 2 y_0 y1=t(x0,y0)=2y0时,变换后的图像 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1)只是简单地在 x x x y y y两个空间方向上将 f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0)的尺寸放大一倍。

掌握了有关变换函数 s ( x 0 , y 0 ) s(x_0, y_0) s(x0,y0) t ( x 0 , y 0 ) t(x_0, y_0) t(x0,y0)的情况,可以遵循下面的步骤实现几何变换。

算法4.1步骤:

  • 根据空间变换的映射关系,确定变换后目标图像的大小,亦即行、列范围,因为有些变换可能改变图像大小;
  • 计算逆变换 s − 1 ( j 1 , i 1 ) s^{-1} (j_1, i_1) s1(j1,i1) t − 1 ( j 1 , i 1 ) t^{-1} (j_1, i_1) t1(j1,i1)
  • 逐行扫描目标图像 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1),对于 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1)中的每一点 ( j 0 , j 0 ) (j_0, j_0) (j0,j0)
    • 根据空间变换的映射关系,计算得:
      • j 0 ′ = s − 1 ( j 1 , i 1 ) ; j_0' = s^{-1}(j_1, i_1); j0=s1(j1,i1); // 直接通过映射关系计算得到的横坐标,可能不是整数;
      • i 0 ′ = t − 1 ( j 1 , i 1 ) ; i_0' = t^{-1}(j_1, i_1); i0=t1(j1,i1); // 直接通过映射关系计算得到的纵坐标,可能不是整数;
    • 根据选用的插值方法:
      • ( j 0 , i 0 ) = i n t e r p ( j 0 ′ , i 0 ′ ) ; (j_0, i_0) = interp(j_0', i_0'); (j0,i0)=interp(j0,i0); // 对于非整数坐标 ( j 0 ′ , i 0 ′ ) (j_0', i_0') (j0,i0)需要插值
      • i f if if ( j 0 , i 0 ) (j_0, i_0) (j0,i0)在图像 f f f之内
        • 拷贝对应像素: g ( j 1 , i 1 ) = f ( j 0 , i 0 ) ; g(j_1, i_1) = f(j_0, i_0); g(j1,i1)=f(j0,i0);
      • e l s e else else
        • g ( j 1 , i 1 ) = 255 ; g(j_1, i_1) = 255; g(j1,i1)=255;

对于几何失真图像的复原(校正)过程正好是上述变换的逆过程。
x 0 = s − 1 ( x 1 , y 1 ) (3) x_0 = s^{-1} (x_1, y_1) \tag{3} x0=s1(x1,y1)(3)

y 0 = t − 1 ( x 1 , y 1 ) (4) y_0 = t^{-1}(x_1, y_1) \tag{4} y0=t1(x1,y1)(4)

式(3)和(4)表示相应的由 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1) f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0)的逆变换。此时,经过几何变换而失真的图像 g ( x 1 , y 1 ) g(x_1, y_1) g(x1,y1)是要复原的对象,原始图像 f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0)是复原的目标。

当图像归一化用于消除几何因素造成的图像外观变化时,称为图像几何归一化,它能够排除对象间几何关系的差别,找出图像中的那些几何不变量,从而得知这些对象原本就是一样的或属于相同的类别。


图像平移

图像平移就是将图像中所有的点按照指定的平移量水平或垂直移动。
( x 0 , y 0 ) (x_0, y_0) (x0,y0)是原图像上的一点,图像水平平移量为 T x T_x Tx, 垂直平移量为 T y T_y Ty,
平移之后的点坐标变为 ( x 1 , y 1 ) (x_1, y_1) (x1,y1),变为
x 1 = x 0 + t x x_1 = x_0 + t_x x1=x0+tx
y 1 = y 0 + t y y_1 = y_0 + t_y y1=y0+ty

用矩阵表示为
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ 1 0 0 0 1 0 T x T y 1 ] (5) \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ T_x & T_y & 1 \end{bmatrix} \tag{5} [x1y11]=[x0y01] 10Tx01Ty001 (5)
对变换矩阵求逆,可以得到逆变换:
[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ 1 0 0 0 1 0 − T x − T y 1 ] (6) \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} = \begin{bmatrix}x_1 & y_1 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ -T_x & - T_y & 1 \end{bmatrix} \tag{6} [x0y01]=[x1y11] 10Tx01Ty001 (6)

{ x 0 = x 1 − T x y 0 = y 1 − T y (7) \left \{ \begin{matrix} x_0 = x_1 - T_x \\ y_0 = y_1 - T_y \end{matrix} \right. \tag{7} {x0=x1Txy0=y1Ty(7)
从上面的公式中可以得到,平移后的目标图像中的每一点都可以在原图像中找到对应的点。

比如,对于新图中的 ( i , j ) (i,j) (i,j)像素,带入公式可以得到其对应原图像中的像素 ( i − T x , j − T y ) (i-T_x, j-T_y) (iTx,jTy)。此时,如果 T x > i T_x > i Tx>i T y > j T_y > j Ty>j,点 ( i − T x , j − T y ) (i-T_x, j-T_y) (iTx,jTy)就超出了原图的范围,可以直接将它的像素值统一设置为 0 0 0 255 255 255

对于原图中被移出图像显示区域的点通常也有两种处理方法,可以直接丢弃,也可以通过适当增加目标图像的尺寸,将新生成的图像宽度增加 T x T_x Tx,高度增加 T y T_y Ty的方法使得新图像中能够包含这些点。

imtransform函数用于完成一般的二维空间变换。
函数原型:B = imtransform(A, TFORM, method);

  • A为要进行几何变换的图像;
  • TFORM指定了具体的变换类型;
  • method允许为imtransform函数选择插值方法,可选的插值方法有:bicubic、bilinear、nearest

可以通过两种方法来创建TFORM结构,使用maketform函数和cp2tform函数。
cp2tform是一个数据拟合函数,它需要原图像与目标图像之间的对应点对作为输入,用于确定基于控制点对的几何变换关系。

maketform函数调用形式:T = maketform(transformtype, Matrix);

  • 参数transformtype指定了变换的类型;
  • 参数Matrix为相应的仿射变换矩阵,例如对于平移变换,该矩阵为[1,0,0;0,1,0;T_x,T_y,1]

图像镜像

图像镜像变换分为水平镜像和垂直镜像。水平镜像将图像左半部分和右半部分以图像竖直中轴线为中心轴进行兑换;竖直镜像将图像上半部分和下半部分以图像水平中轴线为中心轴进行兑换。

水平镜像的变换公式:
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ − 1 0 0 0 1 0 W i d t h 0 1 ] = [ W i d t h − x 0 y 0 1 ] (8) \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ Width & 0 & 1 \end{bmatrix} = \begin{bmatrix}Width-x_0 & y_0 & 1 \end{bmatrix} \tag{8} [x1y11]=[x0y01] 10Width010001 =[Widthx0y01](8)
对矩阵求逆得到:
[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ − 1 0 0 0 1 0 W i d t h 0 1 ] = [ W i d t h − x 1 y 1 1 ] (9) \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} = \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} \begin{bmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ Width & 0 & 1 \end{bmatrix} = \begin{bmatrix} Width - x_1 & y_1 & 1 \end{bmatrix} \tag{9} [x0y01]=[x1y11] 10Width010001 =[Widthx1y11](9)
竖直镜像变换关系可形式化地描述如下:
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ 1 0 0 0 − 1 0 0 H e i g h t 1 ] (10) \begin{bmatrix}x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & Height & 1 \end{bmatrix} \tag{10} [x1y11]=[x0y01] 10001Height001 (10)
逆运算为:
[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ 1 0 0 0 − 1 0 0 H e i g h t 1 ] (11) \begin{bmatrix}x_0 & y_0 & 1 \end{bmatrix} = \begin{bmatrix}x_1 & y_1 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & Height & 1 \end{bmatrix} \tag{11} [x0y01]=[x1y11] 10001Height001 (11)


图像转置

图像转置是将图像像素的 x x x坐标和 y y y坐标互换,转置后图像的大小会随之改变,高度和宽度将互换。

转置变换公式如下:
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ 0 1 0 1 0 0 0 0 1 ] (12) \begin{bmatrix}x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix}x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} 0 & 1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix} \tag{12} [x1y11]=[x0y01] 010100001 (12)
转置矩阵的逆矩阵仍然为其自身。


图像缩放

图像缩放是指图像按照指定的比率放大或者缩小。

假设图像 x x x轴方向的缩放比率为 S x S_x Sx y y y轴方向的缩放比率为 S y S_y Sy,相应的变换表达式为:
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ S x 0 0 0 S y 0 0 0 1 ] = [ x 0 ⋅ S x y 0 ⋅ S y 1 ] (13) \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} S_x & 0 & 0 \\ 0 & S_y & 0 \\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix}x_0 \cdot S_x & y_0 \cdot S_y & 1 \end{bmatrix} \tag{13} [x1y11]=[x0y01] Sx000Sy0001 =[x0Sxy0Sy1](13)
其逆运算如下:
[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ 1 S x 0 0 0 1 S y 0 0 0 1 ] = [ x 1 S x y 1 S y 1 ] (14) \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} = \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} \begin{bmatrix} \frac{1}{S_x} & 0 & 0 \\ 0 & \frac{1}{S_y} & 0 \\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} \frac{x_1}{S_x} & \frac{y_1}{S_y} & 1 \end{bmatrix} \tag{14} [x0y01]=[x1y11] Sx1000Sy10001 =[Sxx1Syy11](14)
直接根据缩放公式计算得到的目标图像,某些映射源坐标可能不是整数,从而找不到对应的像素位置。比如当图像放大2倍时,即 S x = S y = 2 S_x = S_y = 2 Sx=Sy=2,放大图像中的像素 ( 0 , 1 ) (0,1) (0,1)对应于原图中的像素 ( 0 , 0.5 ) (0, 0.5) (0,0.5),这不是整数坐标位置,无法提取其灰度值。

必须进行某种近似处理,一种简单的策略是直接使用最邻近的整数坐标位置 ( 0 , 0 ) (0,0) (0,0)或者 ( 0 , 1 ) (0,1) (0,1)处的像素灰度值,这也是最近邻插值算法。


图像旋转

旋转一般是指将图像围绕某一指定点旋转一定的角度。旋转通常也会改变图像的大小。如下图所示

在这里插入图片描述

P ( x 0 , y 0 ) P(x_0, y_0) P(x0,y0)绕原点逆时针旋转角度 θ \theta θ P 1 ( x 1 , y 1 ) P1(x_1, y_1) P1(x1,y1),令 L = ∣ O P ∣ = x 2 + y 2 L = |OP| = \sqrt{x^2 + y^2} L=OP=x2+y2 ,有: s i n α = y 0 / L sin \alpha = y_0/L sinα=y0/L c o s α = x 0 / L cos \alpha = x_0/L cosα=x0/L

到达 P 1 P1 P1点后,有:
s i n ( α + θ ) = y 1 / L = c o s θ s i n α + s i n θ c o s α c o s ( α + θ ) = x 1 / L = c o s θ c o s α − s i n θ s i n α (15) sin(\alpha + \theta) = y_1 / L = cos \theta sin \alpha + sin \theta cos \alpha \tag{15} \\ cos(\alpha + \theta) = x_1/L = cos \theta cos \alpha - sin \theta sin \alpha sin(α+θ)=y1/L=cosθsinα+sinθcosαcos(α+θ)=x1/L=cosθcosαsinθsinα(15)
于是有:
x 1 = c o s θ x 0 − s i n θ y 0 y 1 = c o s θ y 0 + s i n θ x 0 (16) x_1 = cos \theta x_0 - sin \theta y_0 \tag{16} \\ y_1 = cos \theta y_0 +sin \theta x_0 x1=cosθx0sinθy0y1=cosθy0+sinθx0(16)
得到旋转变换公式为:
[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ] (17) \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} = \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} \begin{bmatrix} cos \theta & sin \theta & 0 \\ -sin \theta & cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \tag{17} [x1y11]=[x0y01] cosθsinθ0sinθcosθ0001 (17)
其逆运算为:
[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] (18) \begin{bmatrix} x_0 & y_0 & 1 \end{bmatrix} = \begin{bmatrix} x_1 & y_1 & 1 \end{bmatrix} \begin{bmatrix} cos \theta & - sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \tag{18} [x0y01]=[x1y11] cosθsinθ0sinθcosθ0001 (18)
上面的讨论基于以原点即图像左下角为中心进行的,如何围绕任意的指定点来旋转?

将平移和旋转操作相结合即可,先进行坐标系平移,再以新的坐标原点为中心旋转,之后将新原点平移回原坐标系的原点。这个过程可以归纳为以下3个步骤:

  1. 将坐标系Ⅰ变成Ⅱ;
  2. 将该点顺时针旋转 θ \theta θ角;
  3. 将坐标系Ⅱ变回Ⅰ;

以围绕图像中心的旋转为例,如下图所示,坐标系Ⅰ以图像左上角点位原点,向右为 x x x轴正方向,向下为 y y y轴正方向;而坐标系Ⅱ以图像中心为原点,向右为 x x x轴正方向,向下为 y y y轴正方向。坐标系Ⅰ与坐标系Ⅱ之间的转换关系如下:

在这里插入图片描述

假设图像的宽为 w w w, 高位 h h h,容易得到:
[ x Ⅰ y Ⅰ 1 ] = [ x Ⅱ y Ⅱ 1 ] [ 1 0 0 0 − 1 0 0.5 w 0.5 h 1 ] (19) \begin {bmatrix} x_Ⅰ \\ y_Ⅰ \\ 1 \end{bmatrix} = \begin {bmatrix} x_Ⅱ \\ y_Ⅱ \\ 1 \end{bmatrix} \begin {bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0.5w & 0.5h & 1 \end{bmatrix} \tag{19} xy1 = xy1 100.5w010.5h001 (19)
相应的逆变换为:
[ x Ⅱ y Ⅱ 1 ] = [ x Ⅰ y Ⅰ 1 ] [ 1 0 0 0 − 1 0 − 0.5 w 0.5 h 1 ] (20) \begin{bmatrix} x_Ⅱ \\ y_Ⅱ \\ 1 \end{bmatrix} = \begin{bmatrix} x_Ⅰ \\ y_Ⅰ \\ 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ -0.5w & 0.5h & 1 \end{bmatrix} \tag{20} xy1 = xy1 100.5w010.5h001 (20)
这里已经实现上述3个步骤中的第1步和第3步,再加上第2步的旋转变换就得到了围绕图像中心点旋转的最终变换矩阵。该矩阵实际上是3个变换步骤中分别用到的3个变换矩阵的级联。式中, W o l d W_{old} Wold H o l d H_{old} Hold W n e w W_{new} Wnew H n e w H_{new} Hnew分别表示原图像和新图像的宽和高。

[ x 1 y 1 1 ] = [ x 0 y 0 1 ] [ 1 0 0 0 − 1 0 − 0.5 W o l d 0.5 H o l d 1 ] [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] [ 1 0 0 0 − 1 0 0.5 W n e w 0.5 H n e w 1 ] = [ x 0 y 0 1 ] [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0.5 ⋅ ( − W o l d ⋅ c o s θ + H o l d ⋅ s i n θ + W n e w ) 0.5 ( − W o l d ⋅ s i n θ − H o l d ⋅ c o s θ + H n e w ) 1 ] \begin{align} \begin{bmatrix} x_1 \\ y_1 \\ 1 \end{bmatrix} &= \begin{bmatrix} x_0 \\ y_0 \\ 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ -0.5W_{old} & 0.5H_{old} & 1 \end{bmatrix} \begin{bmatrix} cos \theta & -sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0.5W_{new} & 0.5 H_{new} & 1 \end{bmatrix} \nonumber \\ &= \begin{bmatrix} x_0 \\ y_0 \\ 1 \end{bmatrix} \begin{bmatrix} cos \theta & sin \theta & 0 \\ -sin \theta & cos \theta & 0 \\ 0.5 \cdot (-W_{old} \cdot cos \theta + H_{old} \cdot sin \theta + W_{new} ) & 0.5 ( - W_{old} \cdot sin \theta - H_{old} \cdot cos \theta + H_{new}) & 1 \end{bmatrix} \tag{21} \end{align} x1y11 = x0y01 100.5Wold010.5Hold001 cosθsinθ0sinθcosθ0001 100.5Wnew010.5Hnew001 = x0y01 cosθsinθ0.5(Woldcosθ+Holdsinθ+Wnew)sinθcosθ0.5(WoldsinθHoldcosθ+Hnew)001 (21)

上式的逆变换为:

[ x 0 y 0 1 ] = [ x 1 y 1 1 ] [ 1 0 0 0 − 1 0 − 0.5 W n e w 0.5 H n e w 1 ] [ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ] [ 1 0 0 0 − 1 0 0.5 W o l d 0.5 H o l d 1 ] = [ x 1 y 1 1 ] [ c o s θ − s i n θ 0 s i n θ c o s θ 0 − 0.5 W n e w ⋅ c o s θ − 0.5 H n e w ⋅ s i n θ + 0.5 W o l d 0.5 W n e w ⋅ s i n θ − 0.5 H n e w ⋅ c o s θ + 0.5 H o l d 1 ] \begin{align} \begin{bmatrix} x_0 \\ y_0 \\ 1 \end{bmatrix} &= \begin{bmatrix} x_1 \\ y_1 \\ 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ -0.5W_{new} & 0.5 H_{new} & 1 \end{bmatrix} \begin{bmatrix} cos \theta & sin \theta & 0 \\ -sin \theta & cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ 0.5W_{old} & 0.5 H_{old} & 1 \end{bmatrix} \nonumber \\ &= \begin{bmatrix} x_1 \\ y_1 \\ 1 \end{bmatrix} \begin{bmatrix} cos \theta & -sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ -0.5 W_{new} \cdot cos \theta - 0.5 H_{new} \cdot sin \theta + 0.5 W_{old} & 0.5 W_{new} \cdot sin \theta - 0.5 H_{new} \cdot cos \theta + 0.5 H_{old} & 1 \end{bmatrix} \tag{22} \end{align} x0y01 = x1y11 100.5Wnew010.5Hnew001 cosθsinθ0sinθcosθ0001 100.5Wold010.5Hold001 = x1y11 cosθsinθ0.5Wnewcosθ0.5Hnewsinθ+0.5Woldsinθcosθ0.5Wnewsinθ0.5Hnewcosθ+0.5Hold001 (22)

可以根据逆变换公式,按照算法4.1中的描述实现围绕图像中心的旋转变换,类似地,可以进一步得到以任意点为中心的旋转变换。


插值算法

实现几何运算时,有两种方法:向前映射法和向后映射法。

  • 向前映射法,其原理是将输入图像的灰度按照像素依次转移到输出图像中,即从原图像坐标计算出目标图像坐标: g ( x 1 , y 1 ) = f ( a ( x 0 , y 0 ) , b ( x 0 , y 0 ) ) g(x_1, y_1) = f(a(x_0, y_0), b(x_0, y_0)) g(x1,y1)=f(a(x0,y0),b(x0,y0))。比如图像的平移、镜像等操作可以采用这种方法。
  • 向后映射法,是向前映射变换的逆,即输出像素依次映射回输入图像中,如果一个输出像素映射到的不是输入图像的采样栅格的整数坐标处的像素点,则其灰度值就需要基于整数坐标的灰度值进行推断,这就是插值。向后映射法是逐个像素产生输出图像,不会产生计算浪费问题,再缩放、旋转等操作中多采用这种方法。

常用的插值算法有:最近邻插值、双线性插值、高阶插值。

最近邻插值

最近邻插值算法,输出像素的值为输入图像中与其最邻近的采样点的像素值。

最近邻插值可以表示为
f ( x , y ) = g ( r o u n d ( x ) , r o u n d ( y ) ) (23) f(x,y) = g(round(x), round(y)) \tag{23} f(x,y)=g(round(x),round(y))(23)
最近邻插值计算简单,在多数情况下的输出效果也可以接收。但是,最近邻插值会在图像中产生人为加工的痕迹。

双线性插值

双线性插值又称为一阶插值,是线性插值扩展到二维的一种应用,可以通过一系列的一阶线性插值得到。

线性,指量与量之间按比例、成直线的关系,在数学上可以理解为一阶导数为常数的函数。

线性插值是指根据两个点的值线性地确定位于这两个点连线上的某一点的值。

输出像素的值为输入图像中距离它最近的 2 × 2 2 \times 2 2×2邻域内采样点像素灰度值的加权平均。

设已知单位正方形的顶点坐标分别为 f ( 0 , 0 ) , f ( 1 , 0 ) , f ( 0 , 1 ) , f ( 1 , 1 ) f(0,0), f(1,0), f(0,1), f(1,1) f(0,0),f(1,0),f(0,1),f(1,1),如下图所示,要通过线性插值得到正方形内任意点 f ( x , y ) f(x,y) f(x,y)的值。

首先对上端的两个点进行线性插值,得到 f ( x , 0 ) f(x,0) f(x,0) f ( x , 0 ) = f ( 0 , 0 ) + x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] f(x,0) = f(0,0) + x [f(1,0) - f(0,0)] f(x,0)=f(0,0)+x[f(1,0)f(0,0)]

再对下端的两个顶点进行线性插值,得到 f ( x , 1 ) f(x,1) f(x,1) f ( x , 1 ) = f ( 0 , 1 ) + x [ f ( 1 , 1 , ) − f ( 0 , 1 ) ] f(x,1) = f(0,1) + x[f(1,1,) - f(0,1)] f(x,1)=f(0,1)+x[f(1,1,)f(0,1)]

最后,对垂直方向进行线性插值,得到 f ( x , y ) f(x,y) f(x,y) f ( x , y ) = f ( x , 0 ) + y [ f ( x , 1 ) − f ( x , 0 ) ] f(x,y) = f(x,0) + y [f(x,1) - f(x,0)] f(x,y)=f(x,0)+y[f(x,1)f(x,0)]

整理得到 f ( x , y ) f(x,y) f(x,y)

f ( x , y ) = [ f ( 1 , 0 ) − f ( 0 , 0 ) ] x + [ f ( 0 , 1 ) − f ( 0 , 0 ) ] y + [ f ( 1 , 1 ) + f ( 0 , 0 ) − f ( 0 , 1 ) − f ( 1 , 0 ) ] x y + f ( 0 , 0 ) (24) f(x,y) = [f(1,0) - f(0,0)] x + [f(0,1) - f(0,0)]y + [f(1,1) + f(0,0) - f(0,1) - f(1,0)] xy + f(0,0) \tag{24} f(x,y)=[f(1,0)f(0,0)]x+[f(0,1)f(0,0)]y+[f(1,1)+f(0,0)f(0,1)f(1,0)]xy+f(0,0)(24)

在这里插入图片描述

双线性插值的平滑作用会使图像的细节退化,而其斜率的不连续性则会导致变换产生不希望的结果。

高阶插值

双线性插值的去热点可以通过高阶插值得到弥补,高阶插值通常用卷积来实现。

输出像素的值为输入图像中距离它最近的 4 × 4 4 \times 4 4×4邻域内采样点像素值的加权平均值。

以三次插值为例,它使用了如下的三次多项式来逼近理论上的最佳插值函数 s i n c ( x ) sinc(x) sinc(x)
S ( x ) = { 1 − 2 ∣ x ∣ 2 + ∣ x ∣ 3 , 0 ≤ ∣ x ∣ < 1 4 − 8 ∣ x ∣ + 5 ∣ x ∣ 2 − ∣ x ∣ 3 , 1 ≤ ∣ x ∣ < 2 0 ∣ x ∣ ≥ 2 (25) S(x) = \left \{ \begin{matrix} \tag{25} 1 - 2 |x|^2 + |x|^3 , & 0 \le | x| < 1 \\ 4 - 8 |x| + 5 |x|^2 - |x|^3, & 1 \le |x| < 2 \\ 0 & |x| \ge 2 \end{matrix} \right. S(x)= 12∣x2+x3,48∣x+5∣x2x3,00x<11x<2x2(25)
上式中 ∣ x ∣ |x| x是周围像素沿 x x x方向与原点的距离。待求像素 ( x , y ) (x,y) (x,y)的灰度值由其周围16个点的灰度值加权插值得到。计算公式如下:
f ( x , y ) = f ( i + u , j + v ) = A B C (26) f(x,y) = f(i+u, j+v) = ABC \tag{26} f(x,y)=f(i+u,j+v)=ABC(26)
其中
A = [ S ( 1 + v ) S ( v ) S ( 1 − v ) S ( 2 − v ) ] T C = [ S ( 1 + u ) S ( u ) S ( 1 − u ) S ( 2 − u ) ] B = [ f ( i − 1 , j − 1 ) f ( i − 1 , j ) f ( i − 1 , j + 1 ) f ( i − 1 , j + 2 ) f ( i , j − 1 ) f ( i , j ) f ( j , j + 1 ) f ( i , j + 2 ) f ( i + 1 , j − 1 ) f ( i + 1 , j ) f ( i + 1 , j + 1 ) f ( i + 1 , j + 2 ) f ( i + 2 , j − 1 ) f ( i + 2 , j ) f ( i + 2 , j + 1 ) f ( i + 2 , j + 2 ) ] A = \begin{bmatrix} S(1+v) \\ S(v) \\ S(1-v) \\ S(2-v) \end{bmatrix} ^T \nonumber \\ C = \begin{bmatrix} S(1+u) \\ S(u) \\ S(1-u) \\ S(2-u) \end{bmatrix} \nonumber \\ B = \begin{bmatrix} f(i-1, j-1) & f(i-1, j) & f(i-1,j+1) & f(i-1, j+2) \nonumber \\ f(i,j-1) & f(i, j) & f(j, j+1) & f(i, j+2) \nonumber \\ f(i+1, j-1) & f(i+1, j) & f(i+1, j+1) & f(i+1, j+2) \nonumber \\ f(i+2, j-1) & f(i+2, j) & f(i+2, j+1) & f(i+2, j+2) \end{bmatrix} A= S(1+v)S(v)S(1v)S(2v) TC= S(1+u)S(u)S(1u)S(2u) B= f(i1,j1)f(i,j1)f(i+1,j1)f(i+2,j1)f(i1,j)f(i,j)f(i+1,j)f(i+2,j)f(i1,j+1)f(j,j+1)f(i+1,j+1)f(i+2,j+1)f(i1,j+2)f(i,j+2)f(i+1,j+2)f(i+2,j+2)
三次插值方法通常应用在光栅显示中,它在允许任意比例的缩放操作的同时,较好地保持了图像的细节。

未完待续~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数字图像处理】图像的几何变换 的相关文章

  • matlab中优先级队列的实现方法

    matlab中有没有提供minpriorityqueue功能的库 import java util PriorityQueue import java util public class MyQueue Comparator
  • 二维随机微分方程 (SDE)

    我第一次研究随机微分方程 我正在寻求模拟和求解二维随机微分方程 模型如下 dp F t p dt G t p dW t where p 是一个 2 1 向量 p theta t phi t F是列向量 F sin theta Psi cos
  • MATLAB 子图标题和轴标签

    我有以下脚本来最终绘制 4 x 2 子图 files getAllFiles preliminaries n size files cases cell 1 n m cell 1 n for i 1 1 n S load files i c
  • Matlab:如何读取以逗号作为小数分隔符的数字?

    我有很多 数十万 相当大 gt 0 5MB 的文件 其中数据是数字 但以逗号作为小数分隔符 使用像这样的外部工具对我来说是不切实际的sed s g 当分隔符是点时 我只使用textscan fid f f f 但我看不到更改小数点分隔符的选
  • MATLAB;具有 2+ 个/分割图例的饼图 R2017b

    我正在创建一个饼图 理想情况下希望图例水平显示在顶部和 或底部 然而 在几乎所有情况下 这是不可能的 因为图例超出了数字 因此 我理想情况下希望将图例分成两个 或更多 子图例并单独放置它们 我知道这不是 MATLAB 中的内置功能 我使用的
  • 在matlab中融合2个以上的图像

    在 MATLAB 中 如何融合两个以上的图像 例如 我想要做什么imfuse但对于超过 2 个图像 使用两张图像 这是我的代码 A imread file1 jpg B imread file2 jpg C imfuse A B blend
  • 可以避免迭代元胞数组时的“s{1} 烦恼”吗?

    The s 1 标题的 烦恼 指的是下面的 for 块中的第一行 for s some cell array s s 1 unpeel the enclosing cell do stuff with s end This s s 1 业务
  • 如何调整x轴和y轴的大小

    如何调整 x 轴和 y 轴的大小 我想要什么 更具体 3900 60 30 0 60 120 180 3600 我做了什么 a 0 0 1 10000 plot a 我应该写什么才能按预期调整 x 和 y 轴的大小 EDIT 我不想 390
  • Python 中的 eig(a,b) 给出错误“需要 1 个位置参数,但给出了 2 个”

    根据https docs scipy org doc numpy 1 15 0 user numpy for matlab users html https docs scipy org doc numpy 1 15 0 user nump
  • 静态时序数据的数据库解决方案

    我们拥有一个庞大且不断增长的实验数据集 该数据集取自约 30 000 名受试者 对于每个主题 都有多个数据记录 在每个记录中 收集了多个生理数据时间序列 每个时间序列约 90 秒长 并以 250Hz 采样 我应该注意到 时间序列的任何给定实
  • MATLAB 中的内存映射文件?

    我决定使用 memmapfile 因为我的数据 通常为 30Gb 到 60Gb 太大 无法放入计算机内存中 我的数据文件由两列数据组成 对应于两个传感器的输出 并且它们采用 bin 和 txt 格式 m memmapfile G E Str
  • 如何使用神经网络保存 Sift 特征向量进行分类

    SIFT 特征的 Matlab 实现发现于http www cs ubc ca lowe keypoints http www cs ubc ca lowe keypoints 在 stackoverflow 的帮助下 我想将功能保存到 m
  • 通过 h5py 将 matlab v7.3 文件读入 python numpy 数组列表

    我知道以前已经有人问过这个问题 但在我看来 仍然没有答案可以解释正在发生的事情 并且不适用于我的情况 我有一个 matlab v7 3 文件 其结构如下 gt rank lt 1x454 cell gt gt each element is
  • 有没有办法在 MATLAB 中查看 pcode 文件 (.p) 的源代码?

    有没有办法在 MATLAB 中打开 pcode 文件 p 如果 开放 是指edit 那么当然不是 pcode 中的 p 代表 受保护 其主要设计目标是在保护其源代码的同时部署功能组件 如果 开放 是指run 那么当然是的 引用手册 http
  • 图像分析-光纤识别

    我是图像分析新手 您知道如何以仅获取纤维的方式对该图像进行二值化吗 我尝试过不同的阈值技术等 但没有成功 我不介意应该使用什么工具 但我更喜欢 NET or Matlab PS 我不知道该把答案放在哪里 所以我把它放在StackOverfl
  • Matlab-如何在曲线上绘制切线

    我在 matlab 中绘制了一个图表 plot x y 我的图表有不同的斜率 我如何在每个斜率上绘制切线并计算斜率的系数 如果您没有用于绘制点的显式函数 您可以使用有限差分 http en wikipedia org wiki Finite
  • MATLAB中如何画水平线和垂直线?

    我目前正在尝试在 MATLAB 中绘制简单的垂直线和水平线 例如 我想绘制线 y 245 我该怎么做呢 MATLAB 根据您提供的向量逐点进行绘图 因此 要创建一条水平线 您需要改变x同时保持y对于垂直线恒定 反之亦然 xh 0 10 yh
  • 扩展 MATLAB 函数名称的最大长度

    我编写了一个 MATLAB 程序 可以动态创建自定义 MATLAB 函数 并使用以下命令在其他 MATLAB 实例中启动它们unix命令 我使用这个程序来自动化 fMRI 神经影像分析 使用 SPM8 for MATLAB 一切正常 但是
  • Matlab中转换数据类型的有效方法(double vs. im2double)

    我想将真彩色图像转换为双精度 据我所知有两种方法可以做到这一点 double rgb img im2double rgb img 哪一种效率更高 谢谢 他们都是不同的 im2double将图像的范围转换为0 1如果数据类型是uint8 or
  • 在 matlab 中求 3d 峰的体积

    现在我有一个带有峰值的 3D 散点图 我需要找到其体积 我的数据来自图像 因此 x 和 y 值表示 xy 平面上的像素位置 z 值是每个像素的像素值 这是我的散点图 scatter3 x y z 20 z filled 我试图找到数据峰值的

随机推荐

  • 关于三通道彩色图像的存储方式理解

    像素值以 矩阵方式 保存 矩阵的大小取决于图像采用的颜色模型 灰度图 如果是灰度图 那么图像就是单通道的 图像中的每个像素只需要一个矩阵元素来保存 一般就是 0 255 的值 保存灰度图的矩阵长这样 其中 Row0 和 Column0 的交
  • 测试用例设计方法——等价类

    等价类 思路 输入的集合是无穷的 不能全部都覆盖到 依据需求将输入 特殊情况下会考虑输出 划分为若干个等价类 从等价类中挑选一个测试用例 如果这个测试用例通过 则认为所代表的等价类通过 这样就可以用较少的测试用例达到尽可能多的功能覆盖 解决
  • usart串口只能发送不能接收

    今天出了一个低级错误 记录一下 下次注意 我想用stm32做一个usart发送和接收的程序 目标 发送用的是usart1串口 接收用的是中断 当有数据发送给单片机的时候 会触发中断 中断函数中将接受到的数据再发送出去 程序非常简单 我就不放
  • SpringBoot项目捕捉@Validated下@NotBlank、@NotNull等注解抛出的异常

    java捕捉 Validated下 NotBlank NotNull等注解抛出的异常 使用场景 新增通用返回实体类 修改controller 实体类添加 NotBlank 新增WebConfig 新增WebExceptionHandler
  • C++学习总结(二十二)——类模板与友元(友元函数,友元类模板)

    一 类模板与友元 当友元函数在外部定义时 友元函数以及所属的类必须声明 友元函数放在类模板的内部时 友元函数可以直接调用 无需加类限定符 include
  • 使用boost库来计算文件夹的大小

    include
  • 投资学实务 期货日志及实践总结

    我的期货交易可以分为三个阶段 摸索阶段9 27 9 30 日期 单日净盈利 累计净值 单日回撤 9 27 14370 0 9707 0 03 9 28 29670 1 0295 0 9 29 11855 1 0517 0 9 30 1647
  • Acwing-27. 数值的整数次方

    由于本题的指数是int范围 可能很大 所以需要用快速幂 Acwing 875 快速幂 中有详细介绍快速幂 点击链接即可传送 求解 https blog csdn net weixin 43844521 article details 127
  • torch.cat过程中遇到的问题

    项目场景 有关深度强化学习过程中使用torch cat遇到的问题 问题描述 在学习MEC 使用深度强化学习改变卸载率的过程中 要将action和state通过torch cat合并的时候遇到的问题 第一个问题 torch cat当中直接使用
  • 在Vim(gvim)中使用cscope

    之前已经详细的介绍了在vim中使用ctags 这篇文章我们就来详细介绍一下如何在vim中使用cscope 首先 我们还是了解一下什么是cscope 简单来讲 cscope主要用来协助浏览C C 语言 他的功能要强大于ctags 不仅支持变量
  • python基础--除法、地板除、取余

    在Python中 有两种除法 一种除法是 gt gt gt 10 3 3 3333333333333335 除法计算结果是浮点数 即使是两个整数恰好整除 结果也是浮点数 gt gt gt 9 3 3 0 还有一种除法是 称为地板除 两个整数
  • libevent涉及的知识积累

    O 1 实现单链表插入删除 阅读libevent源码时发现了linux提供的一个链表 宏定义如下 define LIST ENTRY type struct struct type le next next element struct t
  • msvcp140.dll丢失的解决方法,win10系统dll报错的解决方法

    今天 我将为大家分享一个关于msvcp140 dll丢失的解决方法 特别是针对在Windows 10系统上遇到这个问题的朋友们 在开始之前 我想先简要介绍一下msvcp140 dll文件的作用 msvcp140 dll是Microsoft
  • linux怎么修改目录的所有者,linux修改文件或目录的所有者(chown)和用户组

    chown更改文件或目录的所有者 注意 所有者 必须存在于 etc passwd 下 比如 linux修改文件或目录的所有者 chown 和用户组 更改文件或目录的所有者命令 1 新建测试文件test 命令为 touch test 2 查看
  • 由于找不到msvcp140.dll无法继续执行代码”问题的解决方法

    DLL文件对于Windows上的应用程序至关重要 因为这些文件在运行时是必需的 如果没有这些文件 或者它们已经损坏 相应的应用程序可能会变得不稳定 或者根本无法运行 现在 让我们一起探讨 由于找不到msvcp140 dll无法继续执行代码
  • html提示框延时消失,JS实现提示效果弹出及延迟隐藏的功能

    自动登录勾选提示效果 要求 鼠标移入显示提示信息框 鼠标离开 信息框消失 消失的效果延迟Document sign display inline block width 15px height 15px border 1px solid c
  • 小白的高德地图初体验(一) —— 打点

    小白的高德地图初体验 一 打点 说到高德地图 肯定要推荐官方文档 传送门 走你 小白的高德地图初体验 一 打点 小白的高德地图初体验 二 点聚合 小白的高德地图初体验 三 轨迹 小白的高德地图初体验 四 矢量图形 小白的高德地图初体验 五
  • NetBeans下载安装

    1 下载 网址 Apache NetBeans Releases 2 安装 执行exe 选择安装目录和jdk
  • qemu搭建和运行起来一个linux内核环境

    qemu搭建和运行起来一个linux内核环境 参考了博客 搭建linux调试环境 一 qemu环境搭建vexpress开发平台 Edver 博客园 嵌入式Linux之QEMU模拟器 4 使用busybox制作根文件系统 ReCclay的博客
  • 【数字图像处理】图像的几何变换

    文章目录 图像几何变换的一般思路 图像平移 图像镜像 图像转置 图像缩放 图像旋转 插值算法 最近邻插值 双线性插值 高阶插值 包含相同内容的两幅图像可能由于成像角度 透视关系乃至镜头自身原因所造成的几何失真而呈现截然不同的外观 通过适当的