OpenCV完美实现两张图片的全景拼接(详细教程)

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

目录

1,主要步骤

1.1  导入需要的包和模块,并读取两张待拼接的图片,这里我们假设它们为 left.jpg 和 right.jpg。

1.2  创建SIFT检测器

1.3 创建一个基于 FLANN 的匹配器

1.4  筛选过程删除掉一些不合适的匹配点,只保留最好的匹配点

1.5透视变换

1.6  消除重叠的效果,对两张图片进行加权处理

2,代码展示

3,效果展示


应用场景主要有两个方面:

  1. 风景或建筑物的拍摄

对于一些风景或建筑物的拍摄,有时候需要的画面宽度超出了单张图片所能提供的视野范围。这时可以通过拍摄多张图片并将它们拼接成一张更加宽阔的全景图来达到所需的效果。

  1. 科学研究

在一些科学研究中,需要对一定的区域进行高精度测量,例如地形测量、海洋测量等。这时候就需要一些宽视野相机来实现拍摄。但是,由于一张图片所能覆盖的区域有限,因此通常还需要将多张图片拼接成一张更大的全景图像,方便科学家们进行研究和分析。

1,主要步骤

  1. 读入待拼接的图片并调整大小;
  2. 使用 SIFT 或 SURF 算法提取图片的关键点和描述符;
  3. 使用基于 FLANN 的匹配器进行关键点匹配,并筛选出较好的匹配点;
  4. 计算视角变换矩阵,并使用透视变换对右边的图片进行变换;
  5. 消除重叠的效果,对两张图片进行加权处理;
  6. 输出拼接后的结果。

1.1  导入需要的包和模块,并读取两张待拼接的图片,这里我们假设它们为 left.jpg 和 right.jpg。

左视图:

OpenCV完美实现两张图片的全景拼接(详细教程),OpenCV从入门到精通,opencv,人工智能,计算机视觉,python

右视图:

OpenCV完美实现两张图片的全景拼接(详细教程),OpenCV从入门到精通,opencv,人工智能,计算机视觉,python

1.2  创建SIFT检测器

cv2.xfeatures2d.SIFT_create() 创建一个 SIFT 检测器。

也可以选择使用 cv2.SIFT_create()

不过前者是更新的版本,可能会更好一些

然后,在两张图片上分别使用这个检测器进行关键点检测和特征提取,获得关键点集合和描述符集合。

surf=cv2.xfeatures2d.SIFT_create()#可以改为SIFT
#sift = cv2.SIFT_create()
sift = cv2.xfeatures2d.SIFT_create()

kp1,descrip1 = sift.detectAndCompute(imageA,None)
kp2,descrip2 = sift.detectAndCompute(imageB,None)

1.3 创建一个基于 FLANN 的匹配器

调用 cv2.FlannBasedMatcher() 创建一个基于 FLANN 的匹配器,并使用 knnMatch() 处理两张图片的特征描述符,得到最佳匹配。

indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
searchParams = dict(checks=50)
flann=cv2.FlannBasedMatcher(indexParams,searchParams)
match=flann.knnMatch(descrip1,descrip2,k=2)
good=[]

1.4  筛选过程删除掉一些不合适的匹配点,只保留最好的匹配点

for i,(m,n) in enumerate(match):
    if(m.distance<0.75*n.distance):
        good.append(m)

1.5透视变换

判断满足条件的匹配点数量是否大于阈值 MIN,如果大于,则进行视角变换矩阵的计算,将右边的图片 imageB 对其进行透视变换,得到 warpImg

if len(good) > MIN:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)
    ano_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)
    M,mask = cv2.findHomography(src_pts,ano_pts,cv2.RANSAC,5.0)
    warpImg = cv2.warpPerspective(imageB, np.linalg.inv(M), (imageA.shape[1]+imageB.shape[1], imageB.shape[0]))
    direct=warpImg.copy()
    direct[0:imageA.shape[0], 0:imageB.shape[1]] =imageA
    simple=time.time()

show('res',warpImg)

同时,将左边的图片覆盖在变换后的图片上,得到 direct。最后,显示结果。

print(rows)
print(cols)
for col in range(0,cols):
    # 开始重叠的最左端
    if imageA[:, col].any() and warpImg[:, col].any():
        left = col
        print(left)
        break

for col in range(cols-1, 0, -1):
    #重叠的最右一列
    if imageA[:, col].any() and warpImg[:, col].any():
        right = col
        print(right)
        break

1.6  消除重叠的效果,对两张图片进行加权处理

根据图片相对位置的不同,左边的图片和右边的图片有可能会在某些列出现重叠部分,为了消除这种不自然的效果,需要实现像素级的混合。首先找到左右图片开始重叠的位置和结束的位置,然后对两张图片进行加权处理,最后将加权后的图片输出。

#加权处理
res = np.zeros([rows, cols, 3], np.uint8)
for row in range(0, rows):
    for col in range(0, cols):
        if not imageA[row, col].any():  # 如果没有原图,用旋转的填充
            res[row, col] = warpImg[row, col]
        elif not warpImg[row, col].any():
            res[row, col] = imageA[row, col]
        else:
            srcImgLen = float(abs(col - left))
            testImgLen = float(abs(col - right))
            alpha = srcImgLen / (srcImgLen + testImgLen)
            res[row, col] = np.clip(imageA[row, col] * (1 - alpha) + warpImg[row, col] * alpha, 0, 255)

warpImg[0:imageA.shape[0], 0:imageA.shape[1]]=res
show('res',warpImg)
final=time.time()
print(final-starttime)

2,代码展示

import cv2
import numpy as np
from matplotlib import pyplot as plt
import time
def show(name,img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
MIN = 10
FLANN_INDEX_KDTREE = 0
starttime = time.time()
img1 = cv2.imread('left.jpg') #query
img2 = cv2.imread('right.jpg') #train
imageA = cv2.resize(img1,(0,0),fx=0.2,fy=0.2)
imageB = cv2.resize(img2,(0,0),fx=0.2,fy=0.2)
surf=cv2.xfeatures2d.SIFT_create()#可以改为SIFT
#sift = cv2.SIFT_create()
sift = cv2.xfeatures2d.SIFT_create()

kp1,descrip1 = sift.detectAndCompute(imageA,None)
kp2,descrip2 = sift.detectAndCompute(imageB,None)
#创建字典
indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
searchParams = dict(checks=50)
flann=cv2.FlannBasedMatcher(indexParams,searchParams)
match=flann.knnMatch(descrip1,descrip2,k=2)
good=[]
#过滤特征点
for i,(m,n) in enumerate(match):
    if(m.distance<0.75*n.distance):
        good.append(m)

# 当筛选后的匹配对大于10时,计算视角变换矩阵
if len(good) > MIN:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)
    ano_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)
    M,mask = cv2.findHomography(src_pts,ano_pts,cv2.RANSAC,5.0)
    warpImg = cv2.warpPerspective(imageB, np.linalg.inv(M), (imageA.shape[1]+imageB.shape[1], imageB.shape[0]))
    direct=warpImg.copy()
    direct[0:imageA.shape[0], 0:imageB.shape[1]] =imageA
    simple=time.time()

show('res',warpImg)
rows,cols=imageA.shape[:2]
print(rows)
print(cols)
for col in range(0,cols):
    # 开始重叠的最左端
    if imageA[:, col].any() and warpImg[:, col].any():
        left = col
        print(left)
        break

for col in range(cols-1, 0, -1):
    #重叠的最右一列
    if imageA[:, col].any() and warpImg[:, col].any():
        right = col
        print(right)
        break
#加权处理
res = np.zeros([rows, cols, 3], np.uint8)
for row in range(0, rows):
    for col in range(0, cols):
        if not imageA[row, col].any():  # 如果没有原图,用旋转的填充
            res[row, col] = warpImg[row, col]
        elif not warpImg[row, col].any():
            res[row, col] = imageA[row, col]
        else:
            srcImgLen = float(abs(col - left))
            testImgLen = float(abs(col - right))
            alpha = srcImgLen / (srcImgLen + testImgLen)
            res[row, col] = np.clip(imageA[row, col] * (1 - alpha) + warpImg[row, col] * alpha, 0, 255)

warpImg[0:imageA.shape[0], 0:imageA.shape[1]]=res
show('res',warpImg)
final=time.time()
print(final-starttime)

3,效果展示

OpenCV完美实现两张图片的全景拼接(详细教程),OpenCV从入门到精通,opencv,人工智能,计算机视觉,python文章来源地址https://www.toymoban.com/news/detail-742256.html

到了这里,关于OpenCV完美实现两张图片的全景拼接(详细教程)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 使用ffmpeg拼接两张图片

      最近在工作中遇到了一个需求,就是需要将两张图片拼接在一起,作为一个封面图。如果只是临时拼接一张,我们可以只用photoshop之类的图片编辑工具,将两张图片拼接在一起。而我们的需要是需要实现自动化,由于之前使用过ffmpeg做过图片的操作,于是搜索了下,ffm

    2024年02月02日
    浏览(29)
  • 3 OpenCV两张图片实现稀疏点云的生成

    前文: 1 基于SIFT图像特征识别的匹配方法比较与实现 2 OpenCV实现的F矩阵+RANSAC原理与实践 1.1 由F到E E = K T ∗ F ∗ K E = K^T * F * K E = K T ∗ F ∗ K E 矩阵可以直接通过之前算好的 F 矩阵与相机内参 K 矩阵获得 相机内参获得的方式是一个较为复杂的方式,需要使用棋盘进行定位获得

    2024年02月07日
    浏览(33)
  • OpenCV Python – 使用SIFT实现两张图片的特征匹配

     我们使用尺度不变特征变换(  SIFT  )特征描述符和暴力匹配算法实现两张图像的特征匹配。其中,  SIFT  用于找到图像中的关键点和描述符,而  暴力匹配算法  用于在两张图像中匹配描述符。 要使用  SIFT  特征检查器和  暴力  匹配算法实现两张图像的特征匹配,可

    2024年02月03日
    浏览(49)
  • OpenCV Python – 使用SIFT算法实现两张图片的特征匹配

    1.要实现在大图中找到任意旋转、缩放等情况下的小图位置,可以使用特征匹配算法,如 SIFT (尺度不变特征变换) 或 SURF (加速稳健特征)。这些算法可以在不同尺度和旋转情况下寻找匹配的特征点 2.我们使用了 SIFT 算法检测和匹配特征点,然后使用 RANSAC 算法计算透视变换矩阵

    2024年02月06日
    浏览(47)
  • opencv-全景图像拼接

    运行环境 python3.6 + opencv 3.4.1.15 stitcher.py

    2024年02月11日
    浏览(60)
  • 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日
    浏览(43)
  • 基于MATLAB的Harris角点检测完成图片全景拼接

    目录 作业概要 1 原理及实现 1 2.1. 模块1 Harris角点检测 1 根据角点响应函数计算每个像素点的角点响应值; 2 2.2. 模块2 关键点的描述及其匹配 3 2.2.1. 生成描述向量 3 2.2.2. 匹配描述子 4 输出matched_points和匹配点对数count; 5 2.3. 模块3 转换矩阵的估计 5 输出仿射变换矩阵H。 6 2

    2024年01月17日
    浏览(41)
  • 使用openCV比对任意两张图片的相似度(亲测较准确)

    方案:使用openCV中的直方图算法做对比。测试效果较好。 代码中提供了均方差算法(MSE)、结构相似性指数算法(SSIM)、峰值信噪比(PSNR)、直方图算法。其中直方图效果最好 Exception in thread \\\"main\\\" java . lang . UnsatisfiedLinkError : no opencv_java455 in java . library . path Exception in threa

    2024年02月16日
    浏览(33)
  • MidJourney教程03--BLEND 两张图片合成一张图片

    MidJourney教程02--BLEND 两张图片合成一张图片 首先输入   然后会让你选择两张图片进行处理!  那么,现在我们把比卡丘,和路飞融合在一起啦!  接下来看出来效果会是怎么样子呢? 那么,我们就得到了一个路飞比卡丘! 其实还有很多种方法可以使用! 例如场景与产品的

    2024年02月15日
    浏览(41)
  • OpenCV处理图片拼接

    读入图片 预处理图片 图片特征提取 特征处理 特征匹配 透视变换 图片再处理 (可选)图片特征点连线配对 Sticher.py 引入头文件 创建类 自定义函数 def stich:外部接口函数 def detectAndDescribe:用于图片的特征点提取,内部逻辑函数 def matchKeypoints:特征点匹配 def drawMatches:显示2图片的特

    2024年02月21日
    浏览(33)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包