OpenCV处理图片拼接

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

图片拼接(实战项目三)

主题思路

  1. 读入图片

  2. 预处理图片

  3. 图片特征提取

  4. 特征处理

  5. 特征匹配

  6. 透视变换

  7. 图片再处理

  8. (可选)图片特征点连线配对

具体代码

Sticher.py

引入头文件
import cv2
import numpy as np
创建类
class Sticher:
自定义函数
  • def stich:外部接口函数

  • def detectAndDescribe:用于图片的特征点提取,内部逻辑函数

  • def matchKeypoints:特征点匹配

  • def drawMatches:显示2图片的特征点匹配,用线勾勒出来,方便观察细节(可选)

展示图片函数:show()
    def show(self, image, name='demo'):
        cv2.imshow(name, image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
外部接口函数:stich()

stich函数传入一个images的列表,里面包含2个图片,经过一系列其他成员函数后将2图片合并

参数说明:

ratio = 0.75 (先验知识,拿来主义~)

# reprojThresh是RANSAC算法中的阈值参数,用于判断是否为内点(inlier)的阈值
# reprojThresh越低,说明受外点影响越小,图像拟合结果更精细,但可能过滤掉一些有价值的匹配点
# reprojThresh越高,说明容忍度越高,但效果可能偏低
    def stich(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):#showMatches是自己定义的一个选项,没什么用
        # 获取输入图片
        (imageB, imageA) = images
        # 检测A,B图片的SIFT关键特征点,并计算特征描述子
        (kpsA, featureA) = self.detectAndDescribe(imageA)
        (kpsB, featureB) = self.detectAndDescribe(imageB)
        # 经过detectAndDescribe()后,返回的kpsA和kpsB都是经过处理后的特征点集信息
        # kpsA,kpsB里面只包含了特征点的坐标信息(pt),因为该成员方法已经过滤提取
        # 匹配两张图片的所有特征点,返回匹配结果
        M = self.matchKeypoints(kpsA, kpsB, featureA, featureB, ratio, reprojThresh)
​
        # 如果返回结果为空,则没有匹配成功的特征点,退出算法
        if M is None:
            return None
​
        # 若匹配成功
        (matches, H, status) = M
        # 我们处理的思路是:
        # 将右边图片进行透视变换,使之与左边的图片配对
        # H为透视变换矩阵
        # 该函数要把imageA依据关系矩阵H进行透视变换,得到一个(宽,高)尺寸的图片
        # 由于H是综合imageA和imageB得到的,所以我们执行完warnPerspective后,会看到imageA中带上了imageB
        result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))
        self.show(result)
        # 参数对应位: (高,宽)
        result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB
        self.show(result)
        # 检测是否需要显示图片匹配:
        if showMatches:
            # 生成匹配图片
            vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
            return (result, vis)
        return result
特征点提取分析函数:detectAndDescribe()

核心思路:SIFT算法文章来源地址https://www.toymoban.com/news/detail-832062.html

# 检测图像的SIFT关键特征点并计算特征描述子
def detectAndDescribe(self, image):
    # 寻找图片的特征点先将图片转换为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 建立一个SIFT特征扫描器(可能有的版本有专利保护)
    descriptor = cv2.xfeatures2d.SIFT_create()
    # 检测SIFT特征点,并计算描述子
    # None表示检测全图,没有掩码遮罩
    (kps, features) = descriptor.detectAndCompute(image, None)#唯该函数真正进行特征点分析
    #kps包含一个特征点的一系列信息:一般我们需要的是 kp.pt 即图片的坐标信息(x,y)
    #kps的其他信息如:size(特征点尺度大小),angle(特征点的方向角度),class_id(特征点的唯一标识)
​
    # 将结果转换成Numpy数组
    # 接下来只提取 kps中 pt 的信息,并将其转成浮点32位的形式,格式需服务于后面的透视变换要求
    # kp.pt 这的pt 包含一个特征点的坐标位置信息,一般是一个二维向量
    kps = np.float32([kp.pt for kp in kps])
​
    # 返回特征点集(kps)和特征点局部区域的特征描述信息(features:特征描述子)
    return (kps, features)
OpenCV处理图片拼接,opencv,人工智能,计算机视觉
OpenCV处理图片拼接,opencv,人工智能,计算机视觉
OpenCV处理图片拼接,opencv,人工智能,计算机视觉
特征匹配函数:matchKeypoints()
#注:此时传入的kps都是只保留了特征点的坐标信息的二维数组
def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):
    # 建立暴力匹配器(BF算法)
    matcher = cv2.BFMatcher()
    # 使用knn检测来自A,B图的SIFT特征匹配对,k=2
    # 下面进行区域匹配,得到一个粗糙的匹配结果,还要进行过滤
    rawMatches = matcher.knnMatch(featuresA, featuresB, 2)
    matches = []  # 该列表用于存放最终的匹配结果
    for m in rawMatches:
        if len(m) == 2 and m[0].distance < m[1].distance * ratio:
            # trainIdx表示训练图像的特征点索引信息,queryIdx表示查询图像的特征点索引信息
            matches.append((m[0].trainIdx, m[0].queryIdx))
    # matches里面现在存放的是 二维数组,每一个单独的元素都代表一个匹配对的信息
​
    # 当筛选后的匹配对大于4时,(我们得保证至少有4个点,才可以进行透视变换_实际上不是这样理解,底层涉及高数)
    if len(matches) > 4:
        # 获取匹配对的点的坐标
        # 这个for循环表示:
        # A:查询出:查询图像特征点的下表索引i
        # 依据i找到其在A图像的特征点集的信息(此处kpsA已经被提前处理成只有kp.pt坐标位信息了
        ptsA = np.float32([kpsA[i] for (_, i) in matches])
        ptsB = np.float32([kpsB[i] for (i, _) in matches])
        # 经过上述计算后,得到的ptsA,ptsB只是筛选后的特征点的坐标二维数组
        # 计算出透视关系
        # cv2.RANSAC:表示使用 RANSAC(Random Sample Consensus)算法进行鲁棒性估计和选择内点的方法
        # findHomography()与cv2.getPerspectiveTransform()不同的是,前者注重图像配准,后者注重图像透视变换,虽然两者都是用来图片的变换矩阵
        (H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, reprojThresh)
        # H表示单应性矩阵,表示从原始图像到目标图像的变换矩阵(到时候会拿来对right图像进行透视变换)
        return (matches, H, status)
        # matches里面存放的是二维数组,特征点的下标索引值(训练图片的下标索引值,查询图片的下标索引值)
    return None
(可选)绘制匹配函数:drawMatches()
# 同理,这里的kps都是处理后的
def drawMatches(self, imageA, imageB, kpsA, kpsB, matches, status):
    # 提取图片的尺寸信息
    (hA, wA) = imageA.shape[:2]
    (hB, wB) = imageB.shape[:2]
    # 使用np.zero创建一个空白图像(也可以说是创建一个三维数组,本质一样,都是zeros方法)
    vis = np.zeros((max(hA, hB), wA + wB, 3), dtype="uint8")
    # vis 就是我们用来绘制:特征点间连线的图
    vis[0:hA, 0:wA] = imageA#左边放imageA
    vis[0:hB, wA:] = imageB#右边放imageB
​
    for ((trainIdx, queryIdx), s) in zip(matches, status):
        if s == 1:  # 即点对匹配成功
            ptA = (int(kpsA[queryIdx][0]), int(kpsA[queryIdx][1]))
            ptB = (int(kpsB[trainIdx][0] + wA), int(kpsB[trainIdx][1]))
            cv2.line(vis, ptA, ptB, (0, 255, 0), 1)  # 在图片上画出绿色线条,端点两端连接着2个匹配的特征点
​
    return vis  # vis 代表可视化结果

imageStichering.py

from Sticher import Sticher# 不能直接写import,原理同(java 静态内部类static一样)
import cv2
​
imageA = cv2.imread("right_01.png")
imageB = cv2.imread("left_01.png")
​
#创建一个工具类
Sticher = Sticher()
(result,vis) = Sticher.stich([imageB,imageA],showMatches=True)
​
#显示所有图片
cv2.imshow('line',vis)
cv2.imshow('res',result)
cv2.waitKey(0)
cv2.destroyAllWindows()

到了这里,关于OpenCV处理图片拼接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • opencv多张图片实现全景拼接

       最近camera项目需要用到全景拼接,故此查阅大量资料,终于将此功能应用在实际项目上,下面总结一下此过程中遇到的一些问题及解决方式,同时也会将源码附在结尾处,供大家参考,本文采用的opencv版本为3.4.12。   首先说一下此源码的大概执行流程,此项目进行全

    2024年01月17日
    浏览(46)
  • 基于Java(SpringBoot框架)毕业设计作品成品(33)AI人工智能毕设AI常用数字图像图片特效处理系统设计与实现

    博主介绍: 《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、PPT、论文模版

    2024年02月08日
    浏览(48)
  • 基于Java(SpringBoot框架)毕业设计作品成品(34)AI人工智能毕设AI41_黑白图片和上色处理系统设计与实现

    博主介绍: 《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、PPT、论文模版

    2024年02月08日
    浏览(46)
  • OpenCV将两张图片拼接成一张图片

    可以用opencv或者numpy的拼接函数,直接将两张图拼接到一起,很简单方便,参考代码2, 推荐此方式 。 新建图片,将两张图片的像素值填充到新图片对应位置上即可,参考代码1。 以下是将两张图片拼接成一张图片的示例代码: 以下是将两张图片在同一个窗口显示的示例代码

    2024年02月04日
    浏览(49)
  • Python 结合opencv实现图片截取和拼接

    python 3.6.2 scikit-build-0.16.7 win10 opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 下载地址: https://pypi.org/project/opencv-python/4.5.4.60/#files https://files.pythonhosted.org/packages/57/6c/7f4f56b2555d5c25dd4f41fc72a16dc6402cb2b4f967da11d8d26c669b55/opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 注意:下载时不用下abi版的,比如 o

    2024年02月08日
    浏览(45)
  • opencv实践项目-多张图片拼接之stitcher

    OpenCV从2.4.x版本之后多出来一个新的模型 图像拼接,该模块通过简单的高级API设置,可以获得比较好的图像拼接效果,OpenCV官方提供了一个高度集成的API函数 Stitcher,只要两行代码就可以得到一个很好的拼接图像。 其中第一行代码是创建拼接Stitcher的指针,第二行代码是调用

    2024年02月04日
    浏览(43)
  • Python Opencv实践 - 全景图片拼接stitcher

            由于手里没有切割好的全景图片资源,因此首先写了一个切片的程序spliter。         如果有现成的切割好的待拼接的切片文件,则不需要使用spliter。         对于全景图片的拼接,需要注意一点,各个切片图片之间要有重复的内容以便opencv能够提取到关键点并

    2024年02月22日
    浏览(49)
  • openCV 第四篇 角点检测、图像特征、图片拼接

    本文原本打算直接简单介绍一下harris和sift,之后进行特征匹配,来一波图像拼接。 想来想去还是先介绍下原理吧,虽然没人看QAQ。可以直接点击右侧目录跳转到代码区。 角点检测  和  图像特征提取(就几行代码) 以及进行图像拼接代码,来完成如下操作: 上图我们可以清楚

    2024年01月17日
    浏览(53)
  • OpenCV完美实现两张图片的全景拼接(详细教程)

    目录 1,主要步骤 1.1  导入需要的包和模块,并读取两张待拼接的图片,这里我们假设它们为 left.jpg 和 right.jpg。 1.2  创建SIFT检测器 1.3 创建一个基于 FLANN 的匹配器 1.4  筛选过程删除掉一些不合适的匹配点,只保留最好的匹配点 1.5透视变换 1.6  消除重叠的效果,对两张

    2024年02月06日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包