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简单日志处理类分享
Feb 14 Python
详解Python程序与服务器连接的WSGI接口
Apr 29 Python
python通过文件头判断文件类型
Oct 30 Python
python3 shelve模块的详解
Jul 08 Python
Pycharm技巧之代码跳转该如何回退
Jul 16 Python
Python模拟三级菜单效果
Sep 11 Python
python正则表达式面试题解答
Apr 28 Python
对Python中创建进程的两种方式以及进程池详解
Jan 14 Python
基于python全局设置id 自动化测试元素定位过程解析
Sep 04 Python
PyCharm最新激活码(2020/10/27全网最新)
Oct 27 Python
python实现简单的学生管理系统
Feb 22 Python
Python超简单容易上手的画图工具库推荐
May 10 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
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
PHP生成静态HTML页面最简单方法示例
2015/04/09 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
Yii框架ACF(accessController)简单权限控制操作示例
2019/04/26 PHP
php使用curl模拟多线程实现批处理功能示例
2019/07/25 PHP
JS提交并解析后台返回的XML的代码
2008/11/03 Javascript
js弹出框轻量级插件jquery.boxy使用介绍
2013/01/15 Javascript
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
2014/02/07 Javascript
js格式化时间和js格式化时间戳示例
2014/02/10 Javascript
JavaScript常用验证函数实例汇总
2014/11/25 Javascript
js设置和获取自定义属性的方法
2016/10/20 Javascript
jQuery使用ajax方法解析返回的json数据功能示例
2017/01/10 Javascript
详解vue slot插槽的使用方法
2017/06/13 Javascript
express默认日志组件morgan的方法
2018/04/05 Javascript
layui表格内容溢出的解决方法
2019/09/06 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
2019/09/20 Javascript
vue+element树组件 实现树懒加载的过程详解
2019/10/21 Javascript
node 版本切换的实现
2020/02/02 Javascript
微信小程序实现弹框效果
2020/05/26 Javascript
[04:52]第二届DOTA2亚洲邀请赛主赛事第一天比赛集锦:OG娜迦海妖放大配合谜团大中3人
2017/04/02 DOTA
[01:08:33]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python矩阵的转置和逆转实例
2018/12/12 Python
Python实现剪刀石头布小游戏(与电脑对战)
2019/12/31 Python
pytorch 图像预处理之减去均值,除以方差的实例
2020/01/02 Python
Pycharm Git 设置方法
2020/09/15 Python
Python QT组件库qtwidgets的使用
2020/11/02 Python
德国知名健康零食网上商店:Seeberger
2017/07/27 全球购物
阿里巴巴英国:Alibaba英国
2019/12/11 全球购物
群胜软件Java笔试题
2012/09/29 面试题
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
热爱祖国的演讲稿
2014/05/04 职场文书
无传销社区工作方案
2014/05/13 职场文书
个人安全生产承诺书
2014/05/22 职场文书
2015年小学教科研工作总结
2015/07/20 职场文书
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫