计算机视觉 创建全景图

创建全景图

全景拼接

图像拼接就是将两幅或多幅具有重叠区域的图像,合并成一张大图。

拼接的具体步骤为:
1、针对某个场景拍摄多张、序列图像
2、计算第二张图像与第一张图像之间的变换关系
3、将第二张图像叠加到第一张图像的坐标系中
4、变换后的融合、合成
5、在多图场景,重复上述过程

RANSAC

RANSAC(RANdom SAmple Consencus)是用来找到正确模型拟合带有噪声数据的迭代方法。给定一个模型,例如点集之间的单应性矩阵,RANSAC的基本思想是,数据中包含的正确的点和噪声点,合理的模型应该能够在描述正确数据点的同时屏蔽噪声点。RANSAC目的就是找到一个单应性矩阵H,使得能够满足这个单应性矩阵的特征点最多。

RANSAC代码

from array import array

from matplotlib.pyplot import *
from PIL import Image
from numpy.ma import vstack, dot

import warp
import homography
from PCV.localdescriptors import sift

featname = ['img/' + str(i + 1) + '.sift' for i in range(5)]
imname = ['img/' + str(i + 1) + '.jpg' for i in range(5)]
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()

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

# 扭曲图像
delta = 20  # 用于填充和平移 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()

一开始没有使用原图时,运行出现了以下错误
在这里插入图片描述

现在下列两组图片都已压缩到大小为8.54KB,但在运行时还是报错了另一种错误。
在这里插入图片描述
在这里插入图片描述

ValueError: did not meet fit acceptance criteria

于是改用另一组图片,并将每张图片压缩为14.8KB之后,就成功运行出了结果。
在这里插入图片描述
运行结果并不理想,且右边半张明显与左边脱节、重复,且黑框部分占了一半的空间。
在这里插入图片描述

尝试把delta值从100改为20之后,黑框部分减少,但左侧建筑的拼接明显对不上。
在这里插入图片描述
尝试将上述第二组图片的大小改为与这组相同的14.8KB后,成功运行出了结果。这组图片由于之前压缩过小,所以画质比价不清晰。总结,上述两种报错都是由于测试图片过大或者过小。
在这里插入图片描述

最后尝试用另一组跨度大一些的图片,也成功运行出结果,但建筑楼层的拼接还是不太理想。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
根据上述测试结果,发现图片出现断层的地方都存在拍摄时前后两张图片间的视角变化太大、或者是特征比较明显且复杂、光线不同。所以猜测这应该是造成断层的一部分原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值