计算机视觉——图像拼接

文章目录

    • 一、图像拼接原理
      • 1.1基本流程
    • 二、实现
      • 2.1代码实现基本步骤
      • 2.2代码
    • 三、实验结果与分析
      • 3.1固定位置多张图片拼接
        • 3.1.1失败的拼接
        • 3.1.4部分成功的拼接
        • 3.1.3相对成功的拼接
        • 3.1.4成功的拼接
      • 3.2景深场景下不同位置的图片
    • 四、总结

一、图像拼接原理

1.1基本流程

计算机视觉——图像拼接_第1张图片

  • 特征提取 Feature Extraction: 在所有输入图像中检测特征点
  • 图像配准 Image Registration: 主要指对参考图像和待拼接图像中的匹配信息进行提取,在提取出的信息中寻找最佳的匹配,完成图像间的对齐。
      对于匹配有多种方法:
       1.直接使用图像的像素值的算法,例如,correlation methods
       2.在频域处理的算法,例如,基于快速傅里叶变换(FFT-based)方法;
       3.低水平特征的算法low level features,通常用到边缘和角点,例如,Harris角点检测,SIFT特征匹配(原理见此博客计算机视觉——SIFT特征匹配)
       4.高水平特征的算法high-level features,通常用到图像物体重叠部分,特征关系,例如,图论方法(Graph-theoretic methods)
  • RANSAC算法: 主要通过计算单应性矩阵剔除误匹配特征点(原理见此博客计算机视觉——SIFT特征匹配)
  • 图像变形 Warping: 需要将所有的图像扭曲到一个公共的图像平面上。通常,这里的公共平面为中心图像平面。一种方法是创建一个很大的图像,比如图像中全部填充0,使其和中心图像平行,然后将所有的图像扭曲到上面,由于我们所有的图像是由照相机水平旋转拍摄的,因此我们可以使用一个较简单的步骤:将中心图像左边或者右边的区域填充0,以便为扭曲的图像腾出空间。
  • 叠加后的图像,采用APAP之类的算法对齐特征点: Apap流程:提取两张图片的sift特征点对两张图片的特征点进行匹配, 匹配后,仍有很多错误点, RANSAC的改进算法进行特征点对的筛选。筛选后的特征点基本能够一一对应。使用DLT算法,将剩下的特征点对进行透视变换矩阵的估计。因为得到的透视变换矩阵是基于全局特征点对进行的,即一个刚性的单应性矩阵完成配准。为提高配准的精度,Apap将图像切割成无数多个小方块,对每个小方块的变换矩阵逐一估计。非常依赖于特征点对。若图像高频信息较少,特征点对过少,配准将完全失效,并且对大尺度的图像进行配准,其效果也不是很好,一切都决定于特征点对的数量。
  • 选取拼接缝: 通过图割方法,采用最小割最大流算法。
  • 图像融合 Blending 在完成图像匹配以后,通过改变边界附近的图像灰度级,创建混合图像,让缝合自然过渡。可采用Laplacian(拉普拉斯)金字塔,通过对相邻两层的高斯金字塔进行差分,一层一层叠加,得到每一层的融合结果,最后进行金字塔的反向重建,得到最终融合效果过程。

二、实现

2.1代码实现基本步骤

  1. 给定的图像集
  2. 根据给定的图像集,利用SIFT特征匹配,实现图像之间的特征匹配;
  3. 用RANSAC算法估计单应性矩阵
  4. 扭曲图像,利用图像变换结构,实现图像映射
  5. 针对叠加后的图像,采用算法,对齐特征点
  6. 通过图割方法,自动选取拼接缝
  7. 对图像进行融合。

2.2代码

# -*- coding: utf-8 -*-
# RANSAC算法拼接3张图片
from pylab import *
from numpy import *
from PIL import Image
from PCV.geometry import homography, warp
from PCV.localdescriptors import sift

featname = ['F:/PycharmProjects/ComputerVision/0324/images2/images' + str(i + 1) + '.sift' for i in range(3)]
imname = ['F:/PycharmProjects/ComputerVision/0324/images2/images' + 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])

# visualize the matches (Figure 3-11 in the book)
# sift匹配可视化
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)


# 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

# warp the images
# 扭曲图像
delta = 500  # 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)

figure()
imshow(array(im_02, "uint8"))
axis('off')
savefig("ps.jpg", dpi=300)
show()

三、实验结果与分析

3.1固定位置多张图片拼接

3.1.1失败的拼接

结果:

SIFT特征匹配结果

计算机视觉——图像拼接_第2张图片

拼接结果

计算机视觉——图像拼接_第3张图片
分析:

  • 由拼接结果可看出,后两张图片,拼接效果极佳,不细看甚至看不出拼接的裂缝,没有产生物体线条的扭曲。在SIFT特征匹配结果中也可以看出同一较矮的建筑在两图匹配出的大量正确的特征点,因此而后图片经过扭曲,能根据匹配的特征点很好的叠合了两张图片对应特征点, 使得两张图中矮的建筑完美拼接,而两张图片拼接的缝隙在融合过程中,算法了通过改变边界附近的图像灰度级,使得拼接自然。
  • 前两张图片,并没有拼接上,并且第一张图片极度扭曲。由SIFT特征匹配结果可以看出,虽然经过RANSAC算法剔除了误匹配,但显然剔除效果并不好,两图中存在明显的误匹配特征点(图中可以看出有交叉的匹配线),正是由于存在特征点匹配错误,导致两图片内同一建筑按错误的匹配特征点(实际并不匹配)形成映射,当两图片扭曲后,也就无法叠合特征,从而不能实现图片拼接。

3.1.4部分成功的拼接

SIFT特征匹配结果

计算机视觉——图像拼接_第4张图片

拼接结果

计算机视觉——图像拼接_第5张图片
  这3张图片,右边部分实现了较好的拼接,而左边部分没有拼接上。分析原因可能是,3张图片拍摄角度区别不够大,图片扭曲后为填充画布大小,裁取了第一张图较大的面积,没能实现与第2张图拼接。

3.1.3相对成功的拼接

结果:

SIFT特征匹配结果

计算机视觉——图像拼接_第6张图片

拼接结果


分析:

  • 这3张图大部分物体实现了较好拼接(蓝色框部分),但也出现了部分拼接参差不齐现象(红色圈部分)。由SIFT特征检测结果可知,检测出大部分正确匹配特征点,这些特征点在图像配准中准确对齐,经图像扭曲后实现准确拼接上。
  • 一些边缘物并没有正确拼接上,可能的原因是,图片在拍摄过程中角度稍有旋转,在后两张图片的SIFT特征检测结果可以看出,主体建筑匹配线大部分是倾斜的,也说明两张图片角度有些变化。由于原图片本身角度有差异,后面的图像扭曲为实现拼接上主体对应的特征点,对图片也进行了一些旋转,所以导致边缘没有拼接上。另,边缘物体在SIFT特征检测后并未有匹配结果,所以后面的图片配准,没有配准这部分,自然也无法拼接。

3.1.4成功的拼接

结果:

SIFT特征匹配结果

计算机视觉——图像拼接_第7张图片

拼接结果

分析:
  由于自己拍摄的图片多次尝试都未能完全拼接3张图片,不禁怀疑是否是算法的问题。本例选取的图片来自python计算视觉编程书中的案例图片,结果显示经SIFT特征匹配,匹配出了大量对应特征点,图片映射后相邻两张图片能很好的叠合特征点,证明此算法实现多张图片拼接是可行的,这3张图片拍摄角度都较广,也印证了上面图片拼接部分不成功可能是由于拍摄的图片角度不够大。

3.2景深场景下不同位置的图片

结果:

SIFT特征匹配结果

拼接结果

图(1)(delta = 100):

计算机视觉——图像拼接_第8张图片
图(2)(delta = 100):
计算机视觉——图像拼接_第9张图片
图(3)(delta = 300):

图(4)(delta = 400):

分析:

  • 此有景深差异组图中,SIFT特征匹配主要检测出了近处的植物和较近的建筑和一部分远处的河岸(蓝色圈部分)
  • 图(1),图(2)仅部分拼接成功,且近景拼接较好,远景拼接较差。在尝试变化图片顺序,改变画布大小等方式后,拼接出效果较好的图(3),图(4);这里拼接失败的原因在于画布(delta参数) 过小,导致第三张图片与前一张拼接时,没有足够的扭曲空间。
  • 图(3),图(4)较好的拼接出了全景图,但远处景物有两处明显未拼接上(红圈处)。近处的植物和较近的建筑由SIFT特征匹配检测出匹配特征点,图像经变换结构后由匹配特征点形成映射,再经扭曲,成功拼接。 远处的景物由于拼接后图片由三维变为二维,丢失了位置信息,且SIFT特征匹配并没有检测出此处的匹配特征点,因此在图像叠加特征点过程中主要是准确叠加了近处景物的特征点,导致远处景物没有成功拼接。
  • 近处植物由于原本灰度值相近,融合后,拼接缝隙不明显;远一点的景物即使融合后改变了边界附近灰度级,但还是可以看出出明显的拼接缝隙。
  • 再扩大画布后,结果由图(3)变为图(4),得到的更广的全景图,拼接边界并未改变。

四、总结

  • 图片配准结果与SIFT特征匹配结果有关系,若匹配结果存在较多错配,则图片难以配准,导致最后无法拼接。
  • 多张图片拼接,图片拍摄角度大一些,才能显示比较好的效果。
  • 有景深差异的图像拼接,近景易检测出匹配特征点,远景难检测出匹配特征点,且拼接后没有景物的距离信息,因而图像拼接的结果是近景成功拼接,远景难以拼接。

你可能感兴趣的:(人工智能)