校准图像的过程使用棋盘图案并从对象点的定义开始(现实世界中奶酪图案上的已知点以 xyz 坐标给出,其中 z=0 因为图案位于平面上)和图像点(在图像上找到的点,使用函数:cv2.findChessboardCorners)。对于文件夹“/camera_cal”中的每个图像,这些点存储在 numpy 数组中。通过匹配图像和目标点(使用函数 cv2.calibrateCamera),我们可以获得相机矩阵和畸变参数,这将允许我们使用“cv2.undistort”函数对图像进行去畸变。然后将这些参数保存在 pickle 文件中以备将来使用。
图。1。扭曲的棋盘图案
图 2。未扭曲的棋盘图案
在这里,我总结了我的车道数据操作管道。
1.畸变校正
应用相机不失真(功能不失真(img,mtx,dist,None,mtx)),我们可以从失真图像(img):到未
失真图像: 通过使用相机矩阵(mtx)和失真系数(dist) .
2. 得到一个阈值化的二值图像
我结合使用了颜色和渐变阈值来生成二值图像(用于渐变和颜色阈值的不同函数在文件的project.py
第 25 行和第 76 行之间)。
为了确定哪些通道更适合做阈值处理,我显示了几个图像的所有通道:
很明显,来自 RGB 的通道 R、来自 HLS 的通道 S 和来自 HSV 的通道 V 是车道线似乎更加突出的通道。所以现在,为了定义我实际要使用的那些,我通过将 X 边缘与 Y 边缘和 XY 边缘与边缘梯度阈值相结合来对这些通道执行边缘检测:
和颜色阈值:
通过混合、边缘和颜色阈值化,从这些通道我们可以得到:
这清楚地显示了预期的车道线。/project.py
用于在这 3 个通道上获取二进制阈值图像的代码可以在第 82 行和 171 行之间的文件中找到
3.透视变换
为了获得透视变换矩阵和逆矩阵,我重复使用了第一个项目中的一些代码,以便在我知道包含直线的图像上获得直线车道线:
我得到的源点和目标点如下:
来源 | 目的地 |
---|---|
587、455 | 300, 100 |
230、712 | 300, 720 |
1098, 712 | 980, 720 |
698, 455 | 980, 100 |
有了这些点,我使用函数计算了矩阵 M 和 M_invcv2.getPerspectiveTransform(src, dst)
通过取 4 个点(每行 2 个点)并定义边距,我可以将图像从正常视角转换(使用 jupyter notebook 第五块上的代码)到鸟瞰图(使用函数/P2_advanced_line_detection.ipynb
cv2 .warpPerspective()):
在获得 M 和 M_inv 矩阵后,我将它们保存在 pickle 文件中以备将来与函数一起使用。
然后可以将二进制边缘图像转换为扭曲的二进制图像,如下所示:
在尝试了几张图片后,我注意到在某些情况下(阴影、人行道上的颜色变化),很难为 S 通道找到一个不产生极端噪音的合适阈值,这就是我决定工作的原因R 和 V 通道的组合。这种组合产生如下二进制扭曲图像:
为了使用阴影产生的噪声圆顶,我决定使用称为开运算的形态学操作:
用于拟合二阶多项式的函数在文件的/project.py
第 178 行到第 408 行之间。对于第一张图像以及在轨道丢失的情况下(由完整性检查确定),我使用了“windows”方法:
/project.py
我使用课程中给出的公式在代码的第 502 行到 516 行中执行了此操作。
def measure_curvature_real(actual_fit, ploty):
'''
Calculates the curvature o
f polynomial functions in meters.
'''
ym_per_pix = 30/700 # meters per pixel in y dimension
xm_per_pix = 3.7/700 # meters per pixel in x dimension
# Define y-value where we want radius of curvature
# We'll choose the maximum y-value, corresponding to the bottom of the image
y_eval = np.max(ploty) * ym_per_pix
##### Implement the calculation of R_curve (radius of curvature) #####
curvature = ((1 + (2*actual_fit[0]*y_eval + actual_fit[1])**2)**1.5) / np.absolute(2*actual_fit[0])
return curvature * actual_fit[0]/abs(actual_fit[0])
为了决定是否应该考虑检测,我决定检查 3 个基本的东西
#====Function to measure horizontal position's average and standard deviation====#
#==========between lines. The function also measures the car's position==========#
def horizontal_distance(left_fit,right_fit,ploty):
xm_per_pix = 3.7/700
left_fitx = (left_fit[0]*ploty**2 + left_fit[1]*ploty + left_fit[2]) * xm_per_pix
right_fitx = (right_fit[0]*ploty**2 + right_fit[1]*ploty + right_fit[2]) * xm_per_pix
average_distance = np.average(right_fitx - left_fitx)
std_distance = np.std(right_fitx - left_fitx)
x_der = right_fitx[0]
x_izq = left_fitx[0]
center_car = (1280*xm_per_pix/2.0)
center_road = ((x_der+x_izq)/2.0)
position = center_car-center_road
return average_distance, std_distance, position
一旦检测到车道线并通过健全性检查,就会计算曲率,并使用逆透视变换在原始图像中显示线条。
python基于opencv的车道线检测车道线识别输出车道边界的视觉显示以及车道曲率和车辆位置的数值估计