博客
关于我
双目测距 实践记录
阅读量:205 次
发布时间:2019-02-28

本文共 4785 字,大约阅读时间需要 15 分钟。

双目相机标定与深度计算方法

前言

双目相机标定是一项重要的前沿技术,广泛应用于机器人、自动驾驶和3D重建等领域。该方法通过同时捕捉左右两摄像头的图像,利用几何和光学知识,计算出相机的内外参数,并最终生成深度图。本文将详细介绍双目相机标定的实现过程及深度计算方法。

原理介绍

双目相机标定基于几何学和光学学的原理。通过捕捉左右两摄像头的图像,计算出两摄像头的内外参数,进而求解两个相机的相对位置和方向。这种方法通常采用标定板作为校准目标,通过识别标定板上的角点,计算出相机的内参数(如焦距、中心点)和畸变参数。

实现教程

一、左右摄像头同时拍照并保存于本地

  • 固定好左右相机,使用棋盘标定图进行拍摄。建议左右相机各拍摄15张图像,总图像数为30-40张。
  • 编写相应的程序,例如使用C++或Python,调用摄像头并保存图像。以下是一个示例代码:
  • #include 
    #include
    #include
    #include
    using namespace std;using namespace cv;// 单次拍摄并保存图像void captureImages() { Mat frame, frame1; bool stop = false; while (!stop) { cap.read(frame); cap1.read(frame1); imshow("camera0", frame); imshow("camera1", frame1); int delay = 30; if (delay >= 0 && waitKey(delay) >= 0) { waitKey(0); } imwrite("left1.jpg", frame1); imwrite("right1.jpg", frame); } cap.release(); cap1.release();}

    二、单目标定

    单目标定是双目标定的基础步骤。通过单目标定计算出每个相机的内参数。以下是一个单目标定代码示例:

    #include "opencv2/core/core.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/calib3d/calib3d.hpp"#include "opencv2/highgui/highgui.hpp"using namespace std;using namespace cv;// 单目相机标定void guessCameraParam() {    // 相机内参数    intrinsic.create(3, 3, CV_64FC1);    distortion_coeff.create(5, 1, CV_64FC1);    // 示例内参数值(需根据实际相机测量得出)    intrinsic.at
    (0, 0) = 256.8093262; // fx intrinsic.at
    (0, 2) = 160.2826538; // cx intrinsic.at
    (1, 1) = 254.7511139; // fy intrinsic.at
    (1, 2) = 127.6264572; // cy // 示例畸变参数(需根据实际相机测量得出) distortion_coeff.at
    (0, 0) = -0.193740; // k1 distortion_coeff.at
    (1, 0) = -0.378588; // k2 distortion_coeff.at
    (2, 0) = 0.028980; // p1 distortion_coeff.at
    (3, 0) = 0.008136; // p2}

    三、双目标定

    双目标定是基于单目标定的基础上,结合左右两个相机的数据,计算出两相机的相对位置和外参数。以下是一个双目标定代码示例:

    #include "opencv2/core/core.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/calib3d/calib3d.hpp"#include "opencv2/highgui/highgui.hpp"using namespace std;using namespace cv;// 双目相机标定void stereoCalibrate() {    // 输入参数    vector
    objPoints; // 标定板实际坐标 vector
    leftPoints; // 左相机角点坐标 vector
    rightPoints; // 右相机角点坐标 // 输出参数 Mat cameraMatrixL, cameraMatrixR; // 相机内参数矩阵 Mat distCoeffL, distCoeffR; // 相机畸变参数 vector
    rvecs, tvecs; // 旋转向量和平移向量 // 示例参数值(需根据实际测量得出) cameraMatrixL.create(3, 3, CV_64FC1); cameraMatrixR.create(3, 3, CV_64FC1); distCoeffL.create(5, 1, CV_64FC1); distCoeffR.create(5, 1, CV_64FC1); // 示例内参数值(需根据实际相机测量得出) cameraMatrixL.at
    (0, 0) = 462.279595; // fx cameraMatrixL.at
    (1, 1) = 460.220741; // fy cameraMatrixL.at
    (0, 2) = 312.781587; // cx cameraMatrixL.at
    (1, 2) = 208.225803; // cy // 示例畸变参数(需根据实际相机测量得出) distCoeffL.at
    (0, 0) = -0.054929; // k1 distCoeffL.at
    (1, 0) = 0.224509; // k2 distCoeffL.at
    (2, 0) = 0.000386; // p1 distCoeffL.at
    (3, 0) = 0.001799; // p2 distCoeffL.at
    (4, 0) = -0.302288; // k3 // 示例右相机参数 cameraMatrixR.at
    (0, 0) = 463.923124; // fx cameraMatrixR.at
    (1, 1) = 462.203276; // fy cameraMatrixR.at
    (0, 2) = 322.783959; // cx cameraMatrixR.at
    (1, 2) = 256.100655; // cy // 示例畸变参数(需根据实际相机测量得出) distCoeffR.at
    (0, 0) = -0.049056; // k1 distCoeffR.at
    (1, 0) = 0.229945; // k2 distCoeffR.at
    (2, 0) = 0.001745; // p1 distCoeffR.at
    (3, 0) = -0.001862; // p2 distCoeffR.at
    (4, 0) = -0.321533; // k3 // 标定板实际坐标(需根据实际标定板得出) for (int i = 0; i < 15; i++) { Point3f point(i * 25, i * 25, 0); objPoints.push_back(point); }}

    四、深度计算

    通过双目标定得到的外参数和深度函数,可以计算出深度图。以下是一个深度计算代码示例:

    import numpy as npimport cv2# 假设已经完成双目标定,得到了Q矩阵Q = np.array([    [1, 0, 0, 0],    [0, 1, 0, 0],    [0, 0, 1, 0]], dtype=np.float32)# 读取左右两摄像头图像left_img = cv2.imread("left.jpg")right_img = cv2.imread("right.jpg")# remap图像到校正后的图像rectified_left = cv2.remap(left_img, camera_configs.left_map1, camera_configs.left_map2, cv2.INTER_LINEAR)rectified_right = cv2.remap(right_img, camera_configs.right_map1, camera_configs.right_map2, cv2.INTER_LINEAR)# 将图像转换为灰度格式gray_left = cv2.cvtColor(rectified_left, cv2.COLOR_BGR2GRAY)gray_right = cv2.cvtColor(rectified_right, cv2.COLOR_BGR2GRAY)# 调节trackbar参数num = cv2.getTrackbarPos("num", "depth")blockSize = cv2.getTrackbarPos("blockSize", "depth")# 计算深度图stereo = cv2.StereoBM_create(numDisparities=16 * num, blockSize=blockSize)disparity = stereo.compute(gray_left, gray_right)# 调整深度图disp = cv2.normalize(disparity, disparity, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)# 生成深度图像depth = cv2.reprojectImageTo3D(disparity.astype(np.float32) / 16., Q)# 显示结果cv2.imshow("depth", disparity)cv2.waitKey(1)# 释放资源camera1.release()camera2.release()cv2.destroyAllWindows()

    总结

    通过以上步骤,可以实现双目相机标定并生成深度图。虽然精度有限,但在实际应用中已经足够使用。

    转载地址:http://agpi.baihongyu.com/

    你可能感兴趣的文章
    NIFI1.21.0_java.net.SocketException:_Too many open files 打开的文件太多_实际操作---大数据之Nifi工作笔记0051
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_插入时如果目标表中已存在该数据则自动改为更新数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0058
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_更新时如果目标表中不存在记录就改为插入数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0059
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0_Postgresql和Mysql同时指定库_指定多表_全量同步到Mysql数据库以及Hbase数据库中---大数据之Nifi工作笔记0060
    查看>>
    NIFI1.21.0最新版本安装_连接phoenix_单机版_Https登录_什么都没改换了最新版本的NIFI可以连接了_气人_实现插入数据到Hbase_实际操作---大数据之Nifi工作笔记0050
    查看>>
    NIFI1.21.0最新版本安装_配置使用HTTP登录_默认是用HTTPS登录的_Https登录需要输入用户名密码_HTTP不需要---大数据之Nifi工作笔记0051
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增加修改实时同步_使用JsonPath及自定义Python脚本_03---大数据之Nifi工作笔记0055
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_插入修改删除增量数据实时同步_通过分页解决变更记录过大问题_01----大数据之Nifi工作笔记0053
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表或全表增量同步_实现指定整库同步_或指定数据表同步配置_04---大数据之Nifi工作笔记0056
    查看>>
    NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现update数据实时同步_实际操作05---大数据之Nifi工作笔记0044
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_生成插入Sql语句_实际操作02---大数据之Nifi工作笔记0041
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_不带分页处理_01_QueryDatabaseTable获取数据_原0036---大数据之Nifi工作笔记0064
    查看>>