单目摄像头测距

在Adas等领域中,当检测出前方车辆后通常需要进行距离估计,单目摄像头光学图像测距具有低成本和计算快的优点,下面简单介绍一下该方法。

首先列举一下所需的参数:

相机高度,探测器俯仰角\Theta,探测器垂直半视场角\beta,水平半视场角\gamma。探测器的垂直与水平半视场角若厂商没有提供,可以自行标定测量或根据公式计算。水平半视场角计算公式如下:

\gamma =\arctan \left ( \frac{W\ast d}{2\ast f}\right )

W为图像宽度,d为像元长度,f为焦距。垂直半视场角的计算同上,将W替换为H即可。

探测器检测到地面区域的示意图如下。绿色区域代表图像对应的实际地面区域,{O}'对应图像中心。

单目摄像头测距_第1张图片

(1)求{y}'轴方向y的距离

单目摄像头测距_第2张图片

{y}'轴切面的示意图如上。假设Y为坐标点在图像中y方向距离图像中心点的距离,{Y}'为图像高的一半。

单目摄像头测距_第3张图片

Y位于图像上半部分时取+号,当Y位于图像下半部分时取-号。

需注意,此时为理想情况,相机探测区域全部在地面上。实际过程中,当俯仰角较小时,相机的视场会同时涵盖天空与地面区域,此时只取y>0的情况,对应地面区域。

(2)求{x}'轴方向x的距离

单目摄像头测距_第4张图片

x轴的计算示意图如上。由此可得,

单目摄像头测距_第5张图片

y为(1)中计算出的y方向的地理坐标,X坐标点在图像中x方向距离图像中心点的距离,{X}'为图像宽的一半。

(3)计算距离

根据(1)(2)中计算出的x、y的值可以计算地面距离。

dis=\sqrt{x^{2}+y^{2}}

(4)若被测物体本身具有一定高度H,则

\left ( {x}',{y}' \right )=\left ( x,y \right )*(1-\frac{H}{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);
}

 

你可能感兴趣的:(单目摄像头测距)