OpenCV全景图像拼接的实现示例


Posted in Python onJune 05, 2021

本文主要介绍了OpenCV全景图像拼接的实现示例,分享给大家,具体如下:

left_01.jpg

OpenCV全景图像拼接的实现示例

right_01.jpg

OpenCV全景图像拼接的实现示例

Stitcher.py

import numpy as np
import cv2
 
class Stitcher:
 
    #拼接函数
    def stitch(self, images, ratio=0.75, reprojThresh=4.0,showMatches=False):
        #获取输入图片
        (imageB, imageA) = images
        #检测A、B图片的SIFT关键特征点,并计算特征描述子
        (kpsA, featuresA) = self.detectAndDescribe(imageA)
        (kpsB, featuresB) = self.detectAndDescribe(imageB)
 
        # 匹配两张图片的所有特征点,返回匹配结果
        M = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
 
        # 如果返回结果为空,没有匹配成功的特征点,退出算法
        if M is None:
            return None
 
        # 否则,提取匹配结果
        # H是3x3视角变换矩阵      
        (matches, H, status) = M
        # 将图片A进行视角变换,result是变换后图片
        result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))
        self.cv_show('result', result)
        # 将图片B传入result图片最左端
        result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB
        self.cv_show('result', result)
        # 检测是否需要显示图片匹配
        if showMatches:
            # 生成匹配图片
            vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
            # 返回结果
            return (result, vis)
 
        # 返回匹配结果
        return result
    def cv_show(self,name,img):
        cv2.imshow(name, img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
 
    def detectAndDescribe(self, image):
        # 将彩色图片转换成灰度图
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 
        # 建立SIFT生成器
        descriptor = cv2.xfeatures2d.SIFT_create()
        # 检测SIFT特征点,并计算描述子
        (kps, features) = descriptor.detectAndCompute(image, None)
 
        # 将结果转换成NumPy数组
        kps = np.float32([kp.pt for kp in kps])
 
        # 返回特征点集,及对应的描述特征
        return (kps, features)
 
    def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):
        # 建立暴力匹配器
        matcher = cv2.BFMatcher()
  
        # 使用KNN检测来自A、B图的SIFT特征匹配对,K=2
        rawMatches = matcher.knnMatch(featuresA, featuresB, 2)
 
        matches = []
        for m in rawMatches:
            # 当最近距离跟次近距离的比值小于ratio值时,保留此匹配对
            if len(m) == 2 and m[0].distance < m[1].distance * ratio:
            # 存储两个点在featuresA, featuresB中的索引值
                matches.append((m[0].trainIdx, m[0].queryIdx))
 
        # 当筛选后的匹配对大于4时,计算视角变换矩阵
        if len(matches) > 4:
            # 获取匹配对的点坐标
            ptsA = np.float32([kpsA[i] for (_, i) in matches])
            ptsB = np.float32([kpsB[i] for (i, _) in matches])
 
            # 计算视角变换矩阵
            (H, status) = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, reprojThresh)
 
            # 返回结果
            return (matches, H, status)
 
        # 如果匹配对小于4时,返回None
        return None
 
    def drawMatches(self, imageA, imageB, kpsA, kpsB, matches, status):
        # 初始化可视化图片,将A、B图左右连接到一起
        (hA, wA) = imageA.shape[:2]
        (hB, wB) = imageB.shape[:2]
        vis = np.zeros((max(hA, hB), wA + wB, 3), dtype="uint8")
        vis[0:hA, 0:wA] = imageA
        vis[0:hB, wA:] = 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)
 
        # 返回可视化结果
        return vis

ImageStiching.py

from Stitcher import Stitcher
import cv2
 
# 读取拼接图片
imageA = cv2.imread("left_01.jpg")
imageB = cv2.imread("right_01.jpg")
 
# 把图片拼接成全景图
stitcher = Stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=True)
 
# 显示所有图片
cv2.imshow("Image A", imageA)
cv2.imshow("Image B", imageB)
cv2.imshow("Keypoint Matches", vis)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:

OpenCV全景图像拼接的实现示例

OpenCV全景图像拼接的实现示例

如遇以下错误:

cv2.error: OpenCV(3.4.3) C:\projects\opencv-python\opencv_contrib\modules\xfeatures2d\src\sift.cpp:1207: error: (-213:The function/feature is not implemented) This algorithm is patented and is excluded in this configuration; Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function ‘cv::xfeatures2d::SIFT::create'

如果运行OpenCV程序提示算法版权问题可以通过安装低版本的opencv-contrib-python解决:

pip install --user opencv-contrib-python==3.3.0.10

到此这篇关于OpenCV全景图像拼接的实现示例的文章就介绍到这了,更多相关OpenCV 图像拼接内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中定义结构体的方法
Mar 04 Python
python实现字符串和日期相互转换的方法
May 13 Python
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
简单掌握Python中glob模块查找文件路径的用法
Jul 05 Python
对python中for、if、while的区别与比较方法
Jun 25 Python
用Django写天气预报查询网站
Oct 21 Python
Django高级编程之自定义Field实现多语言
Jul 02 Python
python实现最小二乘法线性拟合
Jul 19 Python
Django文件存储 默认存储系统解析
Aug 02 Python
python 项目目录结构设置
Feb 14 Python
Python Django中的STATIC_URL 设置和使用方式
Mar 27 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
Apr 22 Python
opencv 分类白天与夜景视频的方法
python如何利用traceback获取详细的异常信息
Jun 05 #Python
Python异常类型以及处理方法汇总
Jun 05 #Python
Python OpenCV 彩色与灰度图像的转换实现
Python深度学习之实现卷积神经网络
python opencv通过4坐标剪裁图片
Jun 05 #Python
Python还能这么玩之只用30行代码从excel提取个人值班表
Jun 05 #Python
You might like
PHP中读写文件实现代码
2011/10/20 PHP
php中操作memcached缓存进行增删改查数据的实现代码
2014/08/15 PHP
php使用指定字符列表生成随机字符串的方法
2015/04/18 PHP
PDO::getAttribute讲解
2019/01/28 PHP
在你的网页中嵌入外部网页的方法
2007/04/02 Javascript
javascript之可拖动的iframe效果代码
2008/08/01 Javascript
js左侧三级菜单导航实例代码
2013/09/13 Javascript
javascript函数定义的几种区别小结
2014/01/06 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
浅析javascript函数表达式
2016/02/10 Javascript
Node.js插件安装图文教程
2016/05/06 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
2016/09/15 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
zTree获取当前节点的下一级子节点数实例
2017/09/05 Javascript
使用ECharts实现状态区间图
2018/10/25 Javascript
如何将百度地图包装成Vue的组件的方法步骤
2019/02/12 Javascript
微信小程序获取用户信息及手机号(后端TP5.0)
2019/09/12 Javascript
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
Python常见异常分类与处理方法
2017/06/04 Python
Python3爬虫爬取百姓网列表并保存为json功能示例【基于request、lxml和json模块】
2018/12/05 Python
python按修改时间顺序排列文件的实例代码
2019/07/25 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
python动态文本进度条的实例代码
2020/01/22 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
2020/02/26 Python
pytorch 中的重要模块化接口nn.Module的使用
2020/04/02 Python
离线状态下在jupyter notebook中使用plotly实例
2020/04/24 Python
详解anaconda安装步骤
2020/11/23 Python
python上下文管理器异常问题解决方法
2021/02/07 Python
HTML5中的Web Notification桌面通知功能的实现方法
2019/07/29 HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
越南母婴用品购物网站:Kids Plaza
2020/04/09 全球购物
收银员的岗位职责范本
2014/02/04 职场文书
年检委托书
2014/08/30 职场文书
2015年出纳个人工作总结
2015/04/02 职场文书
经理岗位职责范本
2015/04/15 职场文书