图像的拼接—-RANSAC算法

图像的拼接—-RANSAC算法一、全景拼接的原理1.RANSAC算法介绍RANSAC算法的基本假设是样本中包含正确数据(inliers,可以被模型描述的数据),也包含异常数据(outliers,偏离正常范围很远、无法适应数学模

大家好,又见面了,我是你们的朋友全栈君。

一、全景拼接的原理

1.RANSAC算法介绍
       RANSAC算法的基本假设是样本中包含正确数据(inliers,可以被模型描述的数据),也包含异常数据(outliers,偏离正常范围很远、无法适应数学模型的数据),即数据集中含有噪声。这些异常数据可能是由于错误的测量、错误的假设、错误的计算等产生的。同时RANSAC也假设,给定一组正确的数据,存在可以计算出符合这些数据的模型参数的方法。

2.使用RANSAC算法来求解单应性矩阵
        在进行图像拼接时,我们首先要解决的是找到图像之间的匹配的对应点。通常我们采用SIFT算法来实现特征点的自动匹配,SIFT算法的具体内容参照我的上一篇博客 。SIFT是具有很强稳健性的描述子,比起图像块相关的Harris角点,它能产生更少的错误的匹配,但仍然还是存在错误的对应点。所以需要用RANSAC算法,对SIFT算法产生的128维特征描述符进行剔除误匹配点。

        由直线的知识点可知,两点可以确定一条直线,所以可以随机的在数据点集中选择两点,从而确定一条直线。然后通过设置给定的阈值,计算在直线两旁的符合阈值范围的点,统计点的个数inliers。inliers最多的点集所在的直线,就是我们要选取的最佳直线。

        <span role="heading" aria-level="2">图像的拼接----RANSAC算法

       RANSAC算法就是在一原理的基础上,进行的改进,从而根据阈值,剔除错误的匹配点。首先,从已求得的匹配点对中抽取几对匹配点,计算变换矩阵。然后对所有匹配点,计算映射误差。接着根据误差阈值,确定inliers。最后针对最大inliers集合,重新计算单应矩阵 H。

 

3.基本思想描述:
①考虑一个最小抽样集的势为n的模型(n为初始化模型参数所需的最小样本数)和一个样本集P,集合P的样本数#(P)>n,从P中随机抽取包含n个样本的P的子集S初始化模型M;
②余集SC=P\S中与模型M的误差小于某一设定阈值t的样本集以及S构成S*。S*认为是内点集,它们构成S的一致集(Consensus Set);
③若#(S*)≥N,认为得到正确的模型参数,并利用集S*(内点inliers)采用最小二乘等方法重新计算新的模型M*;重新随机抽取新的S,重复以上过程。
④在完成一定的抽样次数后,若未找到一致集则算法失败,否则选取抽样后得到的最大一致集判断内外点,算法结束。

 4.图像拼接

使用RANSAC算法估计出图像间的单应性矩阵,将所有的图像扭曲到一个公共的图像平面上。通常,这里的公共平面为中心图像平面。一种方法是创建一个很大的图像,比如将图像中全部填充0,使其和中心图像平行,然后将所有的图像扭曲到上面。由于我们所有的图像是由照相机水平旋转拍摄的,因此我们可以使用一个较简单的步骤:将中心图像左边或者右边的区域填充为0,以便为扭曲的图像腾出空间。
二、实验

1.源代码

复制代码

 

复制代码

 


# -*- coding: utf-8 -*-
from pylab import *
from PIL import Image
from PCV.geometry import homography, warp
from PCV.localdescriptors import sift

# set paths to data folder
featname = ['C:/Users/LE/PycharmProjects/untitled/hh/' + str(i + 1) + '.sift' for i in range(4)]
imname = ['C:/Users/LE/PycharmProjects/untitled/hh/' + str(i + 1) + '.jpg' for i in range(4)]

# extract features and match
l = {}
d = {}
for i in range(4):
sift.process_image(imname[i], featname[i])
l[i], d[i] = sift.read_features_from_file(featname[i])

matches = {}
for i in range(3):#2
matches[i] = sift.match(d[i + 1], d[i])

# visualize the matches (Figure 3-11 in the book)
for i in range(3):#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 = 1000 # 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')
show()

 



 

复制代码

 

复制代码
 2.室外固定点位拍摄
数据集
<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 特征匹配

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 <span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 图像拼接

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 

 

3.室内固定点位拍摄
数据集
<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 特征匹配

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 

 图像拼接

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

4.视差变化大拍摄

数据集

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

特征匹配

<span role="heading" aria-level="2">图像的拼接----RANSAC算法<span role="heading" aria-level="2">图像的拼接----RANSAC算法<span role="heading" aria-level="2">图像的拼接----RANSAC算法

图像拼接

 <span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 5.同一地点不同方位拍摄 

 数据集

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

特征匹配

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

图片拼接

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 三、实验结果分析

通过四种不同场景的测试,可以看出:

室外固定点位拍摄的场景因为检测到的特征点较多提高了匹配度, 虽然总体的拼接图像在视觉上有点扭曲,但大致上都拼接出来了。

室内固定点位拍摄的场景,拼接效果比较理想,但由于图像曝光度的不同,导致在图像的边界上存在边缘效应,这也是该算法需要改进的地方。

室外同一地点不同角度拍摄场景,拼接效果最不理想,这是由于,虽然算法在特征匹配时匹配度很高,但是在进行拼接时,算法不会帮我们旋转图片的角度达到很好的拼接效果。

室外视察变化大拍摄的场景,按理来说应该检索到的特征点很多,但拼接结果不是很理想,这是由于我拍摄时没有尽可能的水平移动所导致,并且我的拍摄背景很相似,建筑物比较对称,所以也提醒大家拍摄测试图像要注意:为了拼接出效果比较好的图像,在保证有相同匹配点的情况下,拍摄图像的间隔尽可能大一些。且一定要站在同一点,水平移动手机进行拍摄,就像拍摄全景图那样。若人拍摄的位置发生移动的话,算法可能就会因为找不到正确的点对而报错,且最好不要拍摄那种对称的建筑物,且两边的的特征点长的几乎一样的。这样会使算法的匹配出现失误。

图片像素越高会导致代码运行较慢甚至报错。

四、实验中遇到的错误

1.代码运行时出现

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 解决方法:这是由于图片像素没有设置一致,将所有图片像素设置相同得以解决,同时像素不能太大会降低运行速度,也不能过小,这样提取的特征点不够准确。

2.在解决问题1.后又遇到

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 解决方法:这是因为拍摄的图片没有尽可能的水平位移,并且选取的场景尽量不要对称。

3.解决完问题1和问题2后我又遇到了如下问题

<span role="heading" aria-level="2">图像的拼接----RANSAC算法

 

 在百度,询问同学尝试多种方法后,此问题还是没有解决,可能是与拍摄图片本身有关,所以重新拍摄,以后找到解决方法再更新吧。

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155159.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Linux中查看进程状态信息

    Linux中查看进程状态信息Linux中查看进程状态信息一、常用命令总结ps-l列出与本次登录有关的进程信息;ps-aux查询内存中进程信息;ps-aux|grep***查询***进程的详细信息;top查看内存…

    2022年6月21日
    46
  • 如何使用ccs软件创建工程

    这里简叙如何使用ccs软件创建工程的具体步骤,正文如下:1、打开ccs软件,单击菜单栏中的“Project”选项,在弹出的下拉菜单中选择“NewCCSProject”,如下图所示:  2、在“Projectname”中输入自定义的工程名称,在“Family”中选择所需DSP的系列,在“Variant”的目录下选择所需的DSP的型号,最后在“Connection”目录下选择仿真…

    2022年4月8日
    408
  • TinEye Reverse Search Engine_tidb和mysql

    TinEye Reverse Search Engine_tidb和mysqlCUSTOMER表CREATETABLE`CUSTOMER`(`C_CUSTKEY`intNOTNULL,`C_NAME`varcharNOTNULL,`C_ADDRESS`varcharNOTNULL,`C_NATIONKEY`intNOTNULL,`C_PHONE`varcharNOTNULL,`C_ACCTBAL`decimal(12,2)NOT…

    2022年9月17日
    0
  • 利用键盘钩子捕捉linux键盘动作,利用键盘钩子捕获Windows键盘动作[通俗易懂]

    利用键盘钩子捕捉linux键盘动作,利用键盘钩子捕获Windows键盘动作[通俗易懂]下载本文示例代码引言  在科研生产中对研制、调试操作的记录是非常有必要而且是有很重要价值的。通过对记录信息的分析,可以在事故发生后准确的分析出事故的起因、操作是否存在失误等许多重要线索。通常需要记录的信息是多种多样的,如环境温度记录、软件运行记录、文件访问记录等等。这里将以键盘信息记录为例来讲述类似的实验信息自动记录的一般实现方法。  由于需要记录当前系统下所有应用程序的键盘录入记录,因此必须采取…

    2022年5月2日
    45
  • SaaS管理软件_软件saas

    SaaS管理软件_软件saas山寨SaaS今天又有一个人问我SaaS了,而且显然看了不少资料,也总结与思索了许多。但他与我交流后,我觉得有些话我也要总结总结,我对SaaS的一些观点和想法也清晰了不少,所以记了下来。大家都把SaaS定位在中小企业的身上。这个观点我也认同。因为我遇到的客户恰恰层次比较清晰:1进货卖货当渠道的经销商。本身自己不生产不设计,只是他从厂家进货,然后自己卖了,中间打个价差而已。他们主要的业务就…

    2022年9月23日
    0
  • python怎么调用api接口_偶尔的注解

    python怎么调用api接口_偶尔的注解swagger3的使用Swagger2(基于openApi3)已经在17年停止维护了,取而代之的是sagger3(基于openApi3),而国内几乎没有sagger3使用的文档,百度搜出来的都是swagger2的使用,这篇文章将介绍如何在java中使用openApi3(swagger3)。相关介绍OpenAPIOpenApi是业界真正的api文档标准,其是由Swagg…

    2022年10月26日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号