[数字图像处理] SIFT实现弯曲全景图像拼接
背景介绍
现在的全景图像拼接一般是涉及两张或多张左右平移的图像的拼接,例如两张左右视角的楼宇的照片的拼接,而本文主要简单描述如何用Python和OpenCV实现多张特殊角度的图片自动拼接,首先展示一下最终的拼接效果。
基本原理
要实现两张图片的简单拼接,需要找出两张图片中相似的点 (至少四个,因为homography矩阵的计算需要至少四个点),计算一张图片可以变换到另一张图片的变换矩阵(homography单应性矩阵),用这个矩阵把那张图片变换后放到另一张图片相应的位置(就是相当于把两张图片中定好的四个相似的点給重合在一起)。如此,就可以实现简单的全景拼接。因为拼合之后图片会重叠在一起,所以需要重新计算图片重叠部分的像素值,否则结果会出现分割线等不和谐的效果。
总结起来是两个步骤:
1. 找两张图片中相似的点,计算变换矩阵
2. 变换一张图片放到另一张图片合适的位置,并计算重叠区域新的像素值 (这里就是图片融合所需要采取的策略)
具体实现
寻找相似点
相似点越多或者相似点对应的位置越准确,所得的结果就越好,但是人的肉眼所找的位置总是有误差的,而且找出很多的点也不是一件容易的事。相似点寻找也称为特征点匹配,这里就用了SIFT算法,OpenCV提供SIFT算法的接口,直接调用即可。如下是两张测试图片的原图和找出相似点后的图片。
其中蓝色的点是SIFT特征检测算子找出的特征点,而绿色的线表示的是在所有找出的特征点中所筛选出的对应匹配点。因为算法找出的匹配特征点并不一定是百分百正确的。然后就可以根据这些筛选出的相似点计算变换矩阵,当然OpenCV也提供了相应的接口方便计算。
图片拼接
计算出变换矩阵后,接下来就是第二步,用计算出的变换矩阵对其中一张图做变换,然后把变换的图片与另一张图片重叠在一起,并重新计算重叠区域新的像素值。对于计算重叠区域的像素值,其实可以有多种方法去实现一个好的融合效果,这里就用最简单粗暴的但效果也不错的方式。直白来说就是实现一个图像的线性渐变,对于重叠的区域,靠近左边的部分,让左边图像内容显示的多一些,靠近右边的部分,让右边图像的内容显示的多一些。用公式表示就是,假设 alpha 表示像素点横坐标到左右重叠区域边界横坐标的距离,新的像素值就为 newpixel = 左图像素值 × (1 - alpha) + 右图像素值 × alpha 。这样就可以实现一个简单的融合效果,如果想实现更复杂或更好的效果,可以去搜索和尝试一下 multi-band 融合,这里就不过多赘述了。
最后附上实现的结果,可供参考,可以看出除了光照不均匀的情况没有拟合的很好,两张图的拼接效果还是很好的。
附上代码连接: 代码