单目测距实战

前言

单目测距是通过使用单个摄像头捕获的图像信息俩估计物体的距离。这是一种在计算机领域广泛研究的问题,并且困难之处在于从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

相关推荐
微笑伴你而行1 天前
Entire-barn dairy cow tracking framework for multi-camera systems
数码相机
格林威2 天前
常规的变焦镜头有哪些类型?能做什么?
人工智能·数码相机·opencv·计算机视觉·视觉检测·机器视觉·工业镜头
格林威2 天前
机器视觉的工业镜头有哪些?能做什么?
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测·工业镜头
云风xe2 天前
从chatGPT获取的关于相机焦距与其他参数的关系
数码相机
格林威3 天前
常规可见光相机在工业视觉检测中的应用
图像处理·人工智能·数码相机·计算机视觉·视觉检测
格林威4 天前
短波红外相机在工业视觉检测中的应用
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测
格林威4 天前
UV紫外相机在工业视觉检测中的应用
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测·uv
格林威4 天前
近红外相机在机器视觉检测中的应用
人工智能·数码相机·opencv·计算机视觉·视觉检测
格林威4 天前
不同光谱的工业相机有哪些?能做什么?
图像处理·人工智能·深度学习·数码相机·计算机视觉·视觉检测
格林威4 天前
MP偏振相机在工业视觉检测中的应用
人工智能·数码相机·opencv·计算机视觉·视觉检测·uv