[TOC]

概述

文章参考:https://blog.csdn.net/zimiao552147572/article/details/106089951

曲线的曲率就是针对曲线上某个点的切线方向角对弧长的转动率,通过微分来定义,表明曲线偏离直线的程度。数学上表明曲线在某一点的弯曲程度的数值。曲率越大,表示曲线的弯曲程度越大。曲率的倒数就是曲率半径。

下面有三个球体,网球、篮球、地球,半径越小的越容易看出是圆的,所以随着半径的增加,圆的程度就越来越弱了。

img

定义球体或者圆的“圆”的程度,就是 曲率 ,计算方法为:
$$
K = 1 / r
$$
其中r为球体或者圆的半径,这样半径越小的圆曲率越大,直线可以看作半径为无穷大的圆,其曲率为:

曲线的曲率

不同的曲线有不同的弯曲程度:

img

怎么来表示某一条曲线的弯曲程度呢?

我们知道三点确定一个圆:

img

当$$segurma$$ 趋近于0时,我们可以得到曲线在$$x_0$$ 处的密切圆,也就是曲线在该点的圆近似:

img

另外我们也可以观察到,在曲线比较平坦的位置,密切圆较大,在曲线比较弯曲的地方,密切圆较小,

img

img

代码实现

我们根据上述的计算曲率半径的方法,代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def cal_radius(img, left_fit, right_fit):

# 图像中像素个数与实际中距离的比率
# 沿车行进的方向长度大概覆盖了30米,按照美国高速公路的标准,宽度为3.7米(经验值)
ym_per_pix = 30 / 720 # y方向像素个数与距离的比例
xm_per_pix = 3.7 / 700 # x方向像素个数与距离的比例

# 计算得到曲线上的每个点
left_y_axis = np.linspace(0, img.shape[0], img.shape[0] - 1)
left_x_axis = left_fit[0] * left_y_axis ** 2 + left_fit[1] * left_y_axis + left_fit[2]
right_y_axis = np.linspace(0, img.shape[0], img.shape[0] - 1)
right_x_axis = right_fit[0] * right_y_axis ** 2 + right_fit[1] * right_y_axis + right_fit[2]

# 获取真实环境中的曲线
left_fit_cr = np.polyfit(left_y_axis * ym_per_pix, left_x_axis * xm_per_pix, 2)
right_fit_cr = np.polyfit(right_y_axis * ym_per_pix, right_x_axis * xm_per_pix, 2)

# 获得真实环境中的曲线曲率半径
left_curverad = ((1 + (2 * left_fit_cr[0] * left_y_axis * ym_per_pix + left_fit_cr[1]) ** 2) ** 1.5) / np.absolute(
2 * left_fit_cr[0])
right_curverad = ((1 + (
2 * right_fit_cr[0] * right_y_axis * ym_per_pix + right_fit_cr[1]) ** 2) ** 1.5) / np.absolute(
2 * right_fit_cr[0])

# 在图像上显示曲率半径
cv2.putText(img, 'Radius of Curvature = {}(m)'.format(np.mean(left_curverad)), (20, 50), cv2.FONT_ITALIC, 1,
(255, 255, 255), 5)
return img

显示效果:

img

计算偏离中心的距离: