阿雪的学习记录|图片拼接python代码解读

继上一篇文章,代码解读来了
代码还是来自这篇博客
复制过来好了,解读在里边的注释上,不单拎出来一条条解释了,不方便对应

import cv2
import numpy as np

img1 = cv2.imread(r'C:\Users\Bai\Desktop\p2.jpg')
img2 = cv2.imread(r'C:\Users\Bai\Desktop\p1.jpg')

# img1 = cv2.resize(img1, (640, 480))
# img2 = cv2.resize(img2, (640, 480))

input = np.hstack((img1, img2))
cv2.imwrite(r'C:\Users\Bai\Desktop\p2p1.jpg',input)
cv2.imshow('input', input)
cv2.waitKey(0)

def get_homo(img1, img2):
    # 1实现实例化图片,就是为对象开辟内存空间
    sift = cv2.xfeatures2d.SIFT_create()
    
    # 2实现计算出图像的关键点和sift特征向量,所以关键点是k,特征向量是p1
    k1, p1 = sift.detectAndCompute(img1, None)
    k2, p2 = sift.detectAndCompute(img2, None)
    
    # 3实现建立匹配关系
    bf = cv2.BFMatcher()
    # 4实现返回两个DMatch类型,是两个与原图像特征点最接近的两个特征点,
    # 这两个特征点的欧氏距离小于一定值才会匹配成功,所以这个2就是那个一定值?
    matches = bf.knnMatch(p1, p2, k=2)
    # 5实现昂,当m1的距离小于0.8倍m2时,被过滤为有效特征点,都添加到good后面
    good = []
    for m1, m2 in matches:
        if m1.distance < 0.8 * m2.distance:
            good.append(m1)
            
    # 6实现单应性矩阵计算,单应性矩阵就是尺度因子*内参*外参,
    #最后算出来的就是物体在世界坐标系和像素坐标系之间的位置映射关系
    #findHomography计算多个二维点对之间的最优单映射变换矩阵H
    if len(good) > 8:
        img1_pts = []
        img2_pts = []
        for m in good:
            img1_pts.append(k1[m.queryIdx].pt)
            img2_pts.append(k2[m.trainIdx].pt)
        img1_pts = np.float32(img1_pts).reshape(-1, 1, 2)
        img2_pts = np.float32(img2_pts).reshape(-1, 1, 2)
        H, mask = cv2.findHomography(img1_pts, img2_pts, cv2.RANSAC, 5.0)
        return H
    else:
        print('piints is not enough 8!')
        exit()

def stitch_img(img1, img2, H):
    # 1实现获得图像的四个角点坐标,对的,就是用高和宽,也就是图片的形状shape,
    #shape的三个参数为(高,宽,通道数),高和宽对应着行数和列数,通道数一般为3,RGB嘛因为
    #shape[:2]就是前两个参数的意思
    h1, w1 = img1.shape[:2]
    h2, w2 = img2.shape[:2]
    
    img1_point = np.float32([[0,0], [0,h1], [w1,h1], [w1,0]]).reshape(-1, 1, 2)
    img2_point = np.float32([[0,0], [0,h2], [w2,h2], [w2,0]]).reshape(-1, 1, 2)
    # 2实现根据单映射变换矩阵H对img1_point进行变换,是对图1的变换
    img1_trans = cv2.perspectiveTransform(img1_point, H)
    # 将img1变换后的角点与img2原来的角点做拼接
    result_point = np.concatenate((img2_point, img1_trans), axis=0)
    # 获得拼接后图像x,y的最小值
    [x_min, y_min] = np.int32(result_point.min(axis=0).ravel()-0.5)
    # 获得拼接后图像x,y的最大值
    [x_max, y_max] = np.int32(result_point.max(axis=0).ravel()+0.5)
    # 平移距离
    trans_dist = [-x_min, -y_min]
    # 构建一个齐次平移矩阵
    trans_array = np.array([[1, 0, trans_dist[0]],
                            [0, 1, trans_dist[1]],
                            [0, 0, 1]])
    # 这里是我新加的输出,第一个是输出单应性平移变换矩阵HT,也就是单映射变换矩阵H+齐次平移矩阵T,
    # 第二个是输出单映射变换矩阵
    # 第三个输出齐次平移矩阵
    # 第四个输出HT的行列式
    # 第五个输出H的行列式
    # 注:这里的输出仅为个人研究需要
    print(trans_array.dot(H))
    print(H)
    print(trans_array)
    print(np.linalg.det(trans_array.dot(H)))
    print(np.linalg.det(H))
    # 平移和单应性变换函数cv2.warpPerspective
    #对1图进行平移和单应性变换(输入的图像,输出的图像(可略),透视变换的单应性平移矩阵H,输出图像的大小)
    #所以上面获取拼接后图像的最大最小值就是为了确定拼接后的图片的尺寸!
    res_img = cv2.warpPerspective(img1, trans_array.dot(H), (x_max-x_min, y_max-y_min))
    # 3实现把图2覆盖在图1上,所以如果颠倒图片顺序,生成的结果也会不一样
    res_img[trans_dist[1]:trans_dist[1]+h2,
            trans_dist[0]:trans_dist[0]+w2] = img2
    return res_img

H = get_homo(img1, img2)
res_img = stitch_img(img1, img2, H)
# 4实现 显示拼接结果,保存拼接结果
cv2.imshow('result', res_img)
cv2.imwrite(r'C:\Users\Bai\Desktop\p2-p1.jpg',res_img)
cv2.waitKey(0) 

我什么时候才能像有些大佬一样用英文写学习笔记啊……感觉就只有我在给代码加一行一行又一行的中文白话文,罢了罢了

总之这个代码可以直接复制到spyder运行,还是两部分,第一张图片连接的结果显示出来之后任意键开始图片拼接,如果是用手机拍的那种大分辨率照片(比如我的竖屏尺寸是3120x4160),就会有点点慢,单纯想粗略看看运行效果的话就把开头resize那两行的注释取消掉,resize成你想要的大小,就会运行的快点了,记得修改图片路径、连接和拼接的路径哦!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Matlab中,你可以使用scatter函数来绘制散点图,使用convhulln函数来计算凸包的坐标,然后使用patch函数将坐标点连接成面,形成包络图。下面是一个示例代码: ```matlab A = importdata('E:\各种数据集\220417\y001.txt'); B = importdata('E:\各种数据集\220417\001yy.txt'); Ax = A(:, 1); Ay = A(:, 2); Az = A(:, 3); Bx = B(:, 1); By = B(:, 2); Bz = B(:, 3); figure; scatter3(Ax, Ay, Az, 'filled', 'MarkerFaceColor', 'r'); hold on; scatter3(Bx, By, Bz, 'filled', 'MarkerFaceColor', 'b'); f = convhulln(A); patch('vertices', A, 'faces', f, 'facecolor', 'r', 'FaceAlpha', 0.3); f1 = convhulln(B); patch('vertices', B, 'faces', f1, 'facecolor', 'b', 'FaceAlpha', 0.3); axis equal; xlabel('X'); ylabel('Y'); zlabel('Z'); title('散点图绘制包络图'); ``` 这段代码会将两组数据点A和B绘制成散点图,并使用convhulln函数计算出A和B的凸包坐标,然后使用patch函数将凸包坐标连接成面,形成包络图。你可以根据自己的数据文件路径进行修改。 #### 引用[.reference_title] - *1* [阿雪学习记录|MATLAB绘制三维离散点包络体](https://blog.csdn.net/baixue1183/article/details/125013589)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值