【图像拼接】

import cv2
import numpy as np
if __name__=='__main__':
    #1.读入图片
    imageA = cv2.imread('left.png')
    imageB = cv2.imread('right.png')

    #2.转换为灰度图
    gray1 = cv2.cvtColor(imageA,cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

    #3.构造sift对象,求解特征点和sift特征向量
    sift=cv2.SIFT_create()

    # 有两个必须的参数,第一个是求解特征点和特征向量的图像。第二个参数决定是否对特定区域求解
    # 返回值kps是对图像求解的特征点(keypoints),是一个一维向量,其中每一个元素属于keypoint类型。
    # dp是与kps对应的特征向量,也是一个列表,其中每一个元素是长度为128的向量.
    #求解keypoint和描述子
    kpsA, dpA = sift.detectAndCompute(gray1, None)
    kpsB, dpB = sift.detectAndCompute(gray2, None)
    # print(type(kpsA))
    # print(type(kpsA[0]))
    # print(type(dpA))
    # print(dpA.shape)

    #4.构造BFMatcher对象,用暴力匹配的方式寻找匹配点
    bf=cv2.BFMatcher()

    #5.用KnnMatch方法匹配关键点
    #返回的列表元素是一组包含两个特征点匹配的列表,
    # 其中第一个特征点是查询图片(dpA)中的,第二个特征点是训练图片(dpB)中的。
    # 这里的k值为2,因此每个查询点最多可以与两个训练点进行匹配。
    matches=bf.knnMatch(dpA,dpB,2)
    # print(matches)

    #6.手动去除不可靠匹配
    # 用于存储好的匹配点的下标
    good_matches=[]
    for m in matches:
        # print(m)
        # print(m[0])
        if len(m)==2 and m[0].distance<0.4*m[1].distance:
            """每个匹配对都由两个元素组成:第一个元素是query image中关键点的索引,
             第二个元素是train(即reference) image中关键点的索引"""
            # print(m[0].queryIdx, m[0].trainIdx)
            good_matches.append((m[0].queryIdx,m[0].trainIdx))
    # print((good_matches))

    #7.将可靠的匹配转换数据类型
    """将在变量kpsA中的所有关键点(Keypoint)的位置(即坐标)
    提取出来,并存储为一个浮点数类型的Numpy数组kps1"""
    kps1=np.float32([kp.pt for kp in kpsA]) #求出所有关键点的x,y坐标
    kps2 = np.float32([kp.pt for kp in kpsB])
    # print(kps1)
    # print(kps1[592,:])

    kps1 = np.float32([kps1[a[0]] for a in good_matches])#求出可靠匹配的x,y坐标
    kps2 = np.float32([kps2[a[1]] for a in good_matches])
    # print(kps1[0])
    # print(kps2[0])
    # print(kps1)
    # print(kps2)

    #8.求解转换矩阵
    M,status=cv2.findHomography(kps2,kps1,cv2.RANSAC,4.0)
    # print(M)

    #9.拼接图像
    """这行代码使用OpenCV库中的函数cv2.warpPerspective()对图像imageB进行透视变换,
    使其与另一幅图像imageA对齐,并将结果保存在result变量中。M是一个3×3的变换矩阵,用于
    指定图像的变换方式。这个变换可以将imageB上每个点的像素位置映射到result图像的新位置,
    从而实现图像的拼接或其他形式的处理。具体地,这里将result图像的宽度设置为imageA和imageB
    的宽度之和,高度设置为imageB的高度,以确保两张图像都可以完整地显示在result中。"""
    result=cv2.warpPerspective(imageB,M,(imageA.shape[1]+imageB.shape[1],imageB.shape[0]))
    cv2.imshow('Result', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    """这段代码是将名为imageA的图像复制到名为result的图像的左上角位置。具体来说,它将result
    的第一行到imageA的行数和第一列到imageA的列数的区域(即左上角)替换为imageA的像素值。这通
    常用于图像拼接、覆盖或合并操作中。"""
    result[0:imageA.shape[0],0:imageA.shape[1]]=imageA

    cv2.imshow('Result',result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值