非常详细的相机标定(六)(2维坐标点转为3维坐标点)

根据提取的相机的参数,2维坐标点转为3维坐标点,代码如下:

import argparse
from argparse import RawTextHelpFormatter
import numpy as np
import cv2

# 寻找焦点
def cam_calib_find_corners(img, rlt_dir, col, row):
    # 灰度化图片,减少参数的运算
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 寻找角点
    ret, corners = cv2.findChessboardCorners(gray, (col, row), None)

    # 为了得到稍微精确一点的角点坐标,进一步对角点进行亚像素寻找
    corners2 = cv2.cornerSubPix(
        gray, corners, (7, 7), (-1, -1), (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 10, 0.001))
    if ret == True:
        # 保存角点图像
        sav_path = rlt_dir + "/1_corner.jpg"
        # 绘制角点
        cv2.drawChessboardCorners(img, (col, row), corners2, ret)
        cv2.imwrite(sav_path, img)

    return (ret, corners2)

# 相机标定
def cam_calib_calibrate(img_dir, rlt_dir, col, row, img_num):
    w = 0
    h = 0
    all_corners = []
    patterns = []

    x, y = np.meshgrid(range(col), range(row))
    prod = row * col
    pattern_points = np.hstack(
        (x.reshape(prod, 1), y.reshape(prod, 1), np.zeros((prod, 1)))).astype(np.float32)

    img_path = r"C:\Users\17930\Desktop\1.jpg"
    img = cv2.imread(img_path)
    if img is None:
        print(f"Error reading image at {img_path}")
        pass
    else:
        (h, w) = img.shape[:2]
        ret, corners = cam_calib_find_corners(img, rlt_dir, col, row)
        all_corners.append(corners)
        patterns.append(pattern_points)

    rms, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(
        patterns, all_corners, (w, h), None, None)
    print('相机内参', cameraMatrix)
    print('相机外参旋转向量', rvecs)
    print('相机外参平移向量', tvecs)


    return cameraMatrix, distCoeffs, rvecs, tvecs


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="读取标定的图片并保存结果", formatter_class=RawTextHelpFormatter)
    parser.add_argument("--img_dir", help="标定图片路径", type=str,
                        metavar='', default=r'D:\螺丝数据集与相机标定代码\camera\calib_img')
    parser.add_argument("--rlt_dir", help="保存路径", type=str,
                        metavar='', default="rlt_dir")
    parser.add_argument("--crct_img_dir", help="待矫正图像路径",
                        type=str, metavar='', default="crct_img")
    parser.add_argument("--row_num", help="每一行有多少个角点,边缘处的不算",
                        type=int, metavar='', default="7")
    parser.add_argument("--col_num", help="每一列有多少个角点,边缘处的不算",
                        type=int, metavar='', default="6")
    parser.add_argument("--img_num", help="多少幅图像",
                        type=int, metavar='', default="4")

    args = parser.parse_args()
    cameraMatrix, distCoeffs, rvecs, tvecs = cam_calib_calibrate(
        args.img_dir, args.rlt_dir, args.row_num, args.col_num, args.img_num)

    image_points = np.array([[55, 66], [77, 88]], dtype=np.float32)
    world_z = 0
    world_points = []

    for i in range(len(rvecs)):
        rotation_matrix, _ = cv2.Rodrigues(rvecs[i])
        projection_matrix = np.dot(cameraMatrix, np.hstack(
            (rotation_matrix, tvecs[i])))

        inv_projection_matrix = np.linalg.pinv(projection_matrix)

        for pt in image_points:
            img_pt = np.array([pt[0], pt[1], 1])
            ray_dir = np.dot(inv_projection_matrix, img_pt)
            scale = (world_z - tvecs[i][2]) / ray_dir[2]
            world_pt = tvecs[i].reshape(3) + scale * ray_dir[:3]
            world_points.append(world_pt)

    world_points = np.array(world_points)
    print(world_points)


 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤将停车场室内三维坐标转换为大地三维坐标: 1. 假设停车场室内坐标系的原位置在大地坐标系中的经纬度为 $(\phi_0, \lambda_0)$,高程为 $h_0$。 2. 根据已知信息,可以得到停车场室内坐标系中的三个大地坐标 $(\phi_1, \lambda_1, h_1)$,$(\phi_2, \lambda_2, h_2)$,$(\phi_3, \lambda_3, h_3)$,以及它们在停车场室内坐标系中的表示 $(x_1, y_1, z_1)$,$(x_2, y_2, z_2)$,$(x_3, y_3, z_3)$。 3. 根据已知坐标计算停车场室内坐标系的三个坐标轴向量。设室内坐标系的 $x$ 轴向量为 $\vec{i}$,$y$ 轴向量为 $\vec{j}$,$z$ 轴向量为 $\vec{k}$,它们在大地坐标系中的表示分别为 $(\Delta\phi_i, \Delta\lambda_i, \Delta h_i)$。可以通过以下公式计算: $$ \begin{aligned} \vec{i} &= \frac{1}{d_1} \begin{bmatrix} x_2 - x_1 \\ y_2 - y_1 \\ z_2 - z_1 \end{bmatrix} \\ \vec{j} &= \frac{1}{d_2} \left( \begin{bmatrix} x_3 - x_1 \\ y_3 - y_1 \\ z_3 - z_1 \end{bmatrix} - \frac{\vec{i} \cdot \begin{bmatrix} x_3 - x_1 \\ y_3 - y_1 \\ z_3 - z_1 \end{bmatrix}}{d_1^2} \vec{i} \right) \\ \vec{k} &= \vec{i} \times \vec{j} \end{aligned} $$ 其中,$d_1$ 和 $d_2$ 分别为 $\vec{i}$ 和 $\vec{j}$ 的模长。 4. 计算停车场室内坐标系原在大地坐标系中的表示。设室内坐标系的原在大地坐标系中的表示为 $(\phi_0', \lambda_0', h_0')$,则可以通过以下公式计算: $$ \begin{bmatrix} \phi_0' \\ \lambda_0' \\ h_0' \end{bmatrix} = \begin{bmatrix} \phi_0 \\ \lambda_0 \\ h_0 \end{bmatrix} + \begin{bmatrix} \Delta\phi_i \\ \Delta\lambda_i \\ \Delta h_i \end{bmatrix} - \begin{bmatrix} x_1 \\ y_1 \\ z_1 \end{bmatrix} $$ 5. 将停车场室内坐标 $(x', y', z')$ 转换为大地坐标 $(\phi, \lambda, h)$。设室内坐标系中的 $(x', y', z')$ 在大地坐标系中的表示为 $(\phi', \lambda', h')$,则可以通过以下公式计算: $$ \begin{bmatrix} \phi' \\ \lambda' \\ h' \end{bmatrix} = \begin{bmatrix} \phi_0' \\ \lambda_0' \\ h_0' \end{bmatrix} + x' \vec{i} + y' \vec{j} + z' \vec{k} $$ 其中,$\vec{i}$,$\vec{j}$,$\vec{k}$ 分别为步骤 3 中计算得到的坐标轴向量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值