在Adas等领域中,当检测出前方车辆后通常需要进行距离估计,单目摄像头光学图像测距具有低成本和计算快的优点,下面简单介绍一下该方法。
首先列举一下所需的参数:
相机高度,探测器俯仰角,探测器垂直半视场角,水平半视场角。探测器的垂直与水平半视场角若厂商没有提供,可以自行标定测量或根据公式计算。水平半视场角计算公式如下:
为图像宽度,为像元长度,为焦距。垂直半视场角的计算同上,将替换为即可。
探测器检测到地面区域的示意图如下。绿色区域代表图像对应的实际地面区域,对应图像中心。
(1)求轴方向的距离
轴切面的示意图如上。假设为坐标点在图像中方向距离图像中心点的距离,为图像高的一半。
扫描二维码关注公众号,回复:
2978584 查看本文章
当Y位于图像上半部分时取+号,当Y位于图像下半部分时取-号。
需注意,此时为理想情况,相机探测区域全部在地面上。实际过程中,当俯仰角较小时,相机的视场会同时涵盖天空与地面区域,此时只取的情况,对应地面区域。
(2)求轴方向的距离
x轴的计算示意图如上。由此可得,
为(1)中计算出的y方向的地理坐标,为坐标点在图像中x方向距离图像中心点的距离,为图像宽的一半。
(3)计算距离
根据(1)(2)中计算出的x、y的值可以计算地面距离。
(4)若被测物体本身具有一定高度H,则
(5)补充一点:该模型的假设是相机光学中心即为图像中心,实际过程中会有偏差,找出光学中心对应的像素位置替换即可。
贴下代码
#define USE_RIDE
const float PI = 3.1415926;
const int IMAGE_WIDTH = 1280;
const int IMAGE_HEIGHT = 720;
const float HORIZONTAL_HALF_ANGLE = 26 * PI/180;
const float VERTICAL_HALF_ANGLE = 16 * PI / 180;
const float H = 1.16;
const float PITCH_ANGLE = 7 * PI / 180;
const float RIDE_HEIGHT = 0.15;
float CoordinateTransform(const int &_x,const int &_y, float &x, float &y)
{
if (_x < 0 || _x >= IMAGE_WIDTH || _y < 0 || _y >= IMAGE_HEIGHT)
return -1;
float j = _x + 0.5;
float i = _y + 0.5;
if (i > IMAGE_HEIGHT / 2)
y = H / tan(PITCH_ANGLE + atan((i - IMAGE_HEIGHT / 2) * 2 * tan(VERTICAL_HALF_ANGLE) / IMAGE_HEIGHT));
else
y = H / tan(PITCH_ANGLE - atan((IMAGE_HEIGHT / 2 - i) * 2 * tan(VERTICAL_HALF_ANGLE) / IMAGE_HEIGHT));
if (y <= 0)
return -1;
x = sqrt(H*H + y*y) * fabs(j - IMAGE_WIDTH / 2) * tan(HORIZONTAL_HALF_ANGLE) * 2 / IMAGE_WIDTH;
#ifdef USE_RIDE
x = x*(1 - RIDE_HEIGHT / H);
y = y*(1 - RIDE_HEIGHT / H);
#endif
return sqrt(x*x + y*y);
}