python opencv实现2D-2D对极几何求解位姿以及三角测量

15 篇文章 2 订阅
12 篇文章 2 订阅

使用jupyter (参考视觉SLAM十四讲第二版第七章源码)

# 查看当前kernel下已安装的包  
#!pip install opencv-python --user # opencv-python 4.5.1.48
#!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==3.4.8.29
#!pip list --format=columns

1.ORB特征点提取和配准

import cv2 as cv  ## opencv-python==3.4.8.29
import numpy as np
from  matplotlib import pyplot as plt

# 读取图片
im1 = cv.imread('./data/1.png')
im2 = cv.imread('./data/2.png')

# ORB特征提取
orb = cv.ORB_create()
kp1 = orb.detect(im1)  
kp2 = orb.detect(im2)
kp1, des1 = orb.compute(im1, kp1) # 求特征
kp2, des2 = orb.compute(im2, kp2) # 求特征
bf = cv.BFMatcher(cv.NORM_HAMMING)# 初始化Matcher
matches = bf.match(des1, des2)    # 配准
# 进行初步筛选
min_distance = 10000
max_distance = 0
for x in matches:
    if x.distance < min_distance: min_distance = x.distance
    if x.distance > max_distance: max_distance = x.distance
print('最小距离:%f' % min_distance)
print('最大距离:%f' % max_distance)
good_match = []
for x in matches:
    if x.distance <= max(2 * min_distance, 30):
        good_match.append(x)
print('匹配数:%d' % len(good_match))
outimage = cv.drawMatches(im1, kp1, im2, kp2, good_match, outImg=None)
plt.imshow(outimage[:,:,::-1])
plt.show()

2.求解位姿  估计相机运动

# 提取配准点
points1 = []
points2 = []
for i in good_match:
    points1.append(list(kp1[i.queryIdx].pt));
    points2.append(list(kp2[i.trainIdx].pt));
points1 = np.array(points1)
points2 = np.array(points2)
#em,mask = cv.findEssentialMat(points1, points2, K, cv.RANSAC, 0.999, 1.0,np.array([])) #opencv4
#em,mask = cv.findEssentialMat(points1, points2, 521, (325.1,249.7), cv.RANSAC, 0.999, 1.0,np.array([])) #opencv3
K = np.array([520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1]).reshape([3,-1]) # 相机参数
em,mask = cv.findEssentialMat(points1, points2, 521, (325.1,249.7))       # 计算本质矩阵  RANSAC
#print(em)
#print(mask)

# 求解位姿
#num,R,t,mask = cv.recoverPose( em, points1, points2, K)
num,R,t,mask = cv.recoverPose( em, points1, points2, np.array([]), np.array([]), 521, (325.1,249.7),mask) 
print(R)
print(t)

 

3.三角测量 求得配准点的深度(到相机的距离)

projMatr1 = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0]])    # 第一个相机参数
projMatr2 = np.concatenate((R, t), axis=1)               # 第二个相机参数
projMatr1 = np.matmul(K, projMatr1) # 相机内参 相机外参
projMatr2 = np.matmul(K, projMatr2) #
points4D = cv.triangulatePoints(projMatr1, projMatr2, points1.T, points2.T)
points4D /= points4D[3]       # 归一化
points4D = points4D.T[:,0:3]  # 取坐标点
print(points4D[0:5])

4.三角测量可视化(可视化深度距离)

def get_color(depth):
    up_th = 50
    low_th = 10
    th_range = up_th - low_th;
    if (depth > up_th):
        depth = up_th;
    if (depth < low_th):
        depth = low_th;
    return (255 * depth / th_range, 0, 255 * (1 - depth / th_range));

## 可视化
for i in range(points1.shape[0]):
    # 第一幅图
    im1 = cv.circle(im1, (points1[i][0].astype(int),points1[i][1].astype(int)), 10,get_color(points4D[i,2]), -1)
    # 第二幅图
    tmp_point = np.dot(R,points4D[i,:].reshape(3,1)) + t
    tmp_point = tmp_point.reshape(-1)
    im2 = cv.circle(im2, (points2[i][0].astype(int),points2[i][1].astype(int)), 10,get_color(tmp_point[2]), -1)
plt.subplot(121)
plt.imshow(im1[:,:,::-1])
plt.subplot(122)
plt.imshow(im2[:,:,::-1])
plt.show()

  • 14
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大米粥哥哥

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值