当初选方向时就由于从小几何就很差、缺少空间想像能力才没有选择摄影测量方向而是选择了GIS。昨天同窗找我帮他作图像匹配,这我哪里懂啊,无奈我是一个别人有求于我,老是很差意思开口拒绝的人。因而乎就看着他给的一章节内容开始写程序了,今天总算给他完成了。作的比较简单,中间也遇到了很多问题,尤为是计算量大的问题,因为老师给的数据是粗配准过的数据, RANSAC算法评估时就简化了下。算法
理论内容:dom
第5章 图像配准创建几何变换模型优化
特征点创建匹配关系以后,下一步就是求解图像之间的变换关系。仿射变换可以很好的表达图像之间的通常变换,而且最少只须要3对匹配点就能够求解。因为以前用的匹配算法不能保证没有误匹配(其实是存在误匹配的),本文将采用RANSAC方法来估计两幅图像之间的仿射变换关系。若是有足够多的图像特征匹配符合某一个特定的仿射变换,则咱们认为当前匹配满意,反之,咱们进行下一次估计。spa
5.1 RANSAC算法code
RANSAC(RandomSample Consensus),即随机采样一致算法,准确来讲是一种从一组包含噪声的观测数据中经过迭代的方式估计出数据所知足的某个数学模型的参数的算法。由Fischler和Bolles于1981年提出,是目前普遍使用的一种剔除误匹配点的方法。orm
5.2 仿射变换blog
仿射变换(Affine Transform)是一种仿射平面到自身的变换,它可以保持点的共线性(Parallelism,即保持二维图形之间相对位置关系不变,平行还是平行,相交直线的交角不变)和直线的平行性(Straightness,即变换后圆弧仍是圆弧,直线仍是直线)。仿射变换是配准中最经常使用的一类转换模型,在几何学中有专门的仿射几何分支,并将仿射变换被当作一个平行的投影链。图片
仿射变换可用以个三乘三的矩阵表示,最后一行为(0,0,1)。该变换矩阵将原坐标(x,y)变为(x`,y`)。ip
变换矩阵为:get
咱们在空间几何信息检验中,认为若是两幅图像描述的是同一个物体或场景,因为图片大小,位置和角度的不一样,两幅图像中相应的兴趣点的位置信息应该知足某一个仿射变换关系。所以,咱们以两幅图像之间的特征匹配做为数据来估计仿射变换矩阵,若是能找到一个足够多特征匹配都服从的仿射变换,则认为当前匹配让人满意。
5.3 RANSAC仿射变换空间检验
空间检验就是经过RANSAC算法,根据图像之间的特征匹配信息,估计出一个仿射变换模型。
咱们用下式来表示仿射变换矩阵
其中m1,m2,m3,m4体现尺度和旋转特性,tx是x方向上的平移,ty是y方向上的平移。
则一对匹配点的坐标能够写成
或者写成
其中,(x,y)是变换前,(u,v)是变换后的坐标。
为了解求仿射变换参数,对上式作一下变形:
可写成A*x=b,则模型参数x的值
要解六个参数,至少须要三对特征匹配,所以RANSAC随机采样每次须要三对数据来估计仿射变换矩阵。
介绍完相关概念和理论,下面是RANSAC空间几何信息检验的流程:
1. 数据准备:找到两幅图像(I1和I2)之间的匹配点对和坐标信息。
2. 模型估计:假设有n>3对的匹配点对,随机选取3对,根据公式解求仿射变换模型参数m1,m2,m3,m4,tx,ty。
3. 模型评估:对图像I1中全部的已匹配的点(x,y)作上述仿射变换,获得一系列变换后的坐标(u`,v`)。将这些获得的坐标和I2中对应的匹配点(u,v)求欧氏距离,即仿射变换的估计偏差E。并用I2中相应特征点的尺度信息作归一化,这样每个特征匹配能够求出一个归一化的估计偏差,最终获得一个估计偏差向量。
4. 根据估计偏差向量肯定一个偏差阈值T(该怎么肯定阈值?),估计偏差向量中低于T的对应的特征匹配为Inliers。
5. 若是Inliers数目大于目前最大的Inliers数目,则当作找到了当前最好的放射变换,保存此变换(我看到网上说要对其作局部优化,将全部知足当前最好的仿射变换的Inliers匹配点对,从新作母性估计和模型评估并保存仿射变换信息。通常说来,通过局部优化的新放射变换一般会有更多Inliers,是什么意思啊?)
6. 重复2到6步骤,最终获得的仿射变换认为是I1和I2之间最好的放射变换模型。
这里记录下作的流程:
(1)推导六参数计算公式,编写仿射变换六参数类(因为以前没有检查数据,数据中有几组重复的,致使一直报“尝试除以零”这个错误);
代码以下:
/* * 求解仿射变换模型参数的类 * @ 刘硕编制 */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ImageMatching { class ParameterHelper { public int[] X_Cor { get; set; } public int[] Y_Cor { get; set; } public int[] U_Cor { get; set; } public int[] V_Cor { get; set; } //仿射变换模型六参数 public double m1 { get { return ((U_Cor[1] - U_Cor[0]) - m2 * (Y_Cor[1] - Y_Cor[0])) / (X_Cor[1] - X_Cor[0]); } } public double m2 { get { return ((U_Cor[1] - U_Cor[0])*(X_Cor[2] - X_Cor[0]) - (U_Cor[2] - U_Cor[0])*(X_Cor[1] - X_Cor[0])) / ((Y_Cor[1] - Y_Cor[0])*(X_Cor[2] - X_Cor[0]) - (Y_Cor[2]- Y_Cor[0])*(X_Cor[1] - X_Cor[0])); } } public double m3 { get { return ((V_Cor[1] - V_Cor[0]) - m4 * (Y_Cor[1] - Y_Cor[0])) / (X_Cor[1] - X_Cor[0]); } } public double m4 { get { return ((V_Cor[1] - V_Cor[0]) * (X_Cor[2] - X_Cor[0]) - (V_Cor[2] - V_Cor[0]) * (X_Cor[1] - X_Cor[0])) / ((Y_Cor[1] - Y_Cor[0]) * (X_Cor[2] - X_Cor[0]) - (Y_Cor[2] - Y_Cor[0]) * (X_Cor[1] - X_Cor[0])); } } public double tx { get { return U_Cor[0] - m1 * X_Cor[0] - m2 * Y_Cor[0]; } } public double ty { get { return V_Cor[0] - m3 * X_Cor[0] - m4 * Y_Cor[0]; } } } }(2 )对全部匹配点计算组合数,按RANSAC随机采样每次须要三对数据来估计仿射变换矩阵,则共有(C n 3 *C n 3)种组合状况,计算量至关大。
(3)求解完仿射变换模型六参数后,则要进行模型评估。即计算归一化偏差,获得归一化偏差向量。
(4)肯定阈值,计算Inliers数。这里参照论文,阈值取全部归一化偏差的均值(按说应该取自适应阈值,奈何不懂啊)。
(5)比较全部组合的Inliers数,获得最优仿射变换,并保存。
(6)输出仿射变换六参数及匹配后坐标
欢迎留言拍砖!