全景图拼接
概念
全景图像拼接顾名思义就是将多张存在重叠部分的图像拼成一幅全景图像。换一种理解方式(个人理解):两幅图像之间可以通过特征匹配得到对应点,将这些对应点坐标重合而保留两张图像其他的部分,就可以得到两幅图像的拼接结果,当然前提是这两张图像有匹配的点。以这种方式循环,通过两两拼接的方式最终拼接成一幅全景图。
原理
(1)基于SIFT的特征点的提取与匹配
利用Sift提取图像的局部特征,在尺度空间寻找极值点,并提取出其位置、尺度、方向信息。
具体步骤:
①、生成高斯差分金字塔(DOG金字塔),尺度空间构建
②、 空间极值点检测(关键点的初步查探)
③、稳定关键点的精确定位
④、稳定关键点方向信息分配
⑤、关键点描述
⑥、特征点匹配
(2)图像配准
图像配准是一种确定待拼接图像间的重叠区域以及重叠位置的技术,它是整个图像拼接的核心。本节采用的是基于特征点的图像配准方法,即通过匹配点对构建图像序列之间的变换矩阵,从而完成全景图像的拼接。
变换矩阵H求解是图像配准的核心,其求解的算法流程如下。
①、检测每幅图像中特征点。
②、计算特征点之间的匹配。
③、计算图像间变换矩阵的初始值。
④、迭代精炼H变换矩阵。
⑤、引导匹配。用估计的H去定义对极线附近的搜索区域,进一步确定特征点的对应。
⑥、重复迭代④和⑤直到对应点的数目稳定为止。
设图像序列之间的变换为投影变换
可用4组最佳匹配计算出H矩阵的8 个自由度参数hi=( i=0,1,…,7),并以此作为初始值。
为了提高图像配准的精度,采用RANSAC算法对图像变换矩阵进行求解与精炼,达到了较好的图像拼接效果。RANSAC算法的思想简单而巧妙:首先随机地选择两个点,这两个点确定了一条直线,并且称在这条直线的一定范围内的点为这条直线的支撑。这样的随机选择重复数次,然后,具有最大支撑集的直线被确认为是样本点集的拟合。在拟合的误差距离范围内的点被认为是内点,它们构成一致集,反之则为外点。根据算法描述,可以很快判断,如果只有少量外点,那么随机选取的包含外点的初始点集确定的直线不会获得很大的支撑,值得注意的是,过大比例的外点将导致RANSAC算法失败。在直线拟合的例子中,由点集确定直线至少需要两个点;而对于透视变换,这样的最小集合需要有4个点。
(3)图像融合
因为相机和光照强度的差异,会造成一幅图像内部,以及图像之间亮度的不均匀,拼接后的图像会出现明暗交替,这样给观察造成极大的不便。 亮度与颜色均衡处理,通常的处理方式是通过相机的光照模型,校正一幅图像内部的光照不均匀性,然后通过相邻两幅图像重叠区域之间的关系,建立相邻两幅图像之间直方图映射表,通过映射表对两幅图像做整体的映射变换,最终达到整体的亮度和颜色的一致性。
实现
代码
①、
from pylab import *
from numpy import *
from PIL import Image
# If you have PCV installed, these imports should work
from PCV.geometry import homography, warp
from PCV.localdescriptors import sift
"""
This is the panorama example from section 3.3.
"""
# set paths to data folder
featname = ['F:/python/pic/' + 'a' + str(i + 1) + '.sift' for i in range(5)]
imname = ['F:/python/pic/' + 'a' + str(i + 1) + '.jpg' for i in range(5)]
# extract features and match
l = {
}
d = {
}
for i in range(5):
sift.process_image(imname[i], featname[i])
l[i], d[i] = sift.read_features_from_file(featname[i])
matches = {
}
for i in range(4):
matches[i] = sift.match(d[i + 1], d[i])
# visualize the matches (Figure 3-11 in the book)
for i in range(4):
im1 = array(Image.open