• 棋盘格测距-单目相机(OpenCV/C++)


    一、文章内容简述:

    1’ 通过cv::findChessboardCorners寻找棋盘格角点

    2‘ 用cv::solvePnP计算旋转向量rvec和平移向量tvec

    3’ 通过公式计算相机到棋盘格的距离

    float distance = sqrt(tvec.at<double>(0,0) * tvec.at<double>(0,0) + tvec.at<double>(1,0) * tvec.at<double>(1,0) + tvec.at<double>(2,0) * tvec.at<double>(2,0)) / 10;


     

    二、实现过程

    已完成单目相机标定的情况下:

    (可以参考http://t.csdnimg.cn/v72VN  虽然是我很久之前写的python的,但实现是没啥问题)

    需要以下内容:

    1、已知相机的内参矩阵cameraMatrix和畸变参数distCoeffs(相机标定)

    2、需要拍摄一张棋盘格图像

    3、需要知道棋盘格的w方向和h方向角点数量

    实现代码如下:

    1. #include <opencv2/opencv.hpp>
    2. int main() {
    3. // 读取棋盘格图像
    4. cv::Mat image = cv::imread("chessboard.jpg");
    5. // 定义棋盘格的尺寸和角点列表
    6. cv::Size patternSize(11, 8);
    7. std::vector<cv::Point2f> corners;
    8. // 寻找棋盘格角点
    9. bool found = cv::findChessboardCorners(image, patternSize, corners);
    10. if (found) {
    11. // 优化角点坐标精度
    12. cv::cornerSubPix(image, corners, cv::Size(11, 11), cv::Size(-1, -1),
    13. cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
    14. // 定义棋盘格三维坐标
    15. std::vector<cv::Point3f> objectPoints;
    16. float squareSize = 1.0;
    17. for (int i = 0; i < patternSize.height; ++i) {
    18. for (int j = 0; j < patternSize.width; ++j) {
    19. objectPoints.push_back(cv::Point3f(j * squareSize, i * squareSize, 0));
    20. }
    21. }
    22. // 定义相机参数
    23. cv::Mat cameraMatrix = cv::Mat::eye(3, 3, CV_64F);
    24. cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64F);
    25. // 计算 rvec 和 tvec
    26. cv::Mat rvec, tvec;
    27. cv::solvePnP(objectPoints, corners, cameraMatrix, distCoeffs, rvec, tvec);
    28. // 输出结果
    29. std::cout << "rvec: " << rvec << std::endl;
    30. std::cout << "tvec: " << tvec << std::endl;
    31. //计算相机距离被测物的实际距离
    32. float distance = sqrt(tvec.at<double>(0,0) * tvec.at<double>(0,0) + tvec.at<double>(1,0) * tvec.at<double>(1,0) + tvec.at<double>(2,0) * tvec.at<double>(2,0)) / 10;
    33. std::cout << "distance = "<< distance << std::endl;
    34. } else {
    35. std::cout << "未找到棋盘格角点!" << std::endl;
    36. }
    37. return 0;
    38. }

    三、补充

    使用cv::solvePnP测距的方法,任意被测物都可以实现。只需要有世界坐标系的角点(手动测量)和对应点的像素坐标即可。

    参考文章:http://t.csdnimg.cn/KixCO

    本文中使用棋盘格做测距,通过cv::findChessboardCorners寻找所有棋盘格角点后再计算可以大大提高测距精度。

  • 相关阅读:
    79. 单词搜索
    MindFusion.WinForms Pack 2022.R2
    npm已经配置淘宝源仍然无法使用
    迁移学习(PCL)《PCL: Proxy-based Contrastive Learning for Domain Generalization》
    HTTP 协议
    深度神经网络之BiseNet
    图书管理系统
    ppt添加圆角矩形,并调整圆角弧度方法
    Clickhouse系列三:表引擎副本机制
    云原生的简单理解
  • 原文地址:https://blog.csdn.net/qq_19319481/article/details/134016264