Python图像处理之图像拼接


Posted in Python onApril 28, 2021

一、前言

图像拼接技术就是将数张有重叠部分的图像(可能是不同时间、不同视角或者不同传感器获得的)拼成一幅无缝的全景图或高分辨率图像的技术。

二、特征点匹配

特征点具有局部差异性

动机:特征点具有局部差异性

Python图像处理之图像拼接

图像梯度

Python图像处理之图像拼接

Harris矩阵

Python图像处理之图像拼接
Python图像处理之图像拼接

以每个点为中心取一个窗口,窗口大小为55或者77,如果这个点具有差异性,往周围任意方向移动,周围的环境变化都是会比较大的,如果满足这个特性,我们就认为这个特征点具有明显的局部差异性。在工事中,I表示像素,如果是 彩色图像就是RGB,灰色图像就是灰度。(u,v)表示方向。然后对上式进行一阶泰勒展开。
Harris矩阵H的特征值分析:

Python图像处理之图像拼接

矩阵特征值反应了两个垂直方向的变化情况,一个事变化最快的方向,一个事变化最慢的方向

Python图像处理之图像拼接

Python图像处理之图像拼接

兴趣点位于光滑区域,不是特征点

Python图像处理之图像拼接

兴趣点位于边缘区域

Python图像处理之图像拼接

兴趣点位于角点区域

所以检测特征的任务转化为计算Harris矩阵,判断特征值大小。

在实际操作中,很少通过计算特征值来判断,因为计算特征值计算量比较大,取而代之的是Harris角点准则。

三、匹配错误的特征点干扰

在进行图像匹配过程中,如果图像的噪声太大,就会使得特征点的匹配发生了偏差,匹配到了错误的点,这种不好的匹配效果,会对后面的图像拼接产生很大的影响,如下图

Python图像处理之图像拼接

四、消除干扰

为了进一步提升匹配精度,可以采用随机样本一致性(RANSAC)方法。

因为我们是使用一幅图像(一个平面物体),我们可以将它定义为刚性的,可以在pattern image和query image的特征点之间找到单应性变换(homography transformation )。使用cv::findHomography找到这个单应性变换,使用RANSAC找到最佳单应性矩阵。(由于这个函数使用的特征点同时包含正确和错误匹配点,因此计算的单应性矩阵依赖于二次投影的准确性)

五、RANSAC进行图像匹配

RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。

RANSAC的基本假设是:

(1)数据由“局内点”组成,例如:数据的分布可以用一些模型参数来解释;
(2)“局外点”是不能适应该模型的数据;
(3)除此之外的数据属于噪声。

局外点产生的原因有:噪声的极值;错误的测量方法;对数据的错误假设。

RANSAC也做了以下假设:给定一组(通常很小的)局内点,存在一个可以估计模型参数的过程;而该模型能够解释或者适用于局内点。

RANSAC原理

OpenCV中滤除误匹配对采用RANSAC算法寻找一个最佳单应性矩阵H,矩阵大小为3×3。RANSAC目的是找到最优的参数矩阵使得满足该矩阵的数据点个数最多,通常令h3=1来归一化矩阵。由于单应性矩阵有8个未知参数,至少需要8个线性方程求解,对应到点位置信息上,一组点对可以列出两个方程,则至少包含4组匹配点对。

Python图像处理之图像拼接

其中(x,y)表示目标图像角点位置,(x',y')为场景图像角点位置,s为尺度参数。

RANSAC算法从匹配数据集中随机抽出4个样本并保证这4个样本之间不共线,计算出单应性矩阵,然后利用这个模型测试所有数据,并计算满足这个模型数据点的个数与投影误差(即代价函数),若此模型为最优模型,则对应的代价函数最小。

Python图像处理之图像拼接

RANSAC算法步骤:

1.随机从数据集中随机抽出4个样本数据 (此4个样本之间不能共线),计算出单应矩阵H,记为模型M;

2.计算数据集中所有数据与模型M的投影误差,若误差小于阈值,加入内点集 I ;

3.如果当前内点集 I 元素个数大于最优内点集 I_best , 则更新 I_best = I,同时更新迭代次数k ;

4.如果迭代次数大于k,则退出 ; 否则迭代次数加1,并重复上述步骤;

注:迭代次数k在不大于最大迭代次数的情况下,是在不断更新而不是固定的;
其中,p为置信度,一般取0.995;w为"内点"的比例 ; m为计算模型所需要的最少样本数=4;

Python图像处理之图像拼接
Python图像处理之图像拼接

使用RANSAC图片匹配

from numpy import *
from matplotlib.pyplot import *
from PIL import Image
import warp
import homography
from PCV.localdescriptors import sift

featname = ['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])

# visualize the matches (Figure 3-11 in the book)
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 = 100  # 用于填充和平移 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()

进行匹配的图片

Python图像处理之图像拼接
Python图像处理之图像拼接

匹配后的图片

Python图像处理之图像拼接
Python图像处理之图像拼接
Python图像处理之图像拼接

分析:

本次的拼接效果比较好,原因是因为我在同一时刻差不多角度拍摄的照片,噪声比较小,之前一组图片拍摄的噪声太大,导致最后出现不了结果。
由图片这部分可得,在不同时刻下拍摄照片导致天空颜色不同,在拼接的时候也会有明显的分割线。

Python图像处理之图像拼接

在实验过程中,刚开始使用了一组照片,但运行不出结果,后来经过查询找到原因是因为图片匹配度太低,没办法进行匹配,后来重新拍摄了一组图片最终才完成。

Python图像处理之图像拼接

到此这篇关于Python图像处理之图像拼接的文章就介绍到这了,更多相关Python图像拼接内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
用python代码做configure文件
Jul 20 Python
Python面向对象编程之继承与多态详解
Jan 16 Python
浅谈Python在pycharm中的调试(debug)
Nov 29 Python
Python字符串的全排列算法实例详解
Jan 07 Python
Python爬虫之UserAgent的使用实例
Feb 21 Python
Django 项目重命名的实现步骤解析
Aug 14 Python
wxPython实现带颜色的进度条
Nov 19 Python
Python实现i人事自动打卡的示例代码
Jan 09 Python
pytorch torchvision.ImageFolder的用法介绍
Feb 20 Python
Django debug为True时,css加载失败的解决方案
Apr 24 Python
python爬取某网站原图作为壁纸
Jun 02 Python
Python图片验证码降噪和8邻域降噪
Aug 30 Python
4种非常实用的python内置数据结构
Apr 28 #Python
Python基础详解之描述符
Apr 28 #Python
详解Python 3.10 中的新功能和变化
Apr 28 #Python
Python基础之数据结构详解
Apr 28 #Python
Python基础详解之邮件处理
python实现黄金分割法的示例代码
Apr 28 #Python
Python 流媒体播放器的实现(基于VLC)
You might like
浅析php工厂模式
2014/11/25 PHP
php表单处理操作
2017/11/16 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
PHP sdk实现在线打包代码示例
2020/12/09 PHP
JQuery UI皮肤定制
2009/07/27 Javascript
JavaScript设计模式之抽象工厂模式介绍
2014/12/28 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
JavaScript中用getDate()方法返回指定日期的教程
2015/06/09 Javascript
JS操作COOKIE实现备忘记录的方法
2016/04/01 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
2016/12/08 Javascript
jQuery插件echarts实现的循环生成图效果示例【附demo源码下载】
2017/03/04 Javascript
判断滚动条滑到底部触发事件(实例讲解)
2017/11/15 Javascript
Vue-router的使用和出现空白页,路由对象属性详解
2018/09/03 Javascript
axios使用拦截器统一处理所有的http请求的方法
2018/11/02 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
2020/04/15 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
详解Python中最难理解的点-装饰器
2017/04/03 Python
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
Linux下python与C++使用dlib实现人脸检测
2018/06/29 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
python自动发邮件总结及实例说明【推荐】
2019/05/31 Python
python excel转换csv代码实例
2019/08/26 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
pycharm 配置svn的图文教程(手把手教你)
2021/01/15 Python
迎元旦广播稿
2014/02/22 职场文书
寒假家长评语大全
2014/04/16 职场文书
县政府领导班子四风问题对照检查材料思想汇报
2014/09/26 职场文书
教师节感谢信
2015/01/22 职场文书
三下乡个人总结
2015/03/04 职场文书
2015年小学体育工作总结
2015/05/22 职场文书
《怀念母亲》教学反思
2016/02/19 职场文书
Python 中的Sympy详细使用
2021/08/07 Python
Java虚拟机内存结构及编码实战分享
2022/04/07 Java/Android