前几周的车道线检测方法都是在公开的数据集上进行的检测,而在小车上摄像头对于车道线的检测需要进一步思考,场地不确定以及小车高度摄像头高度的不确定,使得车道线的检测困难重重。更具体的讲,前些周的工作适合摄像头高度较高的情况下进行检测,在一开始的数据集标注时,车道线就被视为一条细线,前面提及的模型对于这种情况下的路况十分适合。而在小车的高度下,它所拍摄到的摄像头的高度汽车高度相差很大,在不能调整摄像头的前提下,我选择了继续探索图像分割方面的深度学习模型。
首先便是对于Unet的探索,该模型是图像分割领域基础的模型,具有开创性的意义。
Unet模型
第一部分是主干特征提取部分,我们可以利用主干部分获得一个又一个的特征层,Unet的主干特征提取部分与VGG相似,为卷积和最大池化的堆叠。利用主干特征提取部分我们可以获得五个初步有效特征层,在第二步中,我们会利用这五个有效特征层可以进行特征融合。我使用的unet网络该部分主要是由两层卷积和激活函数组成
class conv_block(nn.Module):
"""
Convolution Block
"""
def __init__(self, in_ch, out_ch):
super(conv_block, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True))
def forward(self, x):
x = self.conv(x)
return
第二部分是加强特征提取部分,我们可以利用主干部分获取到的五个初步有效特征层进行上采样,并且进行特征融合(对上采样得到的结果进行通道的堆叠),获得一个最终的,融合了所有特征的有效特征层。这也是Unet的精髓所在,添加了skip-connection的机制,从而使得融合了更多有效的特征,使得模型的预测会更准确。
该部分主要是一个反卷积和激活函数组成,而代入的tensor则是上一层的输出和对应的同层之间的第一部分的张量
class up_conv(nn.Module):
"""
Up Convolution Block
"""
def __init__(self, in_ch, out_ch):
super(up_conv, self).__init__()
self.up = nn.Sequential(
nn.Upsample(scale_factor=2),
nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
def forward(self, x):
x = self.up(x)
return x
第三部分是预测部分,我们会利用最终获得的最后一个有效特征层对每一个特征点进行分类,相当于对每一个像素点进行分类。
模型尝试
因此针对该网络我展开了制作训练集,训练,测试等一系列的操作:
标注数据集
数据集需要使用labelme进行标注,得到相关的车道线分割json数据集,通过和上篇文章相同的ultra-fast-lane-detection模型相同的方法。
进行数据处理和读取
class PipeDataset(Dataset):
def __init__(self