合成全景图中计算机视觉技术的知识和原理

或许很多朋友会好奇其中的神秘,比如说为什么不同角度拍摄的图片拼接的时候可以自动对齐(略准确来讲也就是如何处理图片之间的仿射畸变和透视失 真);如何能自动找到图片之间可以粘连的部分并且准确无误地拼接在一起;如何平衡图片之间光线色调的差异等等。其实每一步的背后或多或少都有比较复杂却又 相当精妙的技术和算法,所以这次尝试用比较直观的方式给大家介绍一下每一步的工作原理,逆转对前沿科技“虽不明但觉厉”的看法。

那么先描述一下整个流程:

---图片之间---
1. 特征点匹配:找到素材图片中共有的图像部分。
2. 图片匹配:连接匹配的特征点,估算图像间几何方面的变换。

---全局优化和无缝衔接---
3. 全景图矫直:矫正拍摄图片时相机的相对3D旋转,主要原因是拍摄图片时相机很可能并不在同一水平线上,并且存在不同程度的倾斜,略过这一步可能导致全景图变成波浪形状。
4. 图像均衡补偿:全局平衡所有图片的光照和色调。
5. 图像频段融合:步骤4之后仍然会存在图像之间衔接边缘、晕影效果(图像的外围部分的亮度或饱和度比中心区域低)、视差效果(因为相机透镜移动导致)。

----------------(一)特征点匹配----------------

合成全景图的第一步是提取并且匹配所有素材图片的局部特征点。

1. 什么是特征点?

普遍来讲,一张图片所包含的特征点通常就是周围含有较大信息量的点,而仅通过这些富有特征的局部,基本就可以推测出整张图片。比如说物体的棱角、夜景闪耀的星星,或是图片里的图案和花纹。


图中框内即为判断富有特征的部分。


际上人在识别某个东西或是图案的时候也是通过观察这个物体具有哪种特征,然后与自己的经历和记忆所匹配。举例来说,去超市看到一个水果,假设我们观察到这
个水果是绿色(颜色特征),球形(形状特征),有黑色纹路(图案特征)。于是我们可以通过经验判断出这是个西瓜。当然人还会通过各种其他特征来增强对物体
的判断力,只是整个从收到信息到做出判断的过程行云流水,甚至自己都察觉不到。这就是生物视觉的精妙之处,只可惜距离破解生物视觉系统目前看来似乎仍是遥
不可及,所以在神经网络破解并模拟生物大脑的运作之前就先由计算机视觉来承担这个重担了。

稍稍有些跑题,那么继续之前的问题:提取何种特征?并且如何提取特征?


前面所说,一幅图片具有形形色色各种特征,简单的可以是颜色、形状或图案,复杂的比如说可以是图案的自相似性(是否存在类似重复性图案)或是整个场景里其
他的物体(好比说在超市的水果架上我们可以更能确信西瓜就是西瓜,而水果架这个背景即为特征)。实际上提取这些特征在计算机视觉领域里也占有相当重要的位
置,毕竟好的特征选择是整个识别系统可以成功运转的大前提。

[理论部分]

在合成全景图的流程里运用的是“点匹配”,也就是匹配局部图片信息。因为局部图片能提取的特征有限,比如说形状特征在这种情况就不适宜,所以一般采用通过整个局部的图案来判断是否符合作为特征的条件。其中运用最普遍的为SIFT特征(Scale-invariant feature transform),即尺度不变特征转换
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。此算法由 David Lowe
在1999年所发表,在急速发展的计算机视觉领域内至今仍然被普遍认为是最好的(即State of the art)特征侦测与描述算法。

提取SIFT特征分为两步:侦测描述(形成特征向量)。

单来讲,侦测就是扫描图片所有的尺度下的所有位置(尺度可以理解为局部缩放)。而判断一个点作为特征点合不合格,需要计算在这个尺度下的高斯差
(DoG,Difference of Gaussians)的局部极值(Local
Extrema)。如第一张图所示,每一个尺度(Scale)下对局部影像进行不同尺度的高斯模糊(局部影像与高斯滤波器的卷积)取差值。局部极值计算方
式如第二张图所示,将测试像素的DoG的数值与其26个邻接像素比较取其最大最小极值,也就是测试像素的“特征度” 。

即便找到了特征点,单纯匹配特征点周围的局部影像是行不通的。首先SIFT特征本身最大的优点就是“位置、尺度、旋转不变量",也就是说在一定范围内旋转或是拉远拉近相机,可以检测出相同的特征点位置(Repeatability)以及提取出相同的特征向量(Scale & Rotation Invariant),
所以不同角度条件拍摄的图片才可以通过SIFT特征匹配。而像素数值是不具备这些特点的。再者局部影像的像素信息量大导致匹配效率低下。假设这个局部大小
设为16*16像素大小,每一个像素值对应RGB
3个数值,那么每个特征点就对应一个786维的向量(也就是每个点要用786个数表示),考虑到尺度与旋转不变量这个向量又需要乘上十几倍甚至几十倍以覆
盖所有的变化,假设一个图片如果包含上千个特征点,而数据库包含上千张图片,那么在匹配时庞大的计算量无疑是对CPU的一场灾难。

为了保证提取出来的特征向量具有“旋转不变量
的特性,首先要做的是在每个特征点找到一个“方向”,而这个方向和局部图像的特性应当是一致的,也就是说理想状态下如果旋转这个局部图片,那么重新提取这
个"方向"也和之前相比旋转相同角度。SIFT里选择这个角度的方式是在高斯模糊之后的局部图片里计算每一个像素点的"角度"与"大小",之后进行投票选
出所有像素最多的那个角度作为主方向。下图为计算这个角度和大小的公式,看似很长实际上只是计算横竖相邻像素之间的差值和(m)和角度(θ)。

于是局部图像产生的差值和角度可以通过这种方式形成特征向量(或称为关键点描述子 - Keypoint Descriptor)。


成这个向量的方式是"量化"这些角度(比如说把360度平均分成8等分),
然后根据位置累计起来。上图表示的是一个8x8的局部采样计算出的2x2的特征矩阵,实际上一般使用的是16x16局部采样形成4x4特征矩阵。所以如果
把这个矩阵拉成向量,也就是包含8*4*4 = 128个元素。

形成特征向量之后下一个问题就是如何匹配了。
最基本的方式可以称作“最邻近搜索”(Nearest
Neighbour),实际上也就是找在128维空间上直线距离最近的的特征向量,这个求直线距离的方式和2维无异,最近的特征向量也就被认为是互相匹
配。原作者使用的方式是增加了k-d tree算法来高效率地完成高维度上的最邻近搜索。

[理论部分结束]

----------------(二)图片匹配----------------


下来的目标就是找到所有匹配(也就是重叠)的图片部分,接连所有图片之后就可以形成一个基本的全景图了。因为每张图片有可能和其他每张图片有重叠部分,所
以匹配全部图片需要差不多匹配图片个数的平方次。不过实际上每两张图片之间只需要那么几个相对精准匹配的点就可以估算出这两张图像里的几何关系。

最普遍的方式是用RANSAC(RANdom SAmple Consensus, 随机抽样一致),在这里的用途就是排除掉不符合大部分几何变换的匹配。之后利用这些匹配的点来"估算单应矩阵" (Homography Estimation),也就是把其中一张通过个关联性和另一张匹配的方法,在之后会详细介绍。

上图即为用RANSAC找出符合几何约束的特征点之后,通过单应矩阵来对齐两张图片的内容。

【RANSAC】

[理论部分]

首先介绍一下RANSAC
原理。RANSAC是一种迭代算法(Iteration
Method),用来从观测数据中估算出数学模型的参数,此基础上便可以分离内群(Inliers)与离群(Outliers)数据。简单来说就是一般来
讲观测的数据里经常会出现很多噪音,比如说像SIFT匹配有时就会因为不同地方有类似的图案导致匹配错误。而RANSAC就是通过反复取样,也就是从整个
观测数据中机抽一些数据估算模型参数之后和所有数据误差有多大,然后取误差最小视为最好以及分离内群与离群数据。


图這裡用一個簡單的例子來說明,在一組數據點中找到一條最適合的線。
假設,此有一組集合包含了內群以及離群,其中內群為可以被擬合到線段上的點,而離群則是無法被擬合的點。如果我們用簡單的最小平方法來找此線,我們將無法
得到一條適合於內群的線,因為最小平方法會受離群影響而影響其結果。而RANSAC,可以只由內群來計算出模型,而且概率還夠高。
然而,RANSAC無法保證結果一定最好,所以必須小心選擇參數,使其能有足夠的概率。

下图是一个简单的例子,用RANSAC来找出符合内群的直线的参数(可以看做是找y=ax+b里的a和b),以及内群数据本身。

之所以RANSAC能在有大量噪音情况仍然准确,主要原因是随机取样时只取一部分可以避免估算结果被离群数据影响。流程为以下:(摘自维基)

需要补充这个流程的是:判断数据是否符合模型的阈值以及重复多少次步骤是要自行定义的,并且决定了整个流程相对的准确度与运算时间。

总结一下的话,RANSAC算法的输入为:

1. 观测数据 (包括内群与外群的数据)
2. 符合部分观测数据的模型 (与内群相符的模型)
3. 最少符合模型的内群数量
4. 判断数据是否符合模型的阈值 (数据与模型之间的误差容忍度)
5. 迭代运算次数 (抽取多少次随机内群)

输出为:
1. 最符合数据的模型参数 (如果内群数量小于输入第三条则判断为数据不存在此模型)
2. 内群集 (符合模型的数据)

优点:能在包含大量外群的数据中准确地找到模型参数,并且参数不受到外群影响。

点:计算参数时没有一个最大运算时间的顶限,也就是说在迭代次数被限制的情况下,得出来的参数结果有可能并不是最优的,甚至可能不符合真实内群。所以设定
RANSAC参数的时候要根据应用考虑“准确度与效率”哪一个更重要,以此决定做多少次迭代运算。设定与模型的最大误差阈值也是要自己调,因应用而异。还
有一点就是RANSAC只能估算一个模型。

[理论部分结束]

RANSAC应用于点匹配的效果,基于前图:

匹配时不符合绝大多数几何变换的判断为匹配错误并排除。

【Homography Estimation】

找到两张图里正确的匹配之后就可以利用这些点来估算两张图之间的几何变换关系。简单来说就是:假设固定其中一张图在桌子上,如何摆放,旋转,拉伸另一张图使其与第一张重合。

【待补充】
假设有一对匹配点, , 他们之间的单应矩阵便是下图公式中的H。

【待补充】

时间: 2024-10-10 09:54:31

合成全景图中计算机视觉技术的知识和原理的相关文章

高可用集群技术理论基础知识

目录 1.引言 2.高可用架构框架 3.资源的约束与隔离 4.高可用模型 5.配置高可用架构的前提 1.引言 一言以蔽之,高可用集群技术是为了解决业务因服务器宕机而中断业务的一种技术,它能保障业务7*24*365不间断. 在linux开源的世界里,常见的开源解决方案有如下: keepalived(vrrp+script) heartbeat corosync+pacemaker 要想用好这些开源软件,不得不先来了解一下一个高可用集群中的一些基础知识. 2.高可用架构框架 高可用架构一般可分为以下

3月9日高项作业(信息系统集成专业技术专业知识)

系统集成项目管理工程师教程 第三章 信息系统集成专业技术专业知识 3月9日作业 1.信息系统集成有哪些特点. 信息系统集成有以下几个显著特点. (1)信息系统集成要以满足用户需求为根本出发点. (2)不只是设备选择和供应,更重要,它是具有高技术含 量的工程过程,要面向用需求提供全面解决方案,其核心是软件. (3)系统集成的最终交付物是一个完整的系统而不是一个分立的产品. (4)系统集成包括技术.管理和商务等各项工作,是一项综合性的系统工程.技术是系统集成工作的核心,管理和商务是系统集成项目成功实

多线程编程技术基础知识

GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=414 多线程编程技术基础知识 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同

转:LoadRunner中参数化技术详解

LoadRunner中参数化技术详解 LoadRunner在录制脚本的时候,只是忠实的记录了所有从客户端发送到服务器的数据,而在进行性能测试的时候,为了更接近真实的模拟现实应用,对于某些信息需要每次提交不同的数据,或者使用多个不同的值进行循环输入.这时,在LoadRunner中就可以进行参数化设置,以使用多个不同的值提交应用请求. [参数化]使用指定数据源中的值来替换脚本录制生成的语句中的参数. [好处] l  减少脚本的大小 l  提供使用不同的值执行脚本的能力,更加真实的模拟现实应用. [参

沟通是项目管理知识体系中的九大知识领域之一

项目管理要素有:范围.时间.成本.质量.人力.风险.采购.沟通.在项目管理中,沟通是一个软指标,其所起的作用不好量化,沟通对项目的影响往往也是隐形的.项目沟通管理是现代项目管理知识体系中的九大知识领域之一,项目沟通管理在成功所必须的因素-人.想法和信息之间提供了一个关键性连接. 沟通对项目的成功,尤其是IT项目的成功非常重要.本文就围绕沟通的重要意义.项目干系人.沟通对效率的影响.沟通的关键要素这几方面展开一些探讨,最后结合高职外语教学.综合测评平台项目,对沟通在小组软件开发过程中的应用进行案例

Java中String的基础知识

Java中String的基础知识 ==与equal的区别 基本数据类型,指的是java中的八种基本数据结构(byte,short,char,int,long,float,double,boolean),一般的比较是使用的 ==,比较的是他们的值. 复合数据类型(类) ==比较的是两个对象的引用,可以理解为在内存中的地址,除非是同一个new出来的对象,他们的 ==为true,否则,都为false. equal是object中的方法.object中的实现如下,内部还是使用==实现,也就是说,如果一个

Oracle中IMU技术和redo private strand技术

oracle030 oracle030 Oracle中IMU技术和redo private strand技术 3.图解Oracle IMU机制 select * from v$sysstat where name like '%IMU%'; STATISTIC#, NAME,       CLASS, VALUE, STAT_ID 312     IMU commits     128     393     1914489094 313     IMU Flushes     128    

面向对象中一个疏漏的知识

关于访问修饰符一个重要的问题. private是限制该对象无法在外部对象中访问,但是如果在自己的类中创建自己的对象或者使用自己的对象,那么还是可以使用被private修饰的成员 class A{ public class StringValue { public static void main(String[] args){ A a = new A(); a.i = 1; //这里无法访问,报错! } } class A{ private int i; public boolean equal

Java代码中常见技术债务处理之Exception

写在前面 异常处理是代码中常见的处理,本文根据SonarQube在异常方面的规则和常见检查结果,选取说明了常见异常处理中的技术债务,提倡技术债务最少的编码方式. Exception handlers should preserve the original exceptions Either log or rethrow this exception. When handling a caught exception, the original exception's message and s