(记录)单双目相机标定及三角测量实现(Python OpenCV)

参考https://temugeb.github.io/opencv/python/2021/02/02/stereo-camera-calibration-and-triangulation.html

各标定步骤实现方法 1 计算标靶平面与图像平面之间的映射矩阵 计算标靶平面与图像平面之间的映射矩阵,计算映射矩阵时不考虑摄像机的成像模型,只是根据平面标靶坐标点和对应的图像坐标点的数据,利用最小二乘方法计算得到[ [ix] ] .2 求解摄像机参数矩阵 由计算得到的标靶平面和图像平面的映射矩阵得到与摄像机内部参数相关的基本方程关系,求解方程得到摄像机内部参数,考虑镜头的畸变模型,将上述解方程获 得的内部参数作为初值,进行非线性优化搜索,从而计算出所有参数的准确值 [[x] ] .3 求解左右两摄像机之间的相对位置关系 设双目视觉系统左右摄像机的外部参数分别为Rl, Tl,与Rr, Tr,,即Rl, Tl表示左摄像机与世界坐标系的相对位置,Rr, Tr表示右摄像机与世界坐标系的相对位置 [[xi] ]。因此,对于空间任意一点,如果在世界坐标系、左摄像机坐标系和右摄像机坐标系中的坐标分别为Xw,, Xl , Xr,则有:Xl=RlXw+Tl ;Xr=RrXw+Tr .因此,两台摄像机之间的相对几何关系可以由下式表示R=RrRl-1 ;T=Tr- RrRl-1Tl 在实际标定过程中,由标定靶对两台摄像机同时进行摄像标定,以分别获得两台摄像机的内、外参数,从而不仅可以标定出摄像机的内部参数,还可以同时标定出双目视觉系统的结构参数 [xii] 。由摄像机标定过程可以知道,标定靶每变换一个位置就可以得到一组摄像机外参数:Rr,Tr,与Rl, Tl,因此,由公式R=RrRl-1 ;T=Tr- RrRl-1Tl,可以得到一组结构参数R和T
使用三角测量方法计算双目相机特征点的世界坐标,需要用到相机内外参以及左右两个相机的特征点对应关系。 下面是一个简的示例代码,用于计算双目相机中的特征点的世界坐标: ``` import cv2 import numpy as np # 读取图像和标定参数 img_left = cv2.imread('left.jpg') img_right = cv2.imread('right.jpg') K_left = np.array([[fx_left, 0, cx_left], [0, fy_left, cy_left], [0, 0, 1]]) # 左相机内部参数矩阵 dist_left = np.array([k1_left, k2_left, p1_left, p2_left, k3_left]) # 左相机畸变参数 K_right = np.array([[fx_right, 0, cx_right], [0, fy_right, cy_right], [0, 0, 1]]) # 右相机内部参数矩阵 dist_right = np.array([k1_right, k2_right, p1_right, p2_right, k3_right]) # 右相机畸变参数 R = np.array([[r11, r12, r13], [r21, r22, r23], [r31, r32, r33]]) # 旋转矩阵 T = np.array([[tx], [ty], [tz]]) # 平移向量 # 检测特征点 detector = cv2.SIFT_create() kp_left = detector.detect(img_left) kp_right = detector.detect(img_right) # 计算特征点对应关系 matcher = cv2.BFMatcher() matches = matcher.match(des_left, des_right) # des_left和des_right是特征点的描述子 # 计算三维点云 points_3d = [] for match in matches: # 计算左右相机的相机坐标 pt_left = np.array([kp_left[match.queryIdx].pt], dtype=np.float32) pt_right = np.array([kp_right[match.trainIdx].pt], dtype=np.float32) pts_left, _ = cv2.projectPoints(pt_left, np.zeros((3,1)), np.zeros((3,1)), K_left, dist_left) pts_right, _ = cv2.projectPoints(pt_right, np.zeros((3,1)), np.zeros((3,1)), K_right, dist_right) # 三角测量计算世界坐标 pt_4d_homogeneous = cv2.triangulatePoints(projMatr1=np.hstack((R, T)), projMatr2=np.hstack((np.identity(3), np.zeros((3, 1)))), projPoints1=pts_left.T, projPoints2=pts_right.T) pt_3d = pt_4d_homogeneous[:3] / pt_4d_homogeneous[3] points_3d.append(pt_3d) points_3d = np.array(points_3d) # 将三维点云转换到世界坐标系下 points_3d_homogeneous = np.hstack((points_3d, np.ones((points_3d.shape[0], 1)))) points_3d_in_world = np.dot(R, points_3d_homogeneous.T) + T points_3d_in_world = points_3d_in_world.T print(points_3d_in_world) # 输出所有特征点的世界坐标 ``` 这只是一个简的示例,实际情况下可能需要进行更复杂的计算和处理。注意,上述代码中的描述子是通过SIFT算法获取的,如果您使用的是其他的特征点算法,需要对应修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值