本文共 2804 字,大约阅读时间需要 9 分钟。
图像拼接就是将两幅或多幅具有重叠区域的图像,合并成一张大图。
拼接的具体步骤为:
1、针对某个场景拍摄多张、序列图像 2、计算第二张图像与第一张图像之间的变换关系 3、将第二张图像叠加到第一张图像的坐标系中 4、变换后的融合、合成 5、在多图场景,重复上述过程RANSAC(RANdom SAmple Consencus)是用来找到正确模型拟合带有噪声数据的迭代方法。给定一个模型,例如点集之间的单应性矩阵,RANSAC的基本思想是,数据中包含的正确的点和噪声点,合理的模型应该能够在描述正确数据点的同时屏蔽噪声点。RANSAC目的就是找到一个单应性矩阵H,使得能够满足这个单应性矩阵的特征点最多。
from array import arrayfrom matplotlib.pyplot import *from PIL import Imagefrom numpy.ma import vstack, dotimport warpimport homographyfrom PCV.localdescriptors import siftfeatname = ['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 2fp, tp = convert_points(0)H_01 = homography.H_from_ransac(fp, tp, model)[0] # im 0 to 1tp, fp = convert_points(2) # NB: reverse orderH_32 = homography.H_from_ransac(fp, tp, model)[0] # im 3 to 2tp, fp = convert_points(3) # NB: reverse orderH_43 = homography.H_from_ransac(fp, tp, model)[0] # im 4 to 3# 扭曲图像delta = 20 # 用于填充和平移 for padding and translationim1 = 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之后,黑框部分减少,但左侧建筑的拼接明显对不上。
最后尝试用另一组跨度大一些的图片,也成功运行出结果,但建筑楼层的拼接还是不太理想。
转载地址:http://nghkk.baihongyu.com/