计算机视觉 图像映射和全景拼接

目录

一.图像映射:

1.图像映射基础:

1.1. 基础流程 :

1.2. 计算变换结构流程:

2. 2D 图像变换原理:

2.1. 图像滤波: 改变图像的像素点取值范围:

2.2. 图像变换: 改变图像的坐标取值范围:

2.3. 2D 图像变换类型:

二.全景拼接:

1.拼接原理:

2.RANSAC算法:

3.实验结果:

3.1.实验数据:

 3.2.实验代码:

3.3.实验结果:


一.图像映射:

1.图像映射基础:

        如何将两幅或多幅具有重叠区域的图像,合并成一张大图?
我们需要以下步骤:

1.1. 基础流程 :

① 针对某个场景拍摄多张 / 序列图像
② 计算第二张图像与第一张图像之间的变换关系
③ 将第二张图像叠加到第一张图像的坐标系中
④ 变换后的融合 / 合成
⑤ 在多图场景中,重复上述过程
计算机视觉 图像映射和全景拼接_第1张图片

 

在拼接的应用中,其实可以简化理解为 2D 图像的变换,叠加过程;

1.2. 计算变换结构流程:

提取特征点,生成描述符
特征匹配
计算变换结构

2. 2D 图像变换原理:

2.1. 图像滤波: 改变图像的像素点取值范围:

计算机视觉 图像映射和全景拼接_第2张图片
计算机视觉 图像映射和全景拼接_第3张图片

2.2. 图像变换: 改变图像的坐标取值范围:

计算机视觉 图像映射和全景拼接_第4张图片

 计算机视觉 图像映射和全景拼接_第5张图片

2.3. 2D 图像变换类型:

 计算机视觉 图像映射和全景拼接_第6张图片

 计算机视觉 图像映射和全景拼接_第7张图片

 计算机视觉 图像映射和全景拼接_第8张图片

二.全景拼接:

1.拼接原理:

相关流程:

        • 根据给定图像 / 集,实现特征匹配
        • 通过匹配特征计算图像之间的变换结构
        • 利用图像变换结构,实现图像映射
        • 针对叠加后的图像,采用 APAP 之类的算法,对齐特征点
        • 通过图割方法,自动选取拼接缝
        • 根据 multi-band blending 策略实现融合

        特征匹配过程是运用SIFT局部描述算子检测图像中的关键点和特征,SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、些微视角改变的容忍度也相当高;然后通过一系列图片变化后找到重叠的图片部分,连接所有图片之后就可以形成一个基本的全景图;最常用的方法是采用RANSAC,用此排除掉不符合大部分几何变换的匹配。

2.RANSAC算法:

        RANSAC 算法假设数据中包含正确数据和异常数据(或称为噪声)。正确数据记为内点(inliers),异常数据记为外点(outliers)。同时 RANSAC 也假设,给定一组正确的数据,存在可以计算出符合这些数据的模型参数的方法。该算法核心思想就是随机性和假设性,随机性是根据正确数据出现概率去随机选取抽样数据,根据大数定律,随机性模拟可以近似得到正确结果。假设性是假设选取出的抽样数据都是正确数据,然后用这些正确数据通过问题满足的模型,去计算其他点,然后对这次结果进行一个评分。

RANSAC 求解单应矩阵:
RANSAC loop:
1. 随机选择四对匹配特征
2. 根据 直接线性变换解法 DLT 计算单应矩阵 H (唯一解 )
3. 对所有匹配点,计算映射误差 ε= || p i ’, H p i ||
4. 根据误差阈值,确定 inliers (例如 3-5 像素)
5. 针对最大 inliers 集合,重新计算单应矩阵 H

3.实验结果:

3.1.实验数据:

计算机视觉 图像映射和全景拼接_第9张图片

 

 

 3.2.实验代码:

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
np.seterr(invalid='ignore')


# 设置数据文件夹的路径
featname = ['D:\\image inform\\picture\\' + str(i + 1) + '.sift' for i in range(5)]
imname = ['D:\\image inform\\picture\\' + str(i + 1) + '.jpg' for i in range(5)]

# 提取特征并匹配使用sift算法
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 = 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()

3.3.实验结果:

计算机视觉 图像映射和全景拼接_第10张图片

 计算机视觉 图像映射和全景拼接_第11张图片

 最终效果图:

计算机视觉 图像映射和全景拼接_第12张图片

 

 

你可能感兴趣的:(python)