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编写一个简单的tic-tac-toe游戏的教程
Apr 16 Python
python清除字符串里非数字字符的方法
Jul 02 Python
Python实现数通设备端口使用情况监控实例
Jul 15 Python
Python中扩展包的安装方法详解
Jun 14 Python
Python基于回溯法子集树模板解决全排列问题示例
Sep 07 Python
python中使用正则表达式的后向搜索肯定模式(推荐)
Nov 11 Python
python机器学习之神经网络(三)
Dec 20 Python
解决Spyder中图片显示太小的问题
Apr 27 Python
Python中logging日志库实例详解
Feb 19 Python
解决Django no such table: django_session的问题
Apr 07 Python
Python matplotlib 绘制双Y轴曲线图的示例代码
Jun 12 Python
Python matplotlib绘制条形统计图 处理多个实验多组观测值
Apr 21 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中将ip地址转成十进制数的两种实用方法
2013/08/15 PHP
PHP防止跨域提交表单
2013/11/01 PHP
PDO::getAvailableDrivers讲解
2019/01/28 PHP
解析javascript 实用函数的使用详解
2013/05/10 Javascript
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
jQuery老黄历完整实现方法
2015/01/16 Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
2015/03/03 Javascript
JavaScript跨平台的开源框架NativeScript
2015/03/24 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
JavaScript进阶练习及简单实例分析
2016/06/03 Javascript
JS递归遍历对象获得Value值方法技巧
2016/06/14 Javascript
Angular.js组件之input mask对input输入进行格式化详解
2017/07/10 Javascript
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
vue 解决setTimeOut和setInterval函数无效报错的问题
2020/07/30 Javascript
JavaScript 空间坐标的使用
2020/08/19 Javascript
[01:13:46]iG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
Visual Studio code 配置Python开发环境
2020/09/11 Python
浅析Python requests 模块
2020/10/09 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
canvas仿写贝塞尔曲线的示例代码
2017/12/29 HTML / CSS
香港现代设计家具品牌:Ziinlife Furniture
2018/11/13 全球购物
便利店的创业计划书
2014/01/15 职场文书
十八大感想感言
2014/02/10 职场文书
英文升职感谢信
2015/01/23 职场文书
万能检讨书
2015/01/27 职场文书
2015年三万活动总结
2015/03/25 职场文书
初中团委工作总结
2015/08/13 职场文书
2019安全宣传标语大全
2019/08/14 职场文书
如何在向量化NumPy数组上进行移动窗口
2021/05/18 Python
spring cloud gateway中如何读取请求参数
2021/07/15 Java/Android
Python编程super应用场景及示例解析
2021/10/05 Python