目录
本章讲解图像之间的变换,以及一些计算变换的实用方法。这些变换可以用于图像扭曲变形和图像配准。
3.1 单应性变换
单应性变换是将一个平面内的点映射到另一个平面内的二维投影变换,这里的平面是指图像或者三维中的平面表面。单应性变换具有很强的实用性,比如说图像的配准、图像纠正和纹理扭曲,以及创建全景图像等。本质上,单应性变换H,按照下面的方程映射二维中的点:
\(\begin{bmatrix}x'\\y'\\w'\end{bmatrix}=\begin{bmatrix}h_1&h_2&h_3\\h_4&h_5&h_6\\h_7&h_8&h_9\end{bmatrix}\begin{bmatrix}x\\y\\w\end{bmatrix}\)或\(\mathbf{x}^{\prime}=H\mathbf{x}\)
对于图像平面内的点,齐次坐标是一个非常有用的表达方式。点的齐次坐标是依赖于其尺度定义的,所以\(x=[x,y,w]=[ax,ay,aw]=[x/w,y/w,1]\),表示的是同一个二维点。单应性矩阵仅依赖尺度定义,具有8个独立的自由度。
创建一个能够实现对点进行归一化和转换齐次坐标的功能:
def normalize(points):
"""
在其次坐标意义下对点集进行归一化处理
:param points: 点集
:return:
"""
for row in points:
row /= points[-1]
return points
def make_homog(points):
"""
将点集转化为齐次坐标表示
:param points: 点集
:return:
"""
return vstack((points, ones((1, points.shape[1]))))
进行点和变换的处理时,按照列优先的原则存储这些点,故n个三维点集将会依次存储为齐次坐标意义下的一个3*n数组。
在这些投影变换中存在一些特别重要的变换如:
仿射变换:
\(\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}a_1&a_2&t_x\\a_3&a_4&t_y\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}\)或\(x'=\begin{bmatrix}A&t\\0&1\end{bmatrix}x\)
w=1,不具有投影变换所具有的强大变形能力。仿射变换包含一个可逆矩阵A和一个平移向量\(t[t_{x},t_{y}]\)。
相似变换:
\(\begin{bmatrix}x'\\y'\\1\end{bmatrix}=\begin{bmatrix}s\cos(\theta)&-s\sin(\theta)&t_x\\s\sin(\theta)&s\cos(\theta)&t_y\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}\)或\(x'=\begin{bmatrix}sR&t\\0&1\end{bmatrix}x\)
包含尺度变换的二维刚体变换,上式的s向量指定了变换的尺度,R是角度为的旋转矩阵,\(t=[t_{x},t_{y}]\)是一个平移向量,s=1时,该变换甭管保存距离不变,此时变换为刚体变换。
3.1.1 直接线性变换算法
单应性矩阵可以由两幅图像中对于点计算出来,我们已经了解到一个完全射影变换具有8个自由度,而每个对应点可以写出两个方程,对应x和y坐标,所以计算单应性矩阵H要4个对应点对。计算H的方程如下:
\(\begin{bmatrix}-x_1&-y_1&-1&0&0&0&x_1x_1'&y_1x_1'&x_1'\\0&0&0&-x_1&-y_1&-1&x_1y'_1&y_1y'_1&y'_1\\-x_2&-y_2&-1&0&0&0&x_2x'_2&y_2x'_2&x'_2\\0&0&0&-x