计算机视觉--图像拼接

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

单应性变换

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

仿射变换

在单应性变换中,仿射变换是其中一种特殊的变换。仿射变换是指在变换前后,保持原来的平行线还是平行线,并且保持原来的比例关系不变。一个二维平面上的仿射变换可以表示为:

[ x ′ y ′ 1 ] = [ a b c d e f 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} xy1 = ad0be0cf1 xy1

其中, ( x , y ) (x,y) (x,y) 是原来平面上的一个点, ( x ′ , y ′ ) (x',y') (x,y) 是变换后平面上的对应点。矩阵中的参数 a , b , c , d , e , f a,b,c,d,e,f a,b,c,d,e,f 决定了变换的效果。

具体地,仿射变换包括平移、旋转、缩放和错切四种基本变换。其中,平移可以通过将矩阵中的 c c c f f f 分别设置为平移的距离 t x t_x tx t y t_y ty 来实现;旋转可以通过将矩阵中的 a a a d d d 设置为 cos ⁡ θ \cos \theta cosθ sin ⁡ θ \sin \theta sinθ b b b e e e 设置为 − sin ⁡ θ -\sin \theta sinθ cos ⁡ θ \cos \theta cosθ 来实现;缩放可以通过将矩阵中的 a a a e e e 分别设置为 s x s_x sx s y s_y sy 来实现;错切可以通过将矩阵中的 b b b 设置为 k x k_x kx d d d 设置为 k y k_y ky 来实现。其中, t x t_x tx t y t_y ty 表示平移的距离, θ \theta θ 表示旋转的角度, s x s_x sx s y s_y sy 表示缩放的比例, k x k_x kx k y k_y ky 表示错切的程度。

图像扭曲实现

以下是原图:
计算机视觉--图像拼接

import cv2
import numpy as np

# 读取图片
img = cv2.imread('background/background.jpg')

# 图像的高和宽
rows, cols = img.shape[:2]

# 设置扭曲前后的三个点的坐标
pts1 = np.float32([[0, 0], [cols - 1, 0], [0, rows - 1]])
pts2 = np.float32([[cols * 0.2, rows * 0.1], [cols * 0.9, rows * 0.2], [cols * 0.1, rows * 0.9]])

# 生成变换矩阵
M = cv2.getAffineTransform(pts1, pts2)

# 进行仿射变换
dst = cv2.warpAffine(img, M, (cols, rows))

# 显示原图和扭曲后的图像
cv2.imshow('image', img)
cv2.imshow('affine', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

扭转后的图片:
计算机视觉--图像拼接

图像嵌入(图中图)

被嵌入图像:计算机视觉--图像拼接
嵌入至以下图像中:计算机视觉--图像拼接

# -*- coding: utf-8 -*-
import cv2
from numpy import array
from PCV.geometry import warp
from PIL import Image
from pylab import *
from scipy import ndimage

# 读取两张灰度图像
im1 = cv2.imread(r'background/in.jpg', cv2.IMREAD_GRAYSCALE)
im2 = cv2.imread(r'background/background.jpg', cv2.IMREAD_GRAYSCALE)

# 设置仿射变换的四个点
tp = array([[164,538,540,264],[40,36,405,405],[1,1,1,1]])

# 进行仿射变换
im3 = warp.image_in_image(im1,im2,tp)

# 显示三张图像
figure()
gray()

# 显示第一张图像
imshow(im1)
show()

# 显示第二张图像
imshow(im2)
show()

# 显示第三张图像
imshow(im3)
show()

嵌入后的结果:
计算机视觉--图像拼接

RANSAC算法

算法介绍

RANSAC(Random Sample Consensus)是一种基于随机采样的迭代算法,用于估计数据集中的模型参数。它主要用于从一组有噪声的数据中估计出一个最优的数学模型。

下面是 RANSAC 算法的基本流程:

  1. 随机采样:从原始数据中随机选择一定数量的样本来构造一个初始模型,这个初始模型可以用来进行后续的计算。

  2. 模型拟合:使用所选样本来拟合一个数学模型。

  3. 内点选择:计算每个数据点到所估计的模型的距离,如果距离小于给定的阈值,则将该数据点视为“内点”,否则将其视为“外点”。

  4. 判断收敛:判断是否有足够的内点,如果内点数目达到了一定的阈值,就认为模型已经收敛。

  5. 重复以上步骤:重复以上步骤,直到满足收敛条件或达到预先设定的最大迭代次数。

图片收集

图片就地取材,在宿舍后方连续拍摄2张可拼接的图片:
计算机视觉--图像拼接

无RANSAC优化和有RANSAC优化的代码实现

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

def blend_images(s, t):
    # 给图片加边框
    s = cv.copyMakeBorder(s, 50, 50, 0, 250, cv.BORDER_CONSTANT, value=(0,0,0))
    t = cv.copyMakeBorder(t, 50, 50, 0, 250, cv.BORDER_CONSTANT, value=(0,0,0))

    # 获取图片大小
    w,h = s.shape[:2]

    # 转换为灰度图
    g1 = cv.cvtColor(s, cv.COLOR_BGR2GRAY)
    g2 = cv.cvtColor(t, cv.COLOR_BGR2GRAY)

    # 创建SIFT对象
    sift = cv.SIFT_create()

    # 检测关键点和计算描述符
    k1, d1 = sift.detectAndCompute(g1, None)
    k2, d2 = sift.detectAndCompute(g2, None)

    # 创建FLANN匹配器
    F = cv.FlannBasedMatcher(dict(algorithm=1, trees=5), dict(checks=50))

    # 匹配关键点
    m = F.knnMatch(d1, d2, k=2)
    mask = [[0, 0] for _ in range(len(m))]

    # 根据阈值筛选匹配点
    l1 = [j for i, (j, k) in enumerate(m) if j.distance < 0.7 * k.distance]
    mask = [[1, 0] if j.distance < 0.7 * k.distance else [0, 0] for i, (j, k) in enumerate(m)]

    # 获取图片大小
    r, c = s.shape[:2]

    # 如果匹配点大于10个,计算单应性矩阵
    if len(l1) > 10:
        sc = np.float32([k1[m.queryIdx].pt for m in l1]).reshape(-1, 1, 2)
        ds = np.float32([k2[m.trainIdx].pt for m in l1]).reshape(-1, 1, 2)
        M, mask = cv.findHomography(sc, ds, cv.RANSAC, 4.0)
        MM = np.array(M)
        # 透视变换
        wimg = cv.warpPerspective(t, np.array(MM), (t.shape[1], t.shape[0]), flags=cv.WARP_INVERSE_MAP)

        # 获取左右边界
        left = next(col for col in range(0, c) if s[:, col].any() and wimg[:, col].any())
        right = next(col for col in range(c-1, 0, -1) if s[:, col].any() and wimg[:, col].any())

        # 创建结果图像
        res = np.zeros([r, c, 3], np.uint8)
        for row in range(0, r):
            for col in range(0, c):
                if not s[row, col].any():
                    res[row, col] = wimg[row, col]
                elif not wimg[row, col].any():
                    res[row, col] = s[row, col]
                else:
                    slen = float(abs(col - left))
                    tlen = float(abs(col - right))
                    alpha = slen / (slen + tlen)
                    # 混合图像
                    res[row, col] = np.clip(s[row, col] * (1-alpha) + wimg[row, col] * alpha, 0, 255)

        # 以下为不做ransac处理的结果结果
        M0, mask0 = cv.findHomography(sc, ds, cv.RANSAC, 0)
        MM0 = np.array(M0)
        wimg0 = cv.warpPerspective(t, np.array(MM0), (t.shape[1], t.shape[0]), flags=cv.WARP_INVERSE_MAP)
        res0 = np.zeros([r, c, 3], np.uint8)
        for row in range(0, r):
            for col in range(0, c):
                if not s[row, col].any():
                    res0[row, col] = wimg0[row, col]
                elif not wimg0[row, col].any():
                    res0[row, col] = s[row, col]
                else:
                    slen = float(abs(col - left))
                    tlen = float(abs(col - right))
                    alpha = slen / (slen + tlen)
                    # 混合图像
                    res0[row, col] = np.clip(s[row, col] * (1-alpha) + wimg0[row, col] * alpha, 0, 255)
        return res, res0

# 读取左右两张图片
i1 = cv.imread(r'left.jpg')
i2 = cv.imread(r'right.jpg')
# 调整图片大小
i1 = cv.resize(i1,(756,1008))
i2 = cv.resize(i2,(756,1008))

res, res0 = blend_images(i1, i2)

# 展示结果
plt.subplot(1, 2, 1)
plt.imshow(cv.cvtColor(res0, cv.COLOR_BGR2RGB))
plt.title('res0')
plt.subplot(1, 2, 2)
plt.imshow(cv.cvtColor(res, cv.COLOR_BGR2RGB))
plt.title('res')
plt.show()

# 保存结果
cv.imwrite('res0.jpg', res0)
cv.imwrite('res.jpg', res)

生成的全景结果:
计算机视觉--图像拼接

差别

理论上这两种方法应该会存在些许差别,但是通过这次实验我们很难看出,当然我在本机上也运行过其他图片,拼接的结果都几乎相似。

总结

本次实验主要涉及到计算机视觉领域中图像特征提取、匹配、单应性矩阵估计以及图像融合等方面的内容。这一过程中,我们使用了一些常用的库和工具,例如numpy、cv2和matplotlib等。通过学习本实验,我对图像拼接的原理、方法和实现方式有了更深入的了解和认识,同时也掌握了使用OpenCV进行图像拼接的基本技能。文章来源地址https://www.toymoban.com/news/detail-444463.html

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

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

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

相关文章

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

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

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

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

    2024年02月02日
    浏览(50)
  • 计算机毕设 python opencv 机器视觉图像拼接算法

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

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

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

    2024年02月06日
    浏览(52)
  • 【计算机视觉】图像增强----图像的傅立叶变换

    个人简介:  📦个人主页:赵四司机 🏆学习方向:JAVA后端开发  ⏰往期文章:SpringBoot项目整合微信支付 🔔博主推荐网站:牛客网 刷题|面试|找工作神器 📣种一棵树最好的时间是十年前,其次是现在! 💖喜欢的话麻烦点点关注喔,你们的支持是我的最大动力。 目录 一:

    2024年02月04日
    浏览(39)
  • 计算机视觉-图像的傅里叶变换

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

    2023年04月08日
    浏览(41)
  • 【计算机视觉】二、图像形成——实验:2D变换编辑(Pygame)

    【计算机视觉】二、图像形成:1、向量和矩阵的基本运算:线性变换与齐次坐标   几何基元是计算机图形学中最基本的图形对象,它们是构建更复杂图形的基础单元。常见的几何基元包括: 点(Point) : 由一对或一组坐标值表示的零维对象。 线段(Line Segment) : 由两个端点确定的

    2024年03月22日
    浏览(45)
  • 计算机视觉 | 基于二值图像数字矩阵的距离变换算法

    Hi,大家好,我是半亩花海。 本实验基于 OpenCV 实现了二值图像数字矩阵的距离变换算法。首先生成一个 480x480 的黑色背景图像(定义黑色为0,白色为1),在其中随机选择了三个白色像素点作为距离变换的原点,利用 OpenCV 中 distanceTransform 等相关函数计算并输出这些原点到其

    2024年04月11日
    浏览(45)
  • 计算机视觉 图像形成 几何图形和变换 3D到2D投影

            现在我们知道如何表示2D和3D几何图元以及如何在空间上转换它们,我们需要指定如何将 3D图元投影到图像平面上。 我们可以使用线性3D到2D投影矩阵来做到这一点。最简单的模型是正交法,它不需要除法就可以得到最终的(不均匀的)结果。更常用的模型是透视,

    2023年04月08日
    浏览(64)
  • 【计算机视觉】二、图像形成:1、向量和矩阵的基本运算:线性变换与齐次坐标

    x = [ x y ] boldsymbol{x} =begin{bmatrix}x\\\\yend{bmatrix} x = [ x y ​ ] 1. 平移变换 [ x ′ y ′ ] = [ x y ] + [ a b ] begin{bmatrix}x\\\'\\\\y\\\'end{bmatrix} = begin{bmatrix}x\\\\yend{bmatrix} + begin{bmatrix}a\\\\bend{bmatrix} [ x ′ y ′ ​ ] = [ x y ​ ] + [ a b ​ ]   将向量 [ a b ] begin{bmatrix}a\\\\bend{bmatrix} [ a b ​ ] 加到 [

    2024年03月17日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包