计算机视觉--全景图像的拼接

全景拼接原理的介绍

全景视图是指在一个固定的观察点,能够提供水平方向上方位角360度,垂直方向上180度的自由浏览 (简化的全景只能提供水平方向360度的浏览)。目前市场中的全景摄像机主要分为两种:鱼眼全景摄像机和多镜头全景摄像机。鱼眼全景摄像机是由单传感器配套特殊的超广角鱼眼镜头,并依赖图像校正技术还原图像的鱼眼全景摄像机。鱼眼全景摄像机最终生成的全景图像即使经过校正也依然存在一定程度的失真和不自然。多镜头全景摄像机可以避免鱼眼镜头图像失真的缺点,但是或多或少也会存在融合边缘效果不真实、角度有偏差或分割融合后有"附加"感的缺撼。

步骤

图像获取通过相机取得图像。通常需要根据失真较大的鱼眼镜头和失真较小的窄视角镜头决定算法处理方式。单镜头和多镜头相机在算法处理上也会有一定差别。鱼眼图像矫正若相机镜头为鱼眼镜头,则图像需要进行特定的畸变展开处理。图片匹配根据素材图片中相互重叠的部分估算图片间匹配关系。主要匹配方式分两种:A.与特征无关的匹配方式。最常见的即为相关性匹配。B.根据特征进行匹配的方式。最常见的即为根据SIFT,SURF等素材图片中局部特征点,匹配相邻图片中的特征点,估算图像间投影变换矩阵。图像融合对拼接得到的全景图进行融合处理。全景图像投射将合成后的全景图投射至球面、柱面或立方体上并建立合适的视点,实现全方位的视图浏览。
全景图像拼接具体实现代码:
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 = [‘Univ’+str(i+1)+’.sift’ for i in range(5)]
imname = [‘Univ’+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([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

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 = 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)

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()

实验对三种不同场景进行对比:

  1. 室外景深落差小的远景。
    计算机视觉--全景图像的拼接_第1张图片

  2. 室内的近景。
    计算机视觉--全景图像的拼接_第2张图片
    最大流最小割的简单理解
    假设有两张图像A,B。A,B之间拼接之后存在着重影的现象。那我们把A,B重合的地方分别取出来为PartA,和PartB。把PartA的像素减去相应位置PartB的像素,得到差值作为一个矩阵,再将矩阵中的值和相邻的值相减作为连接点之间的权值。这样就知道当权值的地方说明这里两张图像有很大的不同,所以我们找到一条切割路径使权值之和最小。这样以这条路径作为图像的拼接点,就会使图像消除重影。

    实验总结
    1.拼接图像大小会影响的程序的速度,为了加快速度,所以不要传原图。
    2.代码中有个参数delta。这个参数是针对你拍摄图像时,你相对平移的距离的变量,当你拍摄近景时候,这个参数尽量该小,远景相反。

你可能感兴趣的:(计算机视觉--全景图像的拼接)