ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

[SLAM] opencv-python的3D-2D视觉里程计(参考高老师的视觉slam十四讲)

2021-09-05 14:33:40  阅读:273  来源: 互联网

标签:distance kp2 img kp1 python 里程计 matches 视觉 orb


目录

项目场景

项目参照高老师的《视觉SLAM十四讲》进行实现,主要是为了巩固自己知识,代码仅供参考。

直接上代码

需要注意的是,代码opencv的版本是3.4.2.16(4版本的opencv太新了,好像不兼容),此外,在主函数里面,需要输入自己的图片哦!

import numpy as np
import cv2 as cv

def find_feature_matches(img_1, img_2):
    """寻找特征匹配的点

    Args:
        img_1: pass
        img_2: pass

    Returns:
        kp1: 
        kp2: 
        good_match: 

    """
    orb = cv.ORB_create()

    kp1 = orb.detect(img_1)
    kp2 = orb.detect(img_2)

    kp1, des1 = orb.compute(img_1, kp1)
    kp2, des2 = orb.compute(img_2, kp2)

    bf = cv.BFMatcher(cv.NORM_HAMMING)

    matches = bf.match(des1, des2)

    min_distance = matches[0].distance
    max_distance = matches[0].distance

    for x in matches:
        if x.distance < min_distance:
            min_distance = x.distance
        if x.distance > max_distance:
            max_distance = x.distance
    
    print("Max dist:", max_distance)
    print("Min dist:", min_distance)

    good_match = []

    for x in matches:
        if x.distance <= max(2*min_distance, 30.0):
            good_match.append(x)

    return kp1, kp2, good_match


if __name__ == "__main__":
    img1 = cv.imread("1.png")
    img2 = cv.imread("2.png")
    depth1 = cv.imread("1_depth.png", -1) # 读取深度图像要用-1
    depth2 = cv.imread("2_depth.png", -1)

    # 图像匹配
    keypoints_1, keypoints_2, matches = find_feature_matches(img1, img2)
    print("共计匹配点:", len(matches))

    # 筛选特征点,只记匹配的点,参照上一博客的poes_estimation_2d2d(keypoint_1, keypoint_2, matches)函数
    pts2 = []
    pts1 = []
    for i in range(int(len(matches))):
        pts1.append(keypoints_1[matches[i].queryIdx].pt)
        pts2.append(keypoints_2[matches[i].trainIdx].pt)
    pts1 = np.int32(pts1)
    pts2 = np.int32(pts2)

    # 建立3D点
    # 深度图像为16位无符号数,单通道图像
    K=[[520.9, 0, 325.1], [0, 521.0, 249.7], [0, 0, 1]]
    K=np.array(K)
    pts_3d = []
    pts_2d = []
    for i in range(pts1.shape[0]): # pts1.shape[0]: 匹配点总数  pts1.shape = (len(matches), 2)
        p1 = pts1[i]
        d1 = depth1[p1[1],p1[0]]/1000.0 # 深度距离  以5000为一个单位 高博的是1000.0
        #print(d1)
        if d1 == 0: 
            continue
        p1 = (p1 - (K[0][2],K[1][2]))/(K[0][0],K[1][1])*d1 # 归一化坐标 根据深度单位转为实际坐标
        pts_3d.append([p1[0], p1[1], d1])
        pts_2d.append(pts2[i])

    # 
    print("最终匹配数:", len(pts_3d))
    pts_3d = np.float64(pts_3d)
    pts_2d = np.float64(pts_2d)
    print("3D点:")
    print(pts_3d)

    flag,R,t = cv.solvePnP(pts_3d,pts_2d,K,None)
    R,Jacobian  = cv.Rodrigues(R)
    print("旋转矩阵R:\n", R)
    print("平移矩阵t:\n", t)

实验

最终输出的两个矩阵与上一篇的博客的结果有点区别,旋转矩阵基本上对上了,但是平移矩阵,都有差别,不管是与上一篇博客的还是与高博的
在这里插入图片描述

标签:distance,kp2,img,kp1,python,里程计,matches,视觉,orb
来源: https://blog.csdn.net/qq_39502099/article/details/120114102

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有