最近在看Google的Spatial Transformer Networks,脑洞又一次大开,故打算将学的一点东西记录在这里,本篇博文是学习Spatial Transformer Networks (STN)的基础,主要介绍仿射变换和双线性插值。内容主要参考了Kevin Zakka的博客,有兴趣的戳这里Deep Learning Paper Implementations: Spatial Transformer Networks - Part I
仿射变换
下面的所有变换假设都是针对一幅图像,即一个三维数组(H*W*C),这里为简单起见,假设图像都是单通道(C=1)的。首先说明一下待会要用到的符号:
-
(x,y): 原图像中某一点A的位置
-
(x′,y′): 变换后图像中A点对应的位置
几种常用的线性变换
平移(translation)
若将原图像沿x和y方向分别平移δx和δy,即:
x′=x+δxy′=x+δy(1)
写成矩阵形式如下:
(x′y′)=(1001)(xy)+(δxδy)=(1001δxδy)⎛⎝⎜xy1⎞⎠⎟(2)
缩放(Scaling)
假设将图像分别沿x和y方向分别缩放p倍和q倍,且p>0,q>0,即:
x′=pxy′=qy(3)
写成矩阵形式如下:
(x′y′)=(p00q)(xy)(4)
旋转(Rotation)
图1. 旋转变换示意图
如上图所示,点A旋转θ角到点B,由B点可得
x′=Rcosαy′=Rsinα(5)
由
A点可得:
x=Rcos(α+θ)y=Rsin(α+θ)(6)
由(5)和(6)整理可得:
x′=xcosθ+y′sinθy=−xsinθ+y′cosθ(7)
写成矩阵形式如下:
(x′y′)=(cosθ−sinθsinθcosθ)(xy)(8)
剪切(Shear)
剪切变换相当于将图片沿x和y两个方向拉伸,且x方向拉伸长度与y有关,y方向拉伸长度与x有关,用矩阵形式表示前切变换如下:
(x′y′)=(1nm1)(xy)(9)
仿射变换
其实上面几种常见变换都可以用同一种变换来表示,就是仿射变换,它有更一般的形式,如下:
(x′y′)=(adbecf)⎛⎝⎜xy1⎞⎠⎟(10)
当
a=e=1,b=c=d=f=0,为恒等变换,即输入图像不变;当
a=e=1,b=d=0时,为平移变换;当
a=cosθ,b=sinθ,d=−sinθ,e=cosθ,c=f=0时,为旋转变换;当
a=e=1,c=f=0时,为剪切变换。当6个参数取其他值时,为一般的仿射变换,效果相当于从不同的位置看同一个目标。
双线性插值
在对图像进行仿射变换时,会出现一个问题,当原图像中某一点的坐标映射到变换后图像时,坐标可能会出现小数(如图2所示),而我们知道,图像上某一像素点的位置坐标只能是整数,那该怎么办?这时候双线性插值就起作用了。
图2. (图片链接)
双线性插值的基本思想是通过某一点周围四个点的灰度值来估计出该点的灰度值,如图3所示.
图3. 双线性插值原理示意图
在实现时我们通常将变换后图像上所有的位置映射到原图像计算(这样做比正向计算方便得多),即依次遍历变换后图像上所有的像素点,根据仿射变换矩阵计算出映射到原图像上的坐标(可能出现小数),然后用双线性插值,根据该点周围4个位置的值加权平均得到该点值。过程可用如下公式表示:
R1=x2−xx2−x1Q11+x−x1x2−x1Q21R2=x2−xx2−x1Q12+x−x1x2−x1Q22(11)
P=y2−yy2−y1R1+y−y1y2−y1R2(12)
将(11)代入(12)整理得:
P=(y2−y)(x2−x)(y2−y1)(x2−x1)Q11+(y2−y)(x−x1)(y2−y1)(x2−x1)Q21+(y−y1)(x2−x)(y2−y1)(x2−x1)Q12+(y−y1)(x−x1)(y2−y1)(x2−x1)Q22(13)
因为
Q11,Q12,Q21,Q22是相邻的四个点,所以
y2−y1=1,x2−x1=1,则(13)可化简为:
P=(y2−y)(x2−x)Q11+(y2−y)(x−x1)Q21+(y−y1)(x2−x)Q12+(y−y1)(x−x1)Q22(14)
参考文献