【改进版】全国大学生智能车竞赛——车道线检测Baseline

项目链接:https://aistudio.baidu.com/aistudio/projectdetail/1549842

解压数据集

默认解压到/data目录下,该目录会在每次进入环境时重置,但可以节省项目启动时间。

!unzip -oq /home/aistudio/data/data68698/智能车数据集.zip -d /home/aistudio/data

数据集统计

  1. import os

  2. import cv2

  3. import numpy as np

  4. from tqdm import tqdm


  5. mask_pt = '/home/aistudio/data/mask_4000'


  6. count =  [0 for _ in range(16)]


  7. for m in tqdm(os.listdir(mask_pt)):

  8.    pt = os.path.join(mask_pt, m)

  9.    mask = cv2.imread(pt, 0)

  10.    size = mask.shape[0] * mask.shape[1]

  11.    for i in range(16):

  12.        a = mask == i

  13.        ratio_i = np.sum(a.astype(np.float)) / size

  14.        count[i] += ratio_i


  15. sum_ = np.sum(count[1:])

  16. ratios = [v/sum_ for v in count[1:]]

100%|██████████| 4000/4000 [05:13<00:00, 12.77it/s]
for i in range(0, len(ratios)):    print('-[INFO] Label {}: {:.4f}'.format(i+1, ratios[i]))
-[INFO] Label 1: 0.0170-[INFO] Label 2: 0.4482-[INFO] Label 3: 0.0843-[INFO] Label 4: 0.0767-[INFO] Label 5: 0.0334-[INFO] Label 6: 0.2513-[INFO] Label 7: 0.0070-[INFO] Label 8: 0.0025-[INFO] Label 9: 0.0158-[INFO] Label 10: 0.0152-[INFO] Label 11: 0.0292-[INFO] Label 12: 0.0087-[INFO] Label 13: 0.0061-[INFO] Label 14: 0.0046-[INFO] Label 15: 0.0000
  1. import matplotlib.pyplot as plt


  2. %matplotlib inline


  3. plt.figure(figsize=(6,9)) #调节图形大小

  4. labels = [str(i) for i in range(1, 16)] #定义标签

  5. patches,text1,text2 = plt.pie(ratios,

  6.                      labels=labels,

  7.                      autopct = '%3.2f%%', #数值保留固定小数位

  8.                      shadow = False, #无阴影设置

  9.                      startangle =90, #逆时针起始角度设置

  10.                      pctdistance = 0.6) #数值距圆心半径倍数距离

  11. #patches饼图的返回值,texts1饼图外label的文本,texts2饼图内部的文本

  12. # x,y轴刻度设置一致,保证饼图为圆形

  13. plt.axis('equal')

  14. plt.show()

随机数据增强

  1. import os


  2. os.makedirs('aug_data')

  3. os.makedirs('aug_data/image_4000')

  4. os.makedirs('aug_data/mask_4000')

  1. import numpy as np

  2. import cv2


  3. from random import random


  4. def add_noise(image, threshold=32):


  5.    noise = np.random.uniform(low=-1, high=1, size=image.shape)


  6.    image = image + noise * threshold


  7.    image = np.clip(image, 0, 255)


  8.    return image.astype(np.int)


  9. def gamma_transform_reduce(image, gamma=0.7):


  10.    max_value = np.max(image)

  11.    min_value = np.min(image)


  12.    value_l = max_value - min_value


  13.    image = (image - min_value)/value_l


  14.    image = np.power(image, gamma)


  15.    image = image * 255


  16.    return image.astype(np.int)



  17. def random_aug(img):

  18.    if random() > 0.5:

  19.        img = cv2.medianBlur(img, 3)

  20.    if random() > 0.5:

  21.        img = add_noise(img)

  22.    if random() > 0.5:

  23.        img = gamma_transform_reduce(img, gamma=0.7)

  24.    if random() > 0.5:

  25.        img = gamma_transform_reduce(img, gamma=1.2)

  26.    return img

均衡化数据集

  1. from shutil import copyfile

  2. import os

  3. from tqdm import tqdm

  4. import cv2

  5. import numpy as np


  6. mask_pt = '/home/aistudio/data/mask_4000'

  7. color_path = '/home/aistudio/data/image_4000'


  8. count = 0

  9. for m in tqdm(os.listdir(mask_pt)):

  10.    scr_mask = os.path.join(mask_pt, m)

  11.    mask = cv2.imread(scr_mask, 0)

  12.    a = mask == 2

  13.    b = mask == 6

  14.    size = mask.shape[0] * mask.shape[1]

  15.    ratio_a = np.sum(a.astype(np.float)) / size

  16.    ratio_b = np.sum(a.astype(np.float)) / size

  17.    if ratio_a + ratio_b < 0.003:

  18.        count += 1

  19.        src_color = os.path.join(color_path, m)

  20.        dst_color = os.path.join('aug_data/image_4000', m)

  21.        dst_mask = os.path.join('aug_data/mask_4000', m)

  22.        copyfile(src_color, dst_color)

  23.        copyfile(scr_mask, dst_mask)

  24.        img = cv2.imread(src_color)

  25.        for c in range(4):

  26.            dst_color = os.path.join('aug_data/image_4000', m.replace('.', '_{}.'.format(c)))

  27.            dst_mask = os.path.join('aug_data/mask_4000', m.replace('.', '_{}.'.format(c)))

  28.            aug_img = random_aug(img)

  29.            cv2.imwrite(dst_color, aug_img)

  30.            copyfile(scr_mask, dst_mask)


  31. print('-[TOTAL] Argued:', count)

  1. import os

  2. import cv2

  3. import numpy as np

  4. from tqdm import tqdm


  5. count =  [0 for _ in range(16)]


  6. mask_pt = '/home/aistudio/data/mask_4000'

  7. for m in tqdm(os.listdir(mask_pt)):

  8.    pt = os.path.join(mask_pt, m)

  9.    mask = cv2.imread(pt, 0)

  10.    size = mask.shape[0] * mask.shape[1]

  11.    for i in range(16):

  12.        a = mask == i

  13.        ratio_i = np.sum(a.astype(np.float)) / size

  14.        count[i] += ratio_i


  15. mask_pt = '/home/aistudio/aug_data/mask_4000'

  16. for m in tqdm(os.listdir(mask_pt)):

  17.    pt = os.path.join(mask_pt, m)

  18.    mask = cv2.imread(pt, 0)

  19.    size = mask.shape[0] * mask.shape[1]

  20.    for i in range(16):

  21.        a = mask == i

  22.        ratio_i = np.sum(a.astype(np.float)) / size

  23.        count[i] += ratio_i


  24. sum_ = np.sum(count[1:])

  25. ratios = [v/sum_ for v in count[1:]]

100%|██████████| 4000/4000 [05:50<00:00, 11.41it/s]100%|██████████| 4368/4368 [06:25<00:00, 11.34it/s]
for i in range(0, len(ratios)):    print('-[INFO] Label {}: {:.4f}'.format(i+1, ratios[i]))
-[INFO] Label 1: 0.0262-[INFO] Label 2: 0.2790-[INFO] Label 3: 0.1062-[INFO] Label 4: 0.1595-[INFO] Label 5: 0.0635-[INFO] Label 6: 0.2485-[INFO] Label 7: 0.0166-[INFO] Label 8: 0.0025-[INFO] Label 9: 0.0166-[INFO] Label 10: 0.0161-[INFO] Label 11: 0.0356-[INFO] Label 12: 0.0103-[INFO] Label 13: 0.0099-[INFO] Label 14: 0.0094-[INFO] Label 15: 0.0000

统计均衡化后的数据

  1. import matplotlib.pyplot as plt


  2. %matplotlib inline


  3. plt.figure(figsize=(6,9)) #调节图形大小

  4. labels = [str(i) for i in range(1, 16)] #定义标签

  5. patches,text1,text2 = plt.pie(ratios,

  6.                      labels=labels,

  7.                      autopct = '%3.2f%%', #数值保留固定小数位

  8.                      shadow = False, #无阴影设置

  9.                      startangle =90, #逆时针起始角度设置

  10.                      pctdistance = 0.6) #数值距圆心半径倍数距离

  11. #patches饼图的返回值,texts1饼图外label的文本,texts2饼图内部的文本

  12. # x,y轴刻度设置一致,保证饼图为圆形

  13. plt.axis('equal')

  14. plt.show()

划分数据集

  1. import os

  2. from imghdr import what

  3. import numpy as np

  4. import random



  5. def get_all_date(dir_images, dir_masks):

  6.    """生成训练、测试所需的txt文件"""

  7.    res = []

  8.    for file in os.listdir(dir_images):

  9.        image_path = os.path.join(dir_images, file)

  10.        mask_path = os.path.join(dir_masks, file)

  11.        if os.path.exists(image_path) and os.path.exists(mask_path):  

  12.            if what(image_path) and what(mask_path):

  13.                res.append((os.path.join(dir_images, file), os.path.join(dir_masks, file)))

  14.        else:

  15.            print(image_path, mask_path)

  16.    return res


  17. if True:

  18.    res1 = get_all_date('/home/aistudio/data/image_4000', '/home/aistudio/data/mask_4000')

  19.    res2 = get_all_date('/home/aistudio/aug_data/image_4000', '/home/aistudio/aug_data/mask_4000')

  20.    res = res1 + res2

  21.    print(len(res))

  22.    random.shuffle(res)

  23.    random.shuffle(res)

  24.    with open('./train_list.txt', 'w') as f:

  25.        for line in res[:-500]:

  26.            f.writelines(line[0] + ' ' + line[1] + '\n')


  27.    with open('./val_list.txt', 'w') as f:

  28.        for line in res[-500:]:

  29.            f.writelines(line[0] + ' ' + line[1] + '\n')

8368

执行训练

其中 PaddleSeg/configs/deeplabv3p_resnet50_os8_cityscapes_1024x512_80k.yml文件是训练的配置文件,其引用了 PaddleSeg/configs/_base_/cityscapes.yml,我们可以在训练时针对不同情况进行调参。当然选手也可以在'PaddleSeg/configs'中选择更多模型配置,但需要注意的是数据读取路径等细节也在配置文件中,如非默认则需要自行修改。

# 设置环境变量只使用第1块GPU并切换工作目录# 注意!此操作会更改程序的工作目录!%set_env CUDA_VISIBLE_DEVICES=0%set_env PYTHONPATH='/home/aistudio/PaddleSeg'%cd /home/aistudio
env: CUDA_VISIBLE_DEVICES=0env: PYTHONPATH='/home/aistudio/PaddleSeg'/home/aistudio
# 安装依赖包!pip install paddleseg
!wget https://bj.bcebos.com/paddleseg/dygraph/cityscapes/deeplabv3p_resnet50_os8_cityscapes_1024x512_80k/model.pdparams
!cp /home/aistudio/model.pdparams -d /home/aistudio/output/best_model/
!cp /home/aistudio/output/iter_1000/model.pdopt -d /home/aistudio/output/best_model/
!python pretrained_model/download_model.py deeplabv3p_xception65_bn_coco
python: can't open file 'pretrained_model/download_model.py': [Errno 2] No such file or directory
# 训练命令 如需恢复训练则在下方命令尾部增加 --resume_model output/iter_8000(已存在的ppCheckpoint文件夹名)!python PaddleSeg/train.py \    --config home/aistudio/work/deeplabv3p_resnet101.yml \    --do_eval --use_vdl
# 训练命令 如需恢复训练则在下方命令尾部增加 --resume_model output/iter_****(已存在的ppCheckpoint文件夹名)!python PaddleSeg/train.py \    --config /home/aistudio/work/deeplabv3p_resnet101.yml \    --do_eval --use_vdl --resume_model /home/aistudio/output/iter_9000/
# 进行推理,其中--model_path后跟自己训练好的模型文件路径,一般选择bast_model或iter后最大值的参数文件!python PaddleSeg/predict.py \    --config /home/aistudio/work/deeplabv3p_resnet101.yml \    --model_path output/best_model/model.pdparams --image_path data/infer --save_dir output/result

中值滤波+闭运算

  1. import os

  2. from tqdm import tqdm


  3. base = 'output/result'


  4. kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))


  5. for im in tqdm(os.listdir(base)):

  6.    pt = os.path.join(base, im)

  7.    img = cv2.imread(pt, 0)

  8.    img = cv2.medianBlur(img, 5)

  9.    img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

  10. ECT, (5, 5))


  11. for im in tqdm(os.listdir(base)):

  12.    pt = os.path.join(base, im)

  13.    img = cv2.imread(pt, 0)

  14.    img = cv2.medianBlur(img, 5)

  15.    img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

  16.    cv2.imwrite(pt, img)

提交结果

压缩0-14Label的预测结果文件,在赛题页面->提交结果 上进行提交结果。

%cd /home/aistudio/output/result/result!zip -r -o /home/aistudio/predict.zip ./%cd /home/aistudio

https://mp.weixin.qq.com/s/NqH9c2tGFd1E8I87JhzJxg