360度视频序列全景图拼接系统的设计与实现( 三 )


4.2程序架构
本系统分为用户交互端和视频转换服务端两部分 。
用户交互端负责接收用户请求 , 向视频转换服务端提交任务 , 并提供对全景图的管理功能 , 采用php、html5实现
视频转换服务端接受用户端提交的任务请求并管理任务队列 , 完成视频文件到全景图的转换工作 , 采用c++语言实现 , 基于opencv库 。
系统架构图
用户提交视频后 , 交互端先向服务端申请任务唯一标识 , 在获得标识后完成视频上传工作 , 向服务端提交任务请求 。 服务端在接收到新任务请求后 , 先将请求放就请求队列 。 由任务控制器从队列中取出任务 , 并启动视频转换程序 , 完成转换工作 , 最后将任务结果返馈给交互端 。
系统时序图
4.3视频转换程序设计
视频转换程序是本系统最核心部分 , 负责完成视频序列到全景图的转换任务 。
转换任务分为视频抽帧、帧匹配与拼接、全景图生成三部分工作 。
1. 视频抽帧
视频转全景图的基本思想就是对视频中的帧进行拼合 , 然而视频中帧数量巨大 , 相邻帧之间重复度大 , 一个时长60秒帧率30fps的视频包含1800个帧 , 如果对视频中全部帧进行处理 , 将耗费相当长的时间 , 这样做不仅效率低下 , 而且完全没有必要 。
在本系统中 , 规定输入的视频以匀速旋转一周的方式录制 , 在进行视频转换时 , 只需要抽取部分帧便可完成拼接工作 。
设置抽取帧数为N , 根据视频总帧数算出帧距间隔INTVAL , 在理想情况下 , 从第一帧开始 , 每隔INTVAL抽取一帧与前帧拼合 , 直至视频结束 。
但实际情况下 , 视频录制的效果可能并不理想 , 等间隔抽取的帧未必是最适合的帧 , 因此每抽取一帧时 , 需要对该帧的画面质量以及与前帧的匹配效果进行评估 , 如果当前帧不能达到要求 , 则需要在间隔范围内逐帧回溯寻找更合适的帧 。
2.帧匹配与拼接
每抽取一帧时 , 将已拼合图A与当前帧B进行匹配 。
首先利用sift算法分别提取两张A、B的特征点 , 然后利用距离比值法筛选匹配点 。 再利用RANSAC算法对特征点进行分析 , 计算出最佳匹配的变换矩阵H , 利用H对帧B做投影变换 , 获得B在A中四个顶点的坐标 。
根据变换后的坐标等参数评估当前帧是否符合要求 , 如符合则继续进行拼接 , 否则放弃当前帧 。
在进行拼接时 , 首先调整B的亮度与A匹配 , 然后根据变换坐标将B投射到A上 , 重合部分使用加权平均法进行融合 。
3. 全景图生成
在对抽取的帧依次进行拼接后 , 会得到一幅初始全景图片 , 对初始全景图进行处理后 , 将得到最终的全景图像 。
首先 , 要对初始全景图进行首尾对齐 。
初始全景图首部和尾部会出现重复区域 , 因此需要对起始部分和和结尾部分再进行一次匹配 , 根据得到的变换坐标找到重复区域边界 , 然后对初始全景图进行裁剪 , 将重复部分去除 。
其次 , 要去除初始全景图中的空白区域 。
在拼接过程中 , 由于对帧进行了投影变换 , 原来矩形图像会出变形变 , 在拼接图像的顶部和底部都会出现空白区域 。 为了去除这些空白区域 , 在每一次拼接完成时 , 都要记录空白区域的范围 , 并通过比较得到空白区域的最大边界值 , 最后在生成全景图时 , 根据最大边界值裁去空白区域 。

推荐阅读