图像全景拼接

图像全景拼接

1、全景拼接简介

在此前了解了SIFT的特征点的提取与匹配,并且在SIFT的基础上,采用RANSAC算法对图像变换矩阵进行求解与精炼,删除错配。全景拼接需要在此基础上完成。

2、全景拼接步骤

1.在连续图像对间使用sift特征寻找匹配对应点对
2.进行可视化匹配,匹配两幅图像之间的特征
3.将匹配转换成齐次坐标点的函数,估计单应性矩阵
4.通过估计出图像间的单应性矩阵,将所有的图像扭曲到一个公共的图像平面上

要实现两张图片的简单拼接,其实只需找出两张图片中相似的点 (至少四个,因为 homography 矩阵的计算需要至少四个点), 计算一张图片可以变换到另一张图片的变换矩阵 (homography 单应性矩阵)拟合成一个单应性矩阵。对每个对应点对使用该单应性矩阵,然后返回相应的平方距离之和。用这个矩阵把那张图片变换后放到另一张图片相应的位置 ,从而实现全景拼接

3、实验内容及分析

3.1、实验要求

  1. 针对固定点位拍摄多张图片,以中间图片为中心,实现图像的拼接融合
  2. 针对同一场景(需选取视差变化大的场景,也就是有近景目标)更换拍摄位置
  3. 对结果进行分析说明

3.2、实验代码

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 = ['C:/Users/Administrator/Desktop/pythonhomework/pingjie4/'+str(i+1)+'.sift' for i in range(5)] 
imname = ['C:/Users/Administrator/Desktop/pythonhomework/pingjie4/'+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(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)


# function to convert the matches to hom. points
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([fp[1],fp[0],fp[2]])
    
    return fp,tp


# estimate the homographies
model = homography.RansacModel() 

fp,tp = convert_points(1)
H_12 = homography.H_from_ransac(fp,tp,model)[0] #im 1 to 2 

fp,tp = convert_points(0)
H_01 = homography.H_from_ransac(fp,tp,model)[0] #im 0 to 1 

tp,fp = convert_points(2) #NB: reverse order
H_32 = homography.H_from_ransac(fp,tp,model)[0] #im 3 to 2 

tp,fp = convert_points(3) #NB: reverse order
H_43 = homography.H_from_ransac(fp,tp,model)[0] #im 4 to 3    


# warp the images
delta = 1200 # for padding and translation

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')
savefig("example.png",dpi=300)
show()

3.3、实验结果及分析

3.3.1、固定位置拍摄图片

图片集1

图像全景拼接_第1张图片

sift匹配结果

图像全景拼接_第2张图片
图像全景拼接_第3张图片
图像全景拼接_第4张图片
图像全景拼接_第5张图片
起初没有注意代码逻辑需要从右往左编写图片序号,导致最后拼接结果出现问题,
错误的结果:

拼接结果

发现问题后,改变图片顺序,按照拍摄从右往左的顺序进行编号,正确的结果:

分析

图片拼接效果不理想,如果以建筑物,或者树木为参照物,在照片交接处有很明显的明暗差,但是拼接的位置基本正确。如果以天台的护栏为参照物,可以看到图片已经扭曲的很厉害了。我觉得主要原因是拍摄地点位于天台,拍摄的时候有充足的阳光,并且从左侧往右侧照射。可以看到最右侧的一张图,建筑物的照射很明显,但是左侧的光照就相对较少。导致画面有很明显的明暗差。图片拼接后出现扭曲是因为APAP算法是对每个小格做单应性变换,从单个小格看是没有特征的,所以拼接起来会出现扭曲的现象。
图像全景拼接_第6张图片
图像全景拼接_第7张图片

图片集2

图像全景拼接_第8张图片

sift匹配结果

图像全景拼接_第9张图片
图像全景拼接_第10张图片
图像全景拼接_第11张图片
图像全景拼接_第12张图片

拼接结果

图像全景拼接_第13张图片

分析

因为图片集1出现了明暗差明显的问题,拍摄图片集2我选择在房间内拍摄,拍摄位置固定在左侧的窗户边,让光线充分的照射整个房间。可以看到最后得出来的拼接效果相对图片集1好了很多,还有瑕疵的地方就是相对于窗户最深处,书架书桌的位置光线与衣柜相比还是相对较暗。仍然存在图片扭曲
图像全景拼接_第14张图片
图像全景拼接_第15张图片

3.3.2、移动位置拍摄图片(有近景目标)

图片集3

图像全景拼接_第16张图片

sift匹配结果

图像全景拼接_第17张图片
图像全景拼接_第18张图片
图像全景拼接_第19张图片
图像全景拼接_第20张图片

拼接结果

分析

图片是围绕着面前两盆植株进行拍摄的,可以看到每张图片,植株与后面的建筑物的相对位置是不断变化的。在不同角度能观测到同一个特征点,但是不同角度的图片进行重叠的时候,显然是不能吻合的。

3.4、运行过程中出现的问题

问题1

在这里插入图片描述

解决方法

1、进入warp.py中可以看到导入的错误包
2、将 import matplotlib.delaunay as md 改成 from scipy.spatial import Delaunay
在这里插入图片描述
3、将函数里把triangulate_points(x,y)里面的代码替换成
tri = Delaunay(np.c_[x,y]).simplices
在这里插入图片描述

4、总结

1、由于Apap将图像切割成无数多个小方块,对每个小方块进行单应性矩阵变换,显然图片像素越高,所需的运行时间就越久。因此可以对图片进行等比例缩放,缩短运行时间。
2、因为APAP算法是对每个小格做单应性变换,从单个小格看是没有特征的,所以拼接起来会出现扭曲的现象。
3、在图片拍摄地点的选取上,可以选择背对光源的位置进行拍摄,减少明暗差,拼接效果会更好。
4、图片拍摄的位置需要固定,若变更拍摄位置,在图片重叠的时候会严重扭曲图像。

你可能感兴趣的:(图像全景拼接)