这章节内容少,但非常重要,生成训练时所需的.xt文件,重点在于:xt文件每行后边的1,1,1,1,如果后边1,1,1,1生成不正确,则训练的LOSS是降不下去的,为了快速在自己的训练集Q上训练,建议不要自定义数据集,网上很多教程我也看过,自定义数据集的训练结果非常差,可能是我没有好好排査原因,所以建议大家转换为文章所用的数据集格式,这样不会出错。
上节(四、Ultra-Fast-Lane-Detection训练自己的【汽车车道】线数据集 -CSDN博客)我们完成数据集的基础制作之后形成了以下的json只 文件,里边是一行一行的利用h samples得到的格式如下的标注结果:
{"lanes": [[-2, -2, -2, 482, 468, 455, 442, 428, 415, 401, 387, 372, 357, 343, 328, 313, 299, 284, 270, 256, 241, 227, 212, 198, 183, 169, 154, 140, 126, 111, 97, 82, 68, 53, 39, 25, 10, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], [-2, -2, -2, -2, 494, 484, 474, 464, 453, 443, 433, 423, 413, 402, 392, 382, 372, 361, 350, 340, 329, 319, 308, 298, 287, 276, 266, 255, 245, 234, 223, 213, 202, 192, 181, 171, 160, 150, 140, 129, 119, 108, 98, 88, 77, 67, 57, 46, 36, 25, 15, 5, -2, -2, -2], [-2, -2, -2, -2, 521, 514, 508, 501, 495, 488, 481, 475, 468, 462, 455, 449, 442, 435, 429, 422, 416, 409, 403, 396, 390, 383, 376, 370, 363, 357, 350, 343, 337, 330, 324, 317, 310, 304, 297, 290, 284, 277, 271, 264, 257, 251, 244, 237, 231, 224, 218, 211, 204, 198, -2], [-2, -2, -2, -2, -2, -2, -2, 615, 621, 627, 634, 640, 646, 652, 659, 665, 671, 677, 683, 689, 695, 701, 707, 713, 719, 725, 731, 737, 743, 749, 755, 761, 767, 773, 779, 785, 791, 797, 803, 808, 814, 820, 826, 832, 838, 844, 850, 856, 862, 868, 874, 880, 886, 892, -2], [-2, -2, -2, -2, -2, -2, 643, 654, 664, 675, 686, 696, 707, 718, 728, 739, 750, 760, 771, 782, 792, 802, 812, 822, 832, 842, 852, 862, 872, 882, 892, 902, 912, 922, 932, 942, 952, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], [-2, -2, -2, -2, -2, -2, 680, 695, 710, 725, 741, 756, 771, 786, 801, 815, 830, 845, 859, 874, 889, 903, 918, 933, 947, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2]],
"h_samples": [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540],
"raw_file": "my_dataset1/img/MVI_40192_img00051.jpg"}
下图中的每一行都包括 以上的内容:
接下来,我们需要修改Ultra-Fast-Lane-Detection-master/scripts/convert tusimple.py文件下的generate segmentation and train list(root, line txt,names)函数Q,形成自己的车道线顺序。
以4车道线为例
- 1,1,1,1表示从左到右的车道线都存在;
- 1.1.0.0,有2条斜率K<0的左侧线;
- 0,1.0,0表示有1条斜率K<0的左侧线;
- 0.0.1.0表示有1条斜率k>0的右侧线;
经过分析发现不会出现1,0.0,1或者1,0,1,0。也就是说0不能在中间只能在两边,这个是在训练时发现问题的关键,因此我们在转换的时候一定要注意。我的6车道线转换代码如下,仅仅修改generate segmentation and train list函数:
def generate_segmentation_and_train_list(root, line_txt, names):
train_gt_fp = open(os.path.join(root,'train_gt.txt'),'w')
for i in tqdm.tqdm(range(len(line_txt))):
tmp_line = line_txt[i]
lines = []
for j in range(len(tmp_line)):
lines.append(list(map(float,tmp_line[j])))
ks = np.array([calc_k(line) for line in lines]) # get the direction of each lane
k_neg = ks[ks<0].copy()
k_pos = ks[ks>0].copy()
k_neg = k_neg[k_neg != -10] # -10 means the lane is too short and is discarded
k_pos = k_pos[k_pos != -10]
k_neg.sort()
k_pos.sort()
label_path = names[i][:-3]+'png'
label = np.zeros((540,960),dtype=np.uint8)
bin_label = [0,0,0,0,0,0]
if len(k_neg) == 1: # for only one lane in the left
which_lane = np.where(ks == k_neg[0])[0][0]
draw(label,lines[which_lane],3)
bin_label[2] = 1
elif len(k_neg) == 2: # for two lanes in the left
which_lane = np.where(ks == k_neg[1])[0][0]
draw(label,lines[which_lane],2)
which_lane = np.where(ks == k_neg[0])[0][0]
draw(label,lines[which_lane],3)
bin_label[1] = 1
bin_label[2] = 1
elif len(k_neg) == 3:
which_lane = np.where(ks == k_neg[2])[0][0]
draw(label,lines[which_lane],1) # for two lanes in the left
which_lane = np.where(ks == k_neg[1])[0][0]
draw(label,lines[which_lane],2)
which_lane = np.where(ks == k_neg[0])[0][0]
draw(label,lines[which_lane],3)
bin_label[1] = 1
bin_label[2] = 1
bin_label[0] = 1
elif len(k_neg) > 3: # for more than two lanes in the left,
which_lane = np.where(ks == k_neg[2])[0][0]
draw(label,lines[which_lane],1) # for two lanes in the left
which_lane = np.where(ks == k_neg[1])[0][0]
draw(label,lines[which_lane],2)
which_lane = np.where(ks == k_neg[0])[0][0]
draw(label,lines[which_lane],3)
bin_label[1] = 1
bin_label[2] = 1
bin_label[0] = 1
if len(k_pos) == 1: # For the lanes in the right, the same logical is adopted.
which_lane = np.where(ks == k_pos[0])[0][0]
draw(label,lines[which_lane],4)
bin_label[3] = 1
elif len(k_pos) == 2:
which_lane = np.where(ks == k_pos[1])[0][0]
draw(label,lines[which_lane],4)
which_lane = np.where(ks == k_pos[0])[0][0]
draw(label,lines[which_lane],5)
bin_label[3] = 1
bin_label[4] = 1
elif len(k_pos) == 3:
which_lane = np.where(ks == k_pos[2])[0][0]
draw(label,lines[which_lane],4)
which_lane = np.where(ks == k_pos[1])[0][0]
draw(label,lines[which_lane],5)
which_lane = np.where(ks == k_pos[0])[0][0]
draw(label,lines[which_lane],6)
bin_label[3] = 1
bin_label[4] = 1
bin_label[5] = 1
elif len(k_pos)>3:
which_lane = np.where(ks == k_pos[1])[0][0]
draw(label,lines[which_lane],4)
which_lane = np.where(ks == k_pos[1])[0][0]
draw(label,lines[which_lane],5)
which_lane = np.where(ks == k_pos[0])[0][0]
draw(label,lines[which_lane],6)
bin_label[3] = 1
bin_label[4] = 1
bin_label[5] = 1
cv2.imwrite(os.path.join(root,label_path),label)
train_gt_fp.write(names[i] + ' ' + label_path + ' '+' '.join(list(map(str,bin_label))) + '\n')
train_gt_fp.close()