车道线检测算法可分为基于segment , heatmap , point.本文由于设备影响,要求速度较快,采用的是基于点回归的方式,最终输出的是点, 使用方程拟合车道线后计算轮胎和车道线的距离.
Ultra-Fast-Lane : github地址 , 论文地址
复现本文一个采用了三个公开数据集, 分别是tusimple, CULane, CurveLanes. 由于三个数据集并不是同等大小,所以进行一定处理.
查看网络会发现,最终输入的尺寸高度要为32的整数倍,所以最终把图像尺寸修改为352*640.
注意: 就是将所有的数据进行缩放至352*640 ,并且尽量保证图像不失真. 如果不考虑图像失真问题,可以直接resize.
gt_image : 为mask标签,需要注意的是,这个没根车道线的mask值不相同,第一条为1,第二条为2,依次类推,网络设置的是4条线,所以针对多的线,可以通过计算进行取舍,代码可以参考 ./scripts/convert_tusimple.py 代码,分别保留左右2条线.
如果你需要检测更多的线,也可以修改对应线的数量,然后mask进行修改就行,分别设置1,2,3,4,5,6就行.
images : 为原始图像.
最后整理成一个txt文档:
后面的1和0 代表的是线是否存在,这里可以省掉.
代码部分target_transformer 在后续的读取数据并未使用,这里可以不用设置,
图像操作的顺序是先进行simu_transformer,然后segmen_transformer,最后img_transformer.
其中 segmen_transformer 和 img_transformer分开的,没有必然联系.
这里我采用了不规则点读取,中间密集,下面稀疏,上面没有的原则, 如果你的mask缩放至352*640大小,则需要添加我标记的部分,不然程序无法读取到对应标签内容.
通过阅读这部分代码也会发现,并没有使用txt中后面的1和0 的标签值,所以不写没有影响.
文章主要是使用了resnet作为检测头,语义表达能力有所欠缺,这里我修改了一下,换成了yolo系列的检测头,
主要结构如下:
class yolo(nn.Module):
def __init__(self, inference=False):
super(yolo, self).__init__()
self.conv_0 = RepVGGBlock(3, 16, 3, 2)
self.conv_1 = RepVGGBlock(16, 32, 3, 2)
self.c3_1 = C3(32, 64, n=1, shortcut=True, g=1, e=0.5)
self.conv_2 = RepVGGBlock(64, 128, 3, 2)
self.c3_2 = C3(128, 128, n=3, shortcut=True, g=1, e=0.5)
self.conv_3 = RepVGGBlock(128, 256, 3, 2)
self.c3_3 = C3(256, 256, n=3, shortcut=True, g=1, e=0.5)
self.conv_4 = RepVGGBlock(256, 512, 3, 2)
self.spp = SPPF(512, 512)
self.c3_4 = C3(512, 512, n=1, shortcut=False, g=1, e=0.5) #7*7
# self.c3_5 = C3(512, 512, n=1, shortcut=False, g=1, e=0.5) #7*7
# self.neck = Neck(inference)
def forward(self, x):
x = self.conv_0(x)
x = self.conv_1(x)
x1 = self.c3_1(x)
x = self.conv_2(x1)
x2 = self.c3_2(x)
x = self.conv_3(x2)
x3 = self.c3_3(x)
x = self.conv_4(x3)
x = self.spp(x)
x4 = self.c3_4(x)
# P1, P2, P3 = self.neck(x4, x3, x2)
return x2,x3,x4
输出尺寸:
"""
x2 torch.Size([8, 128, 44, 80])
x3 torch.Size([8, 256, 22, 40])
x4 torch.Size([8, 512, 11, 20])
原始 resnet18 输出尺寸
x2.shape -> (4,128,36,100)
x3.shape -> (4,256,18,50)
fea.shape -> (4,512,9,25) #64
"""
没有添加neck的原因是由于网络本身自带上采样(辅助验证部分).