计算机视觉——全景拼接原理

图像拼接的几何原理

                         

图像被投影到同一平面上,在拼接平面实现全景融合,简单来说,可以理解为2D拼接叠加

图像拼接整体流程

(一)根据给定图像/集,实现特征匹配

特征匹配用来计算图像之间的映射关系,得到每个匹配图像对之间的单应矩阵,结合上一步的映射模型,我们可以得到最终的图像变换序列,结合前面所提到的特征,选取sift特征描述子(关于sift描述,可以看之前的文章)

(二)通过匹配特征计算图像之间的变换结构

一幅图可以变化成另一幅图像处于相同坐标系的图像,有:

平移变换模型:只对图像进行相对于X轴和Y轴的整体平移。仿射变换模型(仿射变换模型共有6个自由度,只要三对对应变换点即可求出一个仿射变换模型。

仿射模型:具有平行保持性,也就是原来平行的直线经过变换后依旧是平行的)投影

变换模型:用于描述相机的平移,旋转,角度变换,变焦等一系列运动。通常使用齐次坐标。投影变换只具有直线保持性,原来是直线投影后一九是直线。

(三)利用图像变换结构,实现图像映射 、

在图像拼接中可以将图像投影到不同平面,如平面模型,柱状,球形等

平面模型:简单通用,进过图像配准后,使用变换模型直接将拼接图像映射到基准图形平面坐标系上。

柱面模型:先将平面图形映射到柱面上,完成拼接后再将结果映射回平面坐标系。

(四)针对叠加后的图像,采用APAP之类的算法对齐特征点

图像配准是将两张场景相关的图像进行映射,寻找其中的关系Apap流程:提取两张图片的sift特征点对两张图片的特征点进行匹配, 匹配后,仍有很多错误点, RANSAC的改进算法进行特征点对的筛选。筛选后的特征点基本能够一一对应。使用DLT算法,将剩下的特征点对进行透视变换矩阵的估计。因为得到的透视变换矩阵是基于全局特征点对进行的,即一个刚性的单应性矩阵完成配准。为提高配准的精度,Apap将图像切割成无数多个小方块,对每个小方块的变换矩阵逐一估计。非常依赖于特征点对。若图像高频信息较少,特征点对过少,配准将完全失效,并且对大尺度的图像进行配准,其效果也不是很好,一切都决定于特征点对的数量。

(五)通过图割方法,自动选取拼接缝

图是一个具有权值的有向结构,通常采用一些节点,一些有向连接线表示,这些节点是像素值,或其他特征点。寻找代价最小的分割,典型算法是最小割最大流算法。最大流几句诗将图内带权值看作带有流量值的管道,将最大量水从源点送到汇点。

(六) 根据multi-band bleing策略实现融合

融合目的在于拼缝消除, Multi-Band能够达到比较好的融合效果,但是效率低,采用Laplacian(拉普拉斯)金字塔,通过对相邻两层的高斯金字塔进行差分,将原图分解成不同尺度的子图,对每一个之图进行加权平均,得到每一层的融合结果,最后进行金字塔的反向重建,得到最终融合效果过程。

代码:

# ch3_panorama_test.py
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//lenovo/Downloads/pcv-book-code-master/ch03/data/a'.sift' for i in range(4)] 
imname = [''C:/Users//lenovo/Downloads/pcv-book-code-master/ch03/data/a'+str(i+1)+'.jpg' for i in range(4)]

# extract features and match
l = {}
d = {}
for i in range(4): 
    sift.process_image(imname[i],featname[i])
    l[i],d[i] = sift.read_features_from_file(featname[i])

matches = {}
for i in range(3):
    matches[i] = sift.match(d[i+1],d[i])

# visualize the matches (Figure 3-11 in the book)
for i in range(3):
    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([tp[1],tp[0],tp[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 
 

# warp the images
delta = 2000 # 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)



figure()
imshow(array(im_42, "uint8"))
axis('off')
savefig("example5.png",dpi=300)
show()
实现效果:

             

                                               错差较大的图片进行合成:

       

                                                       集美大学庄汉水楼

可以看出这三张图片空间错差极大,所以可想而知拼接出来的效果不尽人意。

 

那么接下来三张落差小的图片

 

拼接图:

 

 

                                            

室内图像:

 

      

 

 

合成图像:

           

                                                               (集美大学延奎图书馆内景)

mistake:

如果是   from PCV.geometry import warp, homography   报错

是因为PCV下面的warp.py里面的matplotlib.delaunay不再被使用了,所以把它换成一个相同功能的就可以:

 1:把import matplotlib.delaunay as md 换成from scipy.spatial import Delaunay

 2:warp.py里面的centers,edges,tri,neighbors = md.delaunay(x,y)换成tri= Delaunay(np.c_[x,y]).simplices就ok啦

还有就是图片要从右向左按顺序放,不能乱顺序。

                

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值