opencv学习:图像拼接及完整代码实现

概念

图像拼接是计算机视觉领域中的一项技术,它涉及将多个图像合并成一个连续的、无缝的全景图像。在OpenCV中,图像拼接通常包括以下几个关键步骤:

1. 编写代码
  • 导入必要的库 :导入syscv2numpy库。

  • 定义显示图像的函数 :编写cv_show函数,用于在窗口中显示图像。

    python 复制代码
    import sys
    import cv2
    import numpy as np
    # 显示图像的函数
    def cv_show(name,img):
        cv2.imshow(name,img)
        cv2.waitKey(0)
  • 定义检测关键点和计算描述符的函数 :编写detectAndDescribe函数,使用SIFT算法检测图像中的关键点并计算描述符。

    python 复制代码
    # 检测关键点并计算描述符的函数
    def detectAndDescribe(image):
        gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        desciiptor=cv2.SIFT_create()#创建SIFT描述
        #检测关键点并计算描述符
        (kps,des)=desciiptor.detectAndCompute(gray,None)#kps 是检测到的关键点的列表,des 是关键点的描述符矩阵。
        kps_float=np.float32([kp.pt for kp in kps])#转换关键点坐标为浮点数:
        return (kps,kps_float,des)
2. 读取图像
  • 使用cv2.imread函数读取left.jpgright.jpg图像。

    python 复制代码
    imageA=cv2.imread('left.jpg')
    imageB=cv2.imread('right.jpg')
3. 检测关键点和计算描述符
  • 对两幅图像分别调用detectAndDescribe函数,获取关键点和描述符。

    python 复制代码
    #检测关键点并计算描述符
    (kpsA,kps_floatA,desA)=detectAndDescribe(imageA)
    (kpsB,kps_floatB,desB)=detectAndDescribe(imageB)
4. 特征匹配
  • 创建匹配器 :使用cv2.BFMatcher创建暴力匹配器。

  • 进行K近邻匹配:对两幅图像的描述符进行K近邻匹配,获取匹配点对。

  • 筛选好的匹配点 :使用Lowe's ratio test筛选出好的匹配点。

    python 复制代码
    #创建匹配器
    matcher=cv2.BFMatcher()
    #进行K近邻匹配
    rawMatches=matcher.knnMatch(desB,desA,2)
    good=[]
    matches=[]
    for m in rawMatches:
    
        if len(m)==2 and m[0].distance<0.65*m[1].distance:
            good.append(m)
            matches.append((m[0].trainIdx,m[0].queryIdx))
5. 计算单应性矩阵
  • 检查匹配点数量:如果匹配点数量大于4,则继续;否则,程序退出。

  • 计算单应性矩阵 :使用cv2.findHomography函数和RANSAC算法计算匹配点之间的单应性矩

    python 复制代码
    #左侧连接
    # 如果匹配点足够多,则进行下一步
    if len(matches)>4:
        ptsA=np.float32([kps_floatA[i] for (i,_) in matches])
        ptsB=np.float32([kps_floatB[i] for (_,i) in matches])
        # 使用RANSAC算法计算单应性矩阵
        (H,mask)=cv2.findHomography(ptsB,ptsA,cv2.RANSAC,10)
    else:
        sys.exit()

    阵。

6. 图像变换和拼接
  • 应用单应性矩阵 :使用cv2.warpPerspective函数对右图进行透视变换。

  • 显示变换后的图像 :调用cv_show函数显示变换后的图像。

  • 拼接图像:将左图拼接到变换后的右图上。

  • 显示最终结果 :调用cv_show函数显示最终的拼接结果。

    python 复制代码
    # 应用单应性矩阵进行透视变换
    result=cv2.warpPerspective(imageB,H,(imageB.shape[1]+imageA.shape[1],imageB.shape[0]))
    cv_show('resultB',result)
    # 将左图拼接到结果图像上
    result[0:imageA.shape[0],0:imageA.shape[1]]=imageA
    cv_show('result',result)
7. 可视化匹配的关键点
python 复制代码
# 使用drawMatchesKnn函数绘制匹配的关键点
vis=cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('keypoint',vis)

运行结果

完整代码

python 复制代码
# 图像拼接
import sys
import cv2
import numpy as np
# 显示图像的函数
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)

# 检测关键点并计算描述符的函数
def detectAndDescribe(image):
    gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    desciiptor=cv2.SIFT_create()#创建SIFT描述
    #检测关键点并计算描述符
    (kps,des)=desciiptor.detectAndCompute(gray,None)#kps 是检测到的关键点的列表,des 是关键点的描述符矩阵。
    kps_float=np.float32([kp.pt for kp in kps])#转换关键点坐标为浮点数:
    return (kps,kps_float,des)

imageA=cv2.imread('left.jpg')
imageB=cv2.imread('right.jpg')
#检测关键点并计算描述符
(kpsA,kps_floatA,desA)=detectAndDescribe(imageA)
(kpsB,kps_floatB,desB)=detectAndDescribe(imageB)
#创建匹配器
matcher=cv2.BFMatcher()
#进行K近邻匹配
rawMatches=matcher.knnMatch(desB,desA,2)
good=[]
matches=[]
for m in rawMatches:

    if len(m)==2 and m[0].distance<0.65*m[1].distance:
        good.append(m)
        matches.append((m[0].trainIdx,m[0].queryIdx))
# print(len(good))
# print(matches)
# 使用drawMatchesKnn函数绘制匹配的关键点
vis=cv2.drawMatchesKnn(imageB,kpsB,imageA,kpsA,good,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv_show('keypoint',vis)
#左侧连接
# 如果匹配点足够多,则进行下一步
if len(matches)>4:
    ptsA=np.float32([kps_floatA[i] for (i,_) in matches])
    ptsB=np.float32([kps_floatB[i] for (_,i) in matches])
    # 使用RANSAC算法计算单应性矩阵
    (H,mask)=cv2.findHomography(ptsB,ptsA,cv2.RANSAC,10)
else:
    sys.exit()
# 应用单应性矩阵进行透视变换
result=cv2.warpPerspective(imageB,H,(imageB.shape[1]+imageA.shape[1],imageB.shape[0]))
cv_show('resultB',result)
# 将左图拼接到结果图像上
result[0:imageA.shape[0],0:imageA.shape[1]]=imageA
cv_show('result',result)
相关推荐
南宫生2 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__2 小时前
Web APIs学习 (操作DOM BOM)
学习
数据的世界014 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐4 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
菜狗woc5 小时前
opencv-python的简单练习
人工智能·python·opencv
paixiaoxin6 小时前
CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究
人工智能·深度学习·机器学习·生成对抗网络·计算机视觉·ocr·.net
西猫雷婶6 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
OopspoO7 小时前
qcow2镜像大小压缩
学习·性能优化
AI视觉网奇7 小时前
人脸生成3d模型 Era3D
人工智能·计算机视觉
A懿轩A7 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列