目录
1.概念
图像全景拼接就是将多张图片(两两间存在一定的重叠部分,可以是不同时间、不同视角或者不同传感器获得的)拼成一幅无缝的全景图或高分辨率图像的技术。
2.基本原理
在图像拼接过程中,首先通过sift算法提取图像的特征点然后进行匹配,但是运用sift算法进行匹配的过程中会出现错误匹配的情况,所以我们采用RANSAC算法来提出一些错误匹配的特征点,RANSAC这个算法是随机采用部分特征匹配坐标计算得到一个透视矩阵(单应性矩阵),用这个透视矩阵把所有的匹配点都测试一遍,若匹配则得到该透视矩阵,否则再采用其他特征匹配坐标。所以该方法的作用就是可以把不正确的特征匹配结果剔除,获得正确的透视矩阵。
3.代码实现
# -*- coding: utf-8 -*-
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 = ['xin/' + str(i + 1) + '.sift' for i in range(5)]
imname = ['xin/' + 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])
for i in range(4):
im1 = array(Image.open(imname[i]))
im2 = array(Image.open(imname[i + 1]))
figure()
sift.plot_matches(im2, im1, l[i + 1], l[i], matches[i], show_below=True)
# 将匹配转换成齐次坐标点的函数
def convert_points(j):
ndx = matches[j].nonzero()[0]
fp = homography.make_homog(l[j + 1][ndx, :2].T)
ndx2 = [int(matches[j][i]) for i in ndx]
tp = homography.make_homog(l[j][ndx2, :2].T)
# switch x and y - TODO this should move elsewhere
fp = vstack([fp[1], fp[0], fp[2]])
tp = vstack([tp[1], tp[0], tp[2]])
return fp, tp
# 估计单应性矩阵
model = homography.RansacModel()
# H_from_ransac函数的返回结果为单应性矩阵和对应该单应性矩阵的正确点对
fp, tp = convert_points(1)
# im1 到 im2 的单应性矩阵
H_12 = homography.H_from_ransac(fp, tp, model)[0]
fp, tp = convert_points(0)
# im0 到 im1 的单应性矩阵
H_01 = homography.H_from_ransac(fp, tp, model)[0]
# 注意:点是反序的
tp, fp = convert_points(2)
# im3 到 im2 的单应性矩阵
H_32 = homography.H_from_ransac(fp, tp, model)[0]
# 注意:点是反序的
tp, fp = convert_points(3)
# im4 到 im3 的单应性矩阵
H_43 = homography.H_from_ransac(fp, tp, model)[0]
# 扭曲图像 用于填充和平移
delta = 200
im1 = array(Image.open(imname[1]), "uint8")
im2 = array(Image.open(imname[2]), "uint8")
im_12 = warp.panorama(H_12, im1, im2, delta, delta)
im1 = array(Image.open(imname[0]), "f")
im_02 = warp.panorama(dot(H_12, H_01), im1, im_12, delta, delta)
im1 = array(Image.open(imname[3]), "f")
im_32 = warp.panorama(H_32, im1, im_02, delta, delta)
im1 = array(Image.open(imname[4]), "f")
im_42 = warp.panorama(dot(H_32, H_43), im1, im_32, delta, 2 * delta)
figure()
imshow(array(im_42, "uint8"))
axis('off')
show()
4.实验结果与分析
4.1 固定点位拍摄多张图片实现图像的拼接融合
输入图像为两张
实验结果:
特征点匹配:
拼接图像:
输入图片为五张时
特征点匹配:
拼接图片:
结果分析:
当输入图片为两张时,图片拼接的效果比较好,两张图片在进行特征点匹配时,特征点比较多,重合部分比较大,所以图像融合效果会比较好。但是当进行五张图像进行拼接时,看以看到原图中的左边部分的图片消失了,而且拼接出来的图片有些扭曲,扭曲的原因可能是因为拍摄角度的问题。而左边部分的图片消失,是因为不同角度下,图片的差异比较大,导致左边的图片扭曲到右边图片时,必须舍弃掉一部分,否则很难达到完整的规则图形。两个结果来看,会发现都会有图片重影的现象,可以通过图割法进行消除。
4.2 视差变化大的场景进行图像拼接
特征点匹配:
拼接图象:
结果分析:
在视差变化大场景对三幅图像进行拼接时,拼接效果不是很好,图片有扭曲现象。在图片中可以看到,花盆时相对于比较近的,而花盆后方的建筑物相对比较远,进行拼接时,后方的建筑物拼接效果比较好,花盆比较差,出现了鬼影的现象。可能是远近以及拍摄角度导致的。
5.总结
在进行图像拼接时,拼接的效果会受到拍摄角度以及远近程度的影响,实验结果来看,远景的拼接效果比较好。图像的像素会影响程序运行速度,尽量将图片像素改小一点。