单目测距实战

前言

单目测距是通过使用单个摄像头捕获的图像信息俩估计物体的距离。这是一种在计算机领域广泛研究的问题,并且困难之处在于从2d图像中恢复3d信息。

单目测距常用的或者是实用方法是相似三角形法。

相似三角形法:假设有一个宽度为w的目标的或者物体。然后,我们用相机对物体进行拍照并且测距物体的像素宽度p,相机焦距为f。根据相似三角形得到目标放在距离我们相机为d的位置

d = f * w/p

图像去畸变

图像去畸变是使用相机校准参数来修改图像,进而消除由于镜头的光学因素和相机的构造因素导致的图像畸变。

畸变主要有两种类型:径向畸变和切向畸变。径向畸变是由于透镜的形状导致光线弯曲的比例变化,使得图像看起来像在水面下观察物体。切向畸变则是由于透镜和成像平面之间的不平行导致的。

一般情况下,从摄像头或图像文件中读取的原始图像都包含一定的畸变,取决于具体的摄像头和镜头参数。因此,直接读取的图像是原始的,畸变的。

在进行单目测距或者其他涉及准确的空间量测的计算机视觉任务中,预处理步骤通常会包括一个图像去畸变(undistortion)的步骤。原因是摄像头的镜片畸变会扭曲图像,在图像上测得的距离可能会因此产生偏差。对图像进行去畸变可以提高测量结果的准确性。

因此,进行单目测距通常会需要一个去畸变的步骤。你需要摄像头的校准参数才能正确地去除畸变。在OpenCV中,这通常通过cv::undistort()函数来进行,需要提供摄像头的内参矩阵和畸变系数。

单目测距代码

1、基于实际物体的高度或者宽度的单目测距

单目测距使用的方法大多数是通过参照物,即已知实际物体的高度或者宽度来进行测距。但是这种方法的缺点必须要已经实际物体的高度或者宽度。

复制代码
	double calculateDistance(double &objectHeight, double &imageHeight, double &focalLength)
	{
		// 距离 = 相机的焦距(像素)* 物体的实际高度(米)/ 物体在图像上的成像高度(像素) //* 相机传感器的单位像素高度(米)
		double distance = (focalLength * objectHeight) / (imageHeight);
		return distance;
	}

2、基于相机安装高度的单目测距

相机

复制代码
cv::Point3f MonocularRanging(int x0, int y0)
{
	/*
      x1为检测框左上角x坐标,x2为检测框右下角x坐标,y2为检测框右下角y坐标;
      取检测框底边中点作为单目测距点输入。
                y
                |
                |
      x <-------
    */
    //RGB相机相关参数
    float Theta = 97.5 / 2; //水平视场角一半
	float Beta  = 79.4 / 2; //垂直视场角一半
	float Alpha = 10; //10; //相机安装仰角
    float Mh    = 46.52;    //相机安装高度 前撞:55.2, //相机安装高度 机身:50.5,//红外回充46.52
    // Opencv
    cv::Mat CameraMatrix = (cv::Mat_<float>(3,3) <<  2.9489061908999292e+02,       0., 3.1866700927076226e+02,
                                                     0., 2.9491166478751404e+02, 2.4225251338364708e+02,
                                                      0.,        0.,        1.);
    cv::Mat DistCoeffs = (cv::Mat_<float>(1,5) << 1.2105428797704496e-02, -1.9610247948251138e-02, 4.2034414972305298e-04, 4.9760569760944572e-04, 0.);

    float Tt = Theta * PI / 180.;
    float Bt = (Beta + pitch)  * PI / 180.;
    float x, y, kx, ky;
    double a, b;
	double py = abs(ky - CameraMatrix.at<float>(1, 2));
    double px = CameraMatrix.at<float>(0, 2) - kx;
    a = atan(tan(Bt) * py / CameraMatrix.at<float>(1, 2)) * 180 / PI;
    //b = (90 - a - Alpha) * PI / 180;//相机为俯角时
    b = (a - Alpha) * PI / 180;//相机为仰角时
	y = Mh / tan(b);
    y = abs(y);
    x = tan(Tt) * px * hypot(Mh,y) / CameraMatrix.at<float>(0, 2);
    cv::Point3f point;
    point.x = x * 1e-3;
    point.y = y * 1e-3;
    point.z = 0;
    return point;

参考链接:

1、https://zhuanlan.zhihu.com/p/642601409

相关推荐
枫叶林FYL18 小时前
【强化学习】4 视觉引导的时序奖励塑形:多视角视频驱动的强化学习状态对齐框架
数码相机·音视频
cd_9492172120 小时前
鸿蒙系统给抖音开启相机权限的操作指南(2026)
数码相机·华为·harmonyos
2601_9574188021 小时前
深入解析Android相机有线连接:PTP与MTP协议栈实现原理与实践
android·数码相机·智能手机
qq_526099132 天前
工业视觉核心硬件:图像采集卡性能体系与选型逻辑解析
数码相机
kyle~3 天前
机器人感知 --- 多相机传感时间误差分析
linux·c++·数码相机·机器人·ros2·传感器
ZPC82103 天前
moveit2_servo 怎么接收相机调节指令(视觉伺服)
人工智能·数码相机·算法·计算机视觉·机器人
苏映视官方账号3 天前
展会回顾丨INSNEX苏映视精彩亮相CIBF 深圳国际电池展
数码相机
8K超高清3 天前
2026传媒技术大会:博冠赋能融媒体制播
大数据·人工智能·科技·数码相机·计算机视觉·传媒·媒体
视图猿人3 天前
ubuntu24.04系统使用深度相机Astra pro时的配置方法
数码相机
2601_957418804 天前
Android相机有线连接全栈解决方案:PTP/MTP协议深度实现与应用实践
android·数码相机