Python计算机视觉(三)—图像拼接

这篇具有很好参考价值的文章主要介绍了Python计算机视觉(三)—图像拼接。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 基本原理

    图像拼接是计算机视觉中的重要分支,它是将两幅以上的具有部分重叠的图像进行拼接从而得到较高分辨率或宽视角的图像。本文将结合python+opencv实现两幅图像的拼接。

    图像拼接一般步骤:

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

1.1 SIFT算法匹配特征

    SIFT特征包括兴趣点检测器和描述子,对于尺度、旋转和亮度都具有不变性。

    使用SIFT算法获得基准图像img1和源图像img2的特征,使用opencv中的FLANN匹配算法进行特征匹配,选取优质的匹配点,可视化匹配结果。

    代码:

# 图像拼接
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 读取待拼接图像
MIN = 10
img1 = cv.imread('jm1.jpg')
img2 = cv.imread('jm2.jpg')
# 统一图像大小
height1 = int(img1.shape[0])
width1 = int(img1.shape[1])
dim = (width1, height1)
img2 = cv.resize(img2, dim, interpolation=cv.INTER_AREA)

# 创建SIFT特征点检测
sift = cv.SIFT_create()

# 检测兴趣点并计算描述子
kp1, describe1 = sift.detectAndCompute(img1, None)
kp2, describe2 = sift.detectAndCompute(img2, None)

# 使用OpenCV中的FLANN匹配算法进行特征匹配,并返回最近邻和次近邻匹配的结果
FLANN_INDEX_KDTREE = 0
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
searchParams = dict(checks=50)
flann = cv.FlannBasedMatcher(indexParams,searchParams)
matches = flann.knnMatch(describe1, describe2, k=2)

# 储存特征匹配最好的优质匹配点对
'''基于距离阈值选择优质匹配点对,如果最近邻m的距离小于0.65倍的次近邻n的距离,
则认为这个匹配点对是优质的,将它存储在good列表中。'''
good = []
for m,n in matches:
    if m.distance < 0.65 * n.distance:
        good.append(m)

# 可视化特征匹配结果,并保存
pic3 = cv.drawMatches(img1=img1, keypoints1=kp1, img2=img2, keypoints2=kp2, matches1to2=good, outImg=None)
cv.imwrite(r'/Users/xionglulu/Downloads/project1/m11.jpg', pic3)

    结果:

python图像拼接,计算机视觉,opencv,人工智能
特征匹配图

    结果分析:SIFT算法对图像特征点的提取更全面,但在匹配时也存在错误,对于相似度过高的点匹配效果并不好。通过改变距离阈值大小,可以改变匹配点对数量,阈值越小,匹配数量越少,同时准确率也越高。

 文章来源地址https://www.toymoban.com/news/detail-550565.html

1.2 RANSAC算法

    RANSAC(Random Sample Consensus,随机抽样一致性)算法是一种用于估计模型参数的迭代算法,其主要目的是从包含噪声和异常值的数据集中估计出最优的模型参数。

    RANSAC算法的基本思想是随机选择一组数据点来拟合模型,然后使用该模型来计算所有数据点与模型的拟合误差。如果某个数据点与模型的误差小于一个阈值,则将其视为内点,否则视为外点。算法重复这个过程,直到找到满足一定置信度的最优模型。

    RANSAC算法的步骤如下:

1.从数据集中随机选择一组数据点,根据这些数据点拟合模型。

2.对于所有的数据点,计算其与模型的误差,并将误差小于一个阈值的数据点视为内点,否则视为外点。

3.如果内点的数量大于指定的阈值,则使用所有内点重新估计模型,并计算内点的误差。如果内点的数量小于指定的阈值,则返回步骤1。

4.如果当前模型的内点数量大于之前的模型,则将当前模型作为最优模型,并更新内点的阈值和置信度。

5.重复步骤1到4,直到达到指定的迭代次数或置信度。

    本文图像拼接采用RANSAC算法计算出特征点之间的单应性变换矩阵,每次随机选取4个特征点对,然后通过透视变换将img2映射到img1。

1.3 APAP算法

    在图像拼接融合的过程中,受客观因素的影响,拼接融合后的图像可能会存在“鬼影现象”以及图像间过度不连续等问题。为解决这一问题,可以采用APAP算法。

    APAP算法步骤如下:

1.SIFT得到两幅图像的匹配点对
2.通过RANSAC剔除外点,得到N对内点
3.利用DLT和SVD计算全局单应性
4.将目标图划分网格,取网格中心点,计算每个中心点和目标图上内点之间的欧式距离和权重
5.将权重放到DLT算法的A矩阵中,构建成新的W*A矩阵,重新SVD分解,自然就得到了当前网格的局部单应性矩阵
6.遍历每个网格,利用局部单应性矩阵映射到全景画布上,就得到了APAP变换后的目标图
7.最后就是进行拼接线的加权融合

1.4 最大流最小割方法找最佳拼接缝

    当两张图像拼接完成后,可能会出现情况:两张图像之间的过度不连续,也就是存在拼接缝隙,拼接线两侧的灰度变化较为明显。最大流最小割方法可以解决这个问题。

最大流
给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow)。

最小割
割是网络中定点的一个划分,它把网络中的所有顶点划分成两个顶点集合S和T,其中源点s∈S,汇点t∈T。记为CUT(S,T),满足条件的从S到T的最小割(Min cut)。

1.5 multi-band blending算法

    在找完拼接缝后,由于图像噪声、光照、曝光度、模型匹配误差等因素,直接进行图像合成会在图像重叠区域的拼接处出现比较明显的边痕迹。这些边痕迹需要使用图像融合算法来消除。其中一种方法为Multi-Band Blending。

    Multi-Band Blending的基本原理如下:

1.图像金字塔
首先,对于两张待融合的图像,需要将它们分别构建成图像金字塔。图像金字塔是一种分层存储图像的数据结构,它可以将图像分解为多个不同尺度的子图像,从而实现图像的分层处理。

2.拉普拉斯金字塔
在构建完图像金字塔后,需要对每个图像金字塔层进行拉普拉斯变换。拉普拉斯变换可以将每个图像金字塔层分解为一个高频分量和一个低频分量。高频分量包含图像的细节信息,低频分量包含图像的整体结构信息。

3.融合
在得到每个图像金字塔层的拉普拉斯变换后,可以对它们进行融合。Multi-Band Blending算法采用了加权平均的方法,即对于每个拉普拉斯金字塔层,将它们的高频分量进行加权平均,将它们的低频分量进行简单平均,从而得到最终的融合结果。

4.重构
最后,需要对融合后的图像金字塔进行重构。重构的过程就是将每个拉普拉斯金字塔层进行反变换,从而得到最终的融合图像。

2.代码实现

# 图像拼接
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 读取待拼接图像
MIN = 10
img1 = cv.imread('jm1.jpg')
img2 = cv.imread('jm2.jpg')
# 统一图像大小
height1 = int(img1.shape[0])
width1 = int(img1.shape[1])
dim = (width1, height1)
img2 = cv.resize(img2, dim, interpolation=cv.INTER_AREA)

# 创建SIFT特征点检测
sift = cv.SIFT_create()

# 检测兴趣点并计算描述子
kp1, describe1 = sift.detectAndCompute(img1, None)
kp2, describe2 = sift.detectAndCompute(img2, None)

# 使用OpenCV中的FLANN匹配算法进行特征匹配,并返回最近邻和次近邻匹配的结果
FLANN_INDEX_KDTREE = 0
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
searchParams = dict(checks=50)
flann = cv.FlannBasedMatcher(indexParams,searchParams)
matches = flann.knnMatch(describe1, describe2, k=2)

# 储存特征匹配最好的优质匹配点对
'''基于距离阈值选择优质匹配点对,如果最近邻m的距离小于0.65倍的次近邻n的距离,
则认为这个匹配点对是优质的,将它存储在good列表中。'''
good = []
for m,n in matches:
    if m.distance < 0.65 * n.distance:
        good.append(m)

# 可视化特征匹配结果,并保存
pic3 = cv.drawMatches(img1=img1, keypoints1=kp1, img2=img2, keypoints2=kp2, matches1to2=good, outImg=None)
cv.imwrite(r'/Users/xionglulu/Downloads/project1/m11.jpg', pic3)

# RANSAC算法计算单应性矩阵
if len(good) > MIN:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    tge_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
    M, mask = cv.findHomography(src_pts, tge_pts, cv.RANSAC, 2)
    # 源图像img2图像扭曲(透视变换)
    warpimg = cv.warpPerspective(img2, np.linalg.inv(M), (img1.shape[1] + img2.shape[1], img2.shape[0]))
    cv.namedWindow("warpimg", cv.WINDOW_NORMAL)
    cv.imshow('warpimg',warpimg)
    # 拼接图像
    direct = warpimg.copy()
    direct[0:img1.shape[0], 0:img1.shape[1]] = img1
    rows, cols = img1.shape[:2]

    left = 0
    right = cols
    # 找到img1和warpimg重叠的最左边界
    for col in range(0, cols):
        if img1[:, col].any() and warpimg[:, col].any():
            left = col
        break
    # 找到img1和warpimg重叠的最右边界
    for col in range(cols - 1, 0, -1):
        if img1[:, col].any() and warpimg[:, col].any():
            right = col
        break
    # 图像融合
    res = np.zeros([rows, cols, 3], np.uint8)

    for row in range(0, rows):
        for col in range(0, cols):
            if not img1[row, col].any():
                res[row, col] = warpimg[row, col]
            elif not warpimg[row, col].any():
                res[row, col] = img1[row, col]
            else:
                # 重叠部分加权平均
                srcimgLen = float(abs(col - left))
                testimgLen = float(abs(col - right))
                alpha = srcimgLen / (srcimgLen + testimgLen)
                res[row, col] = np.clip(img1[row, col] * (1 - alpha) + warpimg[row, col] * alpha, 0, 255)


    warpimg[0:img1.shape[0], 0:img1.shape[1]] = res
    img3 = cv.cvtColor(direct, cv.COLOR_BGR2RGB)
    plt.imshow(img3), plt.show()
    img4 = cv.cvtColor(warpimg, cv.COLOR_BGR2RGB)
    plt.imshow(img4), plt.show()
    cv.waitKey()
    cv.destroyAllWindows()

else:
    print("not enough matches!")

    结果:

python图像拼接,计算机视觉,opencv,人工智能
映射结果图
python图像拼接,计算机视觉,opencv,人工智能
阈值为2图像拼接结果图

 

python图像拼接,计算机视觉,opencv,人工智能
阈值为10图像拼接结果图

 

python图像拼接,计算机视觉,opencv,人工智能
阈值为2图像融合结果图

 

python图像拼接,计算机视觉,opencv,人工智能
阈值为10图像融合结果图

 

     结果分析:

1.拍摄时的角度、光线、曝光程度和远近程度等对图像匹配结果都会有影响。

2.SIFT算法进行特征匹配时,对于高度相似的特征点匹配效果并不好;RANSAC算法计算单应性矩阵时通过设置不同阈值选择内点,匹配的效果也不同;实验中阈值为2时,匹配效果比较好,但是映射时图像变形比较严重;实验中阈值为10时,变形缓解但是匹配效果并不好。

3.在进行图像融合时,本实验对重叠部分采用的是加权平均法,可以看出拼接缝两侧的颜色过渡比较自然,但仍可以采用Multi-Band Blending算法更好的融合,尽可能消除拼接缝。

    下面介绍另一种方法实现图像拼接与融合,使用opencv库中的cv2.Stitcher_create()函数创建了一个stitcher对象,并使用stitcher.stitch((img1, img2))函数将两张图像img1img2拼接在一起。

  cv2.Stitcher_create()函数接受一个可选的参数mode,用于指定拼接模式。mode的取值可以是以下两个常量之一:

cv2.STITCHER_PANORAMA:全景拼接模式。

cv2.STITCHER_SCANS:扫描线拼接模式。

  stitcher.stitch()函数返回一个包含两个元素的元组,其中第一个元素是一个整数,表示拼接的状态,第二个元素是一个numpy数组,表示拼接后的图像。

    代码:

import cv2
# 读取待拼接图像
img1 = cv2.imread('/Users/xionglulu/Downloads/project1/jm1.jpg')
img2 = cv2.imread('/Users/xionglulu/Downloads/project1/jm2.jpg')

# 创建stitcher对象并将两张图像拼接在一起
stitcher = cv2.Stitcher_create()
(status, stitched) = stitcher.stitch((img1, img2))

# 显示拼接后的图像
cv2.namedWindow("stitched image", cv2.WINDOW_NORMAL)
cv2.imshow("stitched image", stitched)
cv2.waitKey()
cv2.destroyAllWindows()

    结果:

python图像拼接,计算机视觉,opencv,人工智能
全景图

    结果分析:这种方法获得的全景图几乎完美,图像没有发生变形,没有明显拼接缝,而且颜色过渡均匀,但是存在一个问题,它似乎并不能对所有指定图像进行拼接处理,对拍摄角度相差不大的图像运行会出错,具体原因还有待考证。

 

到了这里,关于Python计算机视觉(三)—图像拼接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 计算机视觉--图像拼接

    计算机视觉--图像拼接

    单应性变换是指一个平面上的点通过一个矩阵变换映射到另一个平面上的点,这个变换矩阵是一个 3 × 3 3 times 3 3 × 3 的矩阵,称为单应性矩阵。单应性变换可以分为仿射变换和投影变换两种类型。 在单应性变换中,仿射变换是其中一种特殊的变换。仿射变换是指在变换前后

    2024年02月04日
    浏览(12)
  • 计算机视觉(三)图像拼接

    计算机视觉(三)图像拼接

    1.1 流程 要拼接多张图像,就一定要找到他们之间的映射关系,流程如下: 得到映射关系,就能进行拼接: 简而言之,拼接两张图像,就是找到他们的特征点,根据这些特征点: 1.2 映射与处理 找到两张图像的像素点对应关系,然后把第二张图像映射到在第一张图像的坐标系

    2024年02月05日
    浏览(7)
  • 计算机视觉基础学习-图像拼接

    计算机视觉基础学习-图像拼接

    首先本文介绍的图像拼接并非对尺寸相同的图片进行简单拼接,而是基于全景图的拼接 普通相机拍摄图像时,无法兼顾相机视场与视场中单个物体的分辨率问题,而全景相机普遍价格昂贵, 不适用于低成本的一般性场景。为了使用普通相机获取宽视角,甚至是 360°全景图像

    2023年04月10日
    浏览(8)
  • 计算机竞赛 - 基于机器视觉的图像拼接算法

    计算机竞赛 - 基于机器视觉的图像拼接算法

    图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要。 再举一个身边的例子吧,你用你的手机对某一场景拍照,但是你没有办法一次将所有你

    2024年02月13日
    浏览(10)
  • 计算机视觉项目实战-基于特征点匹配的图像拼接

    计算机视觉项目实战-基于特征点匹配的图像拼接

    😊😊😊 欢迎来到本博客 😊😊😊 本次博客内容将继续讲解关于OpenCV的相关知识 🎉 作者简介 : ⭐️⭐️⭐️ 目前计算机研究生在读。主要研究方向是人工智能和群智能算法方向。目前熟悉深度学习(keras、pytorch、yolo),python网页爬虫、机器学习、计算机视觉(OpenCV)、

    2024年02月02日
    浏览(9)
  • 计算机视觉算法中的图像拼接(Image Stitching)

    计算机视觉算法中的图像拼接(Image Stitching)

    随着数字摄影技术的发展,人们可以轻松地拍摄多张相邻的图像,并希望将它们合成为一张更大、更全面的图像。这就是图像拼接(Image Stitching)技术的应用场景。图像拼接是计算机视觉领域的一个重要研究方向,它旨在将多张重叠的图像拼接成一张无缝连接的全景图。 图像

    2024年02月06日
    浏览(16)
  • Python OpenCV 计算机视觉:6~7

    原文:OpenCV Computer Vision with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 计算机视觉 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 当别人说你没有底线的时候,你最好真的没有;当别人说你做过某些事的时候,你也最好真的做过。 本附录显示了如何在

    2024年02月02日
    浏览(21)
  • 【Python入门系列】第十篇:Python图像处理和计算机视觉

    图像处理和计算机视觉是计算机科学中非常重要的领域之一。Python作为一种功能强大且易于学习的编程语言,提供了许多用于图像处理和计算机视觉的库和工具。本文将介绍一些常用的Python库,并提供一些示例代码。 Python中有几个流行的图像处理库,其中最常用的是OpenCV和

    2024年02月12日
    浏览(9)
  • 计算机竞赛 机器视觉的试卷批改系统 - opencv python 视觉识别

    计算机竞赛 机器视觉的试卷批改系统 - opencv python 视觉识别

    🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的试卷系统 - opencv python 视觉识别 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 机器视觉的发展对存在的作业批改问题, 提供了有效的解决方案

    2024年02月07日
    浏览(11)
  • Opencv快速入门教程,Python计算机视觉基础

    Opencv快速入门教程,Python计算机视觉基础

    OpenCV 是 Intel® 开源计算机视觉库。它由一系列 C 函数和少量 C++ 类构成, 实现了图像处理和计算机视觉方面的很多通用算法。 OpenCV 拥有包括 300 多个 C 函数的跨平台的中、高层 API。它不依赖于其它的外部库——尽管也 可以使用某些外部库。 OpenCV 对非商业应用和商业应用都

    2024年02月09日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包