一起做双目测距-USB_CAMERA检测人脸距离系列(3)-三角化(三角测距)的python实现(SLAM十四讲)

本文介绍了一种使用Python实现的三角测距方法,该方法基于双目视觉原理,利用两幅图像中的对应点计算三维空间中物体的距离。通过具体实例展示了如何使用OpenCV和NumPy库进行三角化计算,最终输出物体距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三角化函数

阅读SLAM 十四讲,C++ 版本的三角化代码高翔博士已经实现了一遍,有时候因为代码需要,我们把其迁移到python上,看看python上的三角化

由于Python里面numpy用的比较多,没有C++ 的std::vector,所以用numpy数组替代vector存储二维像素点(u,v)即可:
函数如下:

# Triangulation.py
import cv2
import numpy as np
from Calib import USB_Camera

def triangulation(pointl_vec,pointr_vec,R,t,cam_matrix_left,cam_matrix_right,n):
    pointl_cam_vec = []
    pointr_cam_vec = []
    for pointl in pointl_vec:
        pointl_cam_vec.append([(pointl[0] - cam_matrix_left[0, 2]) / cam_matrix_left[0, 0],(pointl[1] - cam_matrix_left[1, 2]) / cam_matrix_left[1, 1]])
    for pointr in pointr_vec:
        pointr_cam_vec.append([(pointr[0] - cam_matrix_right[0, 2]) / cam_matrix_right[0, 0],(pointr[1] - cam_matrix_right[1, 2]) / cam_matrix_right[1, 1]])
    T1 = np.array([[1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.]])
    T2 = np.concatenate((R,t),axis=1)
    # print(T1,T2)
    pointl_cam_vec = np.array(pointl_cam_vec).transpose()
    pointr_cam_vec = np.array(pointr_cam_vec).transpose()
    # print(pointl_cam_vec)
    # print(pointr_cam_vec)

    pts_4d = np.zeros((4,n))
    cv2.triangulatePoints(T1,T2,pointl_cam_vec,pointr_cam_vec,pts_4d)
    pts_3d = []
    for i in range(n):
        x = pts_4d[0,i]/pts_4d[3,i]
        y = pts_4d[1,i]/pts_4d[3,i]
        z = pts_4d[2,i]/pts_4d[3,i]
        pts_3d.append([x,y,z])
    pts_3d = np.array(pts_3d)

    return pts_3d

相机参数类

1、首先要用这个函数,要知道传入参数的类型,这里给出一个测试实例
2、其次USB_Camera 这个类也提供如下,方便导入

# Calib.py
import numpy as np

class USB_Camera(object): 
    def __init__(self):
        # 左相机内参 及 畸变系数
        self.cam_matrix_left = np.array([[1271.71,-0.1385,376.5282],[0.,1270.87,258.1373],[0.,0.,1.]])
        self.distortion_l = np.array([[-0.5688,5.9214,-0.00038018,-0.00052731,-61.7538]])
        # 右相机内参 及 畸变系数
        self.cam_matrix_right = np.array([[1269.2524,-2.098026,367.9874],[0.,1267.1973,246.2712],[0.,0.,1.]])
        self.distortion_r = np.array([[-0.5176,2.4704,-0.0011,0.0012,-16.1715]])
        # 右边相机相对于左边相机的 旋转矩阵 R , 平移矩阵 T
        self.R = np.array([[1.0000,-0.0088,-0.0043],[0.0088,0.9999,0.0072],[0.0042,-0.0072,1.0000]])
        self.T = np.array([[-68.5321],[-0.5832],[-4.0933]])
        # 焦距
        self.focal_length = 6.00
        # 左右相机之间的距离 取 T 向量的第一维数值 单位 mm
        self.baseline = np.abs(self.T[0])

测试函数

# Test.py
from Triangulation import triangulation
from Calib import USB_Camera
import cv2
import numpy as np
# 标定摄像头,config类保存参数
config = USB_Camera()
Roi_points_right = [
[164.0, 634.0],
[257.0, 602.0],
[351.0, 524.0],
[413.0, 446.0],
[460.0, 383.0],
[117.0, 430.0],
[117.0, 336.0],
[117.0, 273.0],
[117.0, 211.0],
[179.0, 414.0],
[194.0, 273.0],
[210.0, 195.0],
[226.0, 148.0],
[241.0, 399.0],
[272.0, 258.0],
[289.0, 180.0],
[319.0, 133.0],
[304.0, 414.0],
[350.0, 304.0],
[367.0, 242.0],
[397.0, 180.0]
]
Roi_points_left = [
[351.0, 649.0],
[445.0, 618.0],
[538.0, 555.0],
[600.0, 477.0],
[647.0, 399.0],
[304.0, 446.0],
[288.0, 351.0],
[288.0, 289.0],
[289.0, 242.0],
[366.0, 430.0],
[366.0, 289.0],
[382.0, 226.0],
[398.0, 164.0],
[414.0, 414.0],
[444.0, 273.0],
[460.0, 211.0],
[476.0, 148.0],
[476.0, 430.0],
[523.0, 320.0],
[553.0, 258.0],
[569.0, 211.0]
]
pts_3d = triangulation(Roi_points_left,Roi_points_right,config.R,config.T,config.cam_matrix_left,config.cam_matrix_right,21)
pts_3d_norm=np.linalg.norm(pts_3d, axis=1, keepdims=True)

for i in range(21):
  dist = pts_3d_norm[i][0]/1000
  print("distance of point {} is {:.4f}m".format(i,dist))

实际运用过程中需要修改两个地方
1、把相机参数换成自己的
2、把像素坐标点Roi_points_left 和 Roi_points_right 修改为自己的左右图像素坐标

提示:可以先运行Test.py 看一下demo是否有Bug~
本系列全部代码,请移步 https://github.com/hitsz-zuoqi/Binoculars-tutorial
如果你感觉有用,star for me 是对我最大的鼓励

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值