1. 拼接原理
(1)检测并提取图像的特征和关键点 (2)匹配两个图像之间的描述符 (3)使用RANSAC算法使用我们匹配的特征向量估计单应矩阵 (4)拼接图像
2. SIFT
(1)(2)是运用SIFT局部描述算子检测图像中的关键点和特征,SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、些微视角改变的容忍度也相当高,所以用来检测要拼接图像的特征及关键点就很有优势。
3. RANSAC算法
RANSAC是一种迭代算法,用来从观测数据中估算出数学模型的参数,此基础上便可以分离内群与离群数据。简单来说就是一般来讲观测的数据里经常会出现很多噪音,比如说像SIFT匹配有时就会因为不同地方有类似的图案导致匹配错误。而RANSAC就是通过反复取样,也就是从整个观测数据中随机抽一些数据估算模型参数之后看和所有数据误差有多大,然后取误差最小视为最好以及分离内群与离群数据。RANSAC可以鲁棒的估计模型参数。 步骤如下: (1)随机采样K个点 (2)针对该K个点拟合模型 (3)计算其它点到该拟合模型的距离,小于一定阈值当做内点,统计内点个数 (4)重复M次,选择内点数最多的模型 (5)利用所有的内点重新估计模型(可选)
4. 单应性变换
单应性变换可简单理解为用来描述物体在世界坐标系和像素坐标系之间的位置映射关系,对应的变换矩阵称为单应性矩阵。单应性变换是将一个平面内的点映射到另一个平面内的二维投影变换。本质上,单应性变换H可以按照下方的方程映射到二维的点:
5. 代码实现
from pylab import *
from numpy import *
from PIL import Image
from PCV.geometry import homography, warp
from PCV.localdescriptors import sift
featname = ['D:\study\计算机视觉\code\code3\image' + str(i + 1) + '.sift' for i in range(3)]
imname = ['D:\study\计算机视觉\code\code3\image' + str(i + 1) + '.jpg' for i in range(3)]
l = {}
d = {}
for i in range(3):
sift.process_image(imname[i], featname[i])
l[i], d[i] = sift.read_features_from_file(featname[i])
matches = {}
for i in range(2):
matches[i] = sift.match(d[i + 1], d[i])
for i in range(2):
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)
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]
fp, tp = convert_points(0)
H_01 = homography.H_from_ransac(fp, tp, model)[0]
delta = 500
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)
figure()
imshow(array(im_02, "uint8"))
axis('off')
show()
结果:
6. 问题解决
No module named 'matplotlib.delaunay’问题解决见博客 解决方法
|