图像拼接
图像拼接是将同一场景的多个重叠图像拼接成较大的图像的一种方法
基本思想:图像拼接并非简单的将两张有共同区域的图像把相同的区域重合起来,由于两张图像拍摄的角度与位置不同,虽然有共同的区域,但拍摄时相机的内参与外参均不相同,所以简单的覆盖拼接是不合理的。因此,对于图像拼接需要以一张图像为基准对另外一张图像进行相应的变换(透视变换),然后将透视变换后的图像进行简单的平移后与基准图像的共同区域进行重合。
RANSAC算法
RANSAC是一种迭代算法,用来从观测数据中估算出数学模型的参数,此基础上便可以分离内群与离群数据。简单来说就是一般来讲观测的数据里经常会出现很多噪音,比如说像SIFT匹配有时就会因为不同地方有类似的图案导致匹配错误。而RANSAC就是通过反复取样,也就是从整个观测数据中随机抽一些数据估算模型参数之后看和所有数据误差有多大,然后取误差最小视为最好以及分离内群与离群数据。RANSAC可以鲁棒的估计模型参数。
单应性矩阵
单应性矩阵可以由两幅图像(或者平面)中对应点对计算出来。每个对应点可以写出两个方程,分别对应与x和y坐标。因此,计算单应性矩阵H至少需要4对匹配点,过程如下:
那么就可以每次从所有的匹配点中选出4对,计算单应性矩阵,然后选出内点个数最多的作为最终的结果。计算距离方法如下:
拼接图像
估计单应矩阵 H后,我们需要将两个图像拼接在一起。这里我们采用透视变换,输入想要扭曲的图像,单应矩阵( H ),还有输出图像的形状。我们通过获取两个图像的宽度之和然后使用第二个图像的高度确定输出图像的导出形状。透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。透视变换如下图:

实现
1.运行代码:
import os
import sys
import cv2
def imgstitcher(imgs): # 传入图像数据 列表[] 实现图像拼接
stitcher = cv2.Stitcher.create(cv2.Stitcher_PANORAMA)
_result, pano = stitcher.stitch(imgs)
if _result != cv2.Stitcher_OK:
print("不能拼接图片, error code = %d" % _result)
sys.exit(-1)
output = 'result' + '.png'
cv2.imwrite(output, pano)
print("拼接成功. %s 已保存!" % output)
if __name__ == "__main__":
# imgPath为图片所在的文件夹相对路径
imgPath = 'C:/img'
imgList = os.listdir(imgPath)
imgs = []
for imgName in imgList:
pathImg = os.path.join(imgPath, imgName)
img = cv2.imread(pathImg)
if img is None:
print("图片不能读取:" + imgName)
sys.exit(-1)
imgs.append(img)
imgstitcher(imgs) # 拼接
cv2.waitKey(0)
cv2.destroyAllWindows()
原始图片:
(1)
(2)
(3)
2.运行结果:
结果分析:
从上面的结果中看出来使用RANSAC图像拼接的效果比较理想,物体分割不明显,物体歪斜不是很严重,物体稍微有点变形,可能是因为输入图片有足够重合相同特征区域,且都在同一深度上,且图片的噪声点比较小。