前言
单目测距是通过使用单个摄像头捕获的图像信息俩估计物体的距离。这是一种在计算机领域广泛研究的问题,并且困难之处在于从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、基于相机安装高度的单目测距
相机文章来源:https://www.toymoban.com/news/detail-824885.html
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文章来源地址https://www.toymoban.com/news/detail-824885.html
到了这里,关于单目测距实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!