当前位置: 首页 > article >正文

棋盘格测距-单目相机(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方向角点数量

实现代码如下:

#include <opencv2/opencv.hpp>

int main() {
    // 读取棋盘格图像
    cv::Mat image = cv::imread("chessboard.jpg");
    
    // 定义棋盘格的尺寸和角点列表
    cv::Size patternSize(11, 8);
    std::vector<cv::Point2f> corners;
    
    // 寻找棋盘格角点
    bool found = cv::findChessboardCorners(image, patternSize, corners);
    
    if (found) {
        // 优化角点坐标精度
        cv::cornerSubPix(image, corners, cv::Size(11, 11), cv::Size(-1, -1),
                         cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
        
        // 定义棋盘格三维坐标
        std::vector<cv::Point3f> objectPoints;
        float squareSize = 1.0;
        for (int i = 0; i < patternSize.height; ++i) {
            for (int j = 0; j < patternSize.width; ++j) {
                objectPoints.push_back(cv::Point3f(j * squareSize, i * squareSize, 0));
            }
        }
        
        // 定义相机参数
        cv::Mat cameraMatrix = cv::Mat::eye(3, 3, CV_64F);
        cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64F);
        
        // 计算 rvec 和 tvec
        cv::Mat rvec, tvec;
        cv::solvePnP(objectPoints, corners, cameraMatrix, distCoeffs, rvec, tvec);
        
        // 输出结果
        std::cout << "rvec: " << rvec << std::endl;
        std::cout << "tvec: " << tvec << std::endl;

        //计算相机距离被测物的实际距离
        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; 
        std::cout << "distance = "<< distance << std::endl;

    } else {
        std::cout << "未找到棋盘格角点!" << std::endl;
    }
    
    return 0;
}

三、补充

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

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

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


http://www.kler.cn/a/106185.html

相关文章:

  • 树莓派镜像 DIY 制作
  • Educational Codeforces Round 164 (Rated for Div. 2)(A~E)
  • 大数据如何助力干部选拔的公正性
  • 卷径计算(基于卷径变化微分方程计算实时卷径)
  • 【项目开发】理解SSL延迟:为何HTTPS比HTTP慢?
  • Excel超级处理器:高效实现2种批量生成二维码方式
  • nginx浏览器缓存和上流缓存expires指令_nginx配置HTTPS
  • Miniconda、Vscode下载和conda源、pip源设置
  • RHCE8 资料整理(四)
  • 【机器学习可解释性】3.部分依赖图
  • Java API访问HDFS
  • 2.18每日一题(不直接给f(x)的定积分及变上限积分)
  • TSINGSEE青犀智慧仓储可视化视频智能监管系统方案
  • Flume基本使用--mysql数据输出
  • 微前端qiankun接入Vue和React项目
  • CNN实现与训练--------------以cifar10数据集为例进行演示(基于Tensorflow)
  • JDK11下载、安装与配置、运行第一个Java程序教程
  • 虹科 | 解决方案 | 汽车示波器 学校教学方案
  • 安装 tensorflow==1.15.2 遇见的问题
  • 一文了解独立站黑科技:clock斗篷技术
  • [推荐]Linux安装与配置虚拟机之虚拟机服务器坏境配置
  • Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (一)
  • 『第七章』翩翩起舞的雨燕:顺序与并发执行
  • Games104现代游戏引擎笔记 网络游戏架构基础
  • 4.1 网络基础之网络IO
  • Cloak斗篷、AB轮询收款科技详解,FP独立站原来可以这样玩!