【Lane】 Ultra-Fast-Lane-Detection 复现

2023-05-16

引言

笔者Ultra-Fast-Lane-Detection专栏链接🔗导航:

  1. 【Lane】 Ultra-Fast-Lane-Detection 复现
  2. 【Lane】Ultra-Fast-Lane-Detection(1)自定义数据集训练
  3. 【Lane】Ultra-Fast-Lane-Detection(2)自定义模型测试

车道线检测源码复现以及训练自己的数据集
源码地址:https://github.com/cfzd/Ultra-Fast-Lane-Detection
论文地址:https://arxiv.org/abs/2004.11757

1 环境搭建

conda create -n lane python=3.7
conda activate lane  # 激活环境
conda install pytorch torchvision cudatoolkit=10.1 -c pytorch 
# 参考官网:https://pytorch.org/get-started/locally/
pip install -r requirements.txt

2 下载项目源码

若在服务器上可以用指令下载,否则直接在网址中下载

git clone https://github.com/cfzd/Ultra-Fast-Lane-Detection

3 下载开源数据集

笔者下载了Tusimple数据集,链接如下:
Tusimple
在这里插入图片描述
上图显示的可以都下载下来

开源数据集准备
在源码根目录中新建文件夹TUSIMPLEROOT,将上述的压缩包解压后放入文件夹中。

$TUSIMPLEROOT
|──clips
|──label_data_0313.json
|──label_data_0531.json
|──label_data_0601.json
|──test_tasks_0627.json
|──test_label.json
|──readme.md

在这里插入图片描述
对于Tusimple,没有提供分段注释,因此我们需要从json注释生成分段。

python scripts/convert_tusimple.py --root $TUSIMPLEROOT

$TUSIMPLEROOT代表你自己创建的文件夹TUSIMPLEROOT的路径。通过这一步将会产生上图中的两个.txt文件

4 测试源码

下载预训练模型,放在源码根目录下,如下图
百度网盘链接,提取码:bghd
在这里插入图片描述

4.1 执行test.py

python test.py configs/tusimple.py --test_model tusimple_18.pth --test_work_dir ./tmp

运行上述指令,在根目录文件夹下终端显示如下:
在这里插入图片描述
并在根目录文件夹下新建tmp文件夹,文件夹下内容如下:
在这里插入图片描述

4.2 执行demo.py

python demo.py configs/tusimple.py --test_model tusimple_18.pth 

运行上述指令,在根目录文件夹下终端显示如下:
在这里插入图片描述
并在终端生成test.avi(将检测结果整合成视频文件)
在这里插入图片描述

4.3 demo.py 自定义修改

(1)测试自己的视频文件

复制demo.py文件并重命名为demo_video.py,代码做如下修改:

"""
2021.08.16
author:alian
function: 
Ultra-Fast-Lane-Detection 测试视频文件并保存结果为视频
"""

import torch, os
import cv2
from model.model import parsingNet
from utils.common import merge_config
from utils.dist_utils import dist_print
import torch
import scipy.special, tqdm
import numpy as np
import torchvision.transforms as transforms
from data.dataset import LaneTestDataset
from data.constant import culane_row_anchor, tusimple_row_anchor

if __name__ == "__main__":
    torch.backends.cudnn.benchmark = True

    args, cfg = merge_config()

    dist_print('start testing...')
    assert cfg.backbone in ['18', '34', '50', '101', '152', '50next', '101next', '50wide', '101wide']

    if cfg.dataset == 'CULane':
        cls_num_per_lane = 18
    elif cfg.dataset == 'Tusimple':
        cls_num_per_lane = 56
    else:
        raise NotImplementedError

    net = parsingNet(pretrained=False, backbone=cfg.backbone, cls_dim=(cfg.griding_num + 1, cls_num_per_lane, 4),
                     use_aux=False).cuda()  # we dont need auxiliary segmentation in testing

    state_dict = torch.load(cfg.test_model, map_location='cpu')['model']
    compatible_state_dict = {}
    for k, v in state_dict.items():
        if 'module.' in k:
            compatible_state_dict[k[7:]] = v
        else:
            compatible_state_dict[k] = v

    net.load_state_dict(compatible_state_dict, strict=False)
    net.eval()

    img_transforms = transforms.Compose([
        # transforms.CenterCrop((590,1640)),
        transforms.Resize((288, 800)),
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
    ])

    cap = cv2.VideoCapture("******.avi")  # 读取视频文件
    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
    rval, frame = cap.read()
    frame = frame[490:1080, 0:1640, :]
    vout = cv2.VideoWriter('output.avi', fourcc, 30.0, (frame.shape[1], frame.shape[0]))  # 结果保存
    print("w= {},h = {}".format(cap.get(3), cap.get(4)))
    from PIL import Image

    print('加载CUDA是否成功:', torch.cuda.is_available())
    while 1:
        rval, frame = cap.read()
        if rval == False:
            break
        frame = frame[490:1080, 0:1640, :]
        img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img_ = Image.fromarray(img)
        imgs = img_transforms(img_)
        imgs = imgs.unsqueeze(0)
        imgs = imgs.cuda()
        with torch.no_grad():
            out = net(imgs)

        col_sample = np.linspace(0, 800 - 1, cfg.griding_num)
        col_sample_w = col_sample[1] - col_sample[0]

        out_j = out[0].data.cpu().numpy()
        out_j = out_j[:, ::-1, :]
        prob = scipy.special.softmax(out_j[:-1, :, :], axis=0)
        idx = np.arange(cfg.griding_num) + 1
        idx = idx.reshape(-1, 1, 1)
        loc = np.sum(prob * idx, axis=0)
        out_j = np.argmax(out_j, axis=0)
        loc[out_j == cfg.griding_num] = 0
        out_j = loc

        for i in range(out_j.shape[1]):
            if np.sum(out_j[:, i] != 0) > 2:
                for k in range(out_j.shape[0]):
                    if out_j[k, i] > 0:
                        ppp = (
                        int(out_j[k, i] * col_sample_w * frame.shape[1] / 800) - 1, int(frame.shape[0] - k * 20) - 1)
                        cv2.circle(frame, ppp, 5, (0, 255, 0), -1)
        vout.write(frame)

    vout.release()

在终端执行指令:

python demo_video.py configs/tusimple.py --test_model tusimple_18.pth 

在根目录下生成output.avi测试结果文件

(2)测试自己的图片文件夹并保存检测结果图

复制demo.py并重命名为demo_custom.py,代码修改如下:

"""
2021.08.16
author:alian
function: 测试自己的数据集,并保存成检测结果图
"""
import torch, os, cv2
from model.model import parsingNet
from utils.common import merge_config
from utils.dist_utils import dist_print
import torch
import scipy.special, tqdm
import numpy as np
import torchvision.transforms as transforms
from data.dataset import LaneTestDataset
from data.constant import culane_row_anchor, tusimple_row_anchor

# 指定测试的配置信息
backbone = '18'  # 骨干网络
dataset = '11'  # 数据集类型
griding_num = 100  # 网格数
# test_model = 'tusimple_18.pth'  # 预训练模型路径 tusimple_18.pth
test_model = r'D:\Alian\Ultra-Fast-Lane-Detection-master\log\20210812_201601_lr_4e-04_b_32\ep099.pth'  # 自训练模型路径
# data_root = r'D:\Alian\Ultra-Fast-Lane-Detection-master\TUSIMPLEROOT'  # 开源数据集测试路径
data_root = r'D:\Alian\Ultra-Fast-Lane-Detection-master\test_img\test'  # 自定义测试路径
data_save = r'D:\Alian\Ultra-Fast-Lane-Detection-master\test_img\out'  # 保存检测结果图路径


import torch
from PIL import Image
import os
import numpy as np
import cv2
import glob


def loader_func(path):
    return Image.open(path)


class TestDataset(torch.utils.data.Dataset):
    def __init__(self, path, img_transform=None):
        super(TestDataset, self).__init__()
        self.path = path
        self.img_transform = img_transform
        # self.list:储存测试图片的相对路径 clips/0601/1494452577507766671/20.jpg\n

    def __getitem__(self, index):
        name = glob.glob('%s/*.jpg'%self.path)[index]
        img = loader_func(name)

        if self.img_transform is not None:
            img = self.img_transform(img)
        return img, name

    def __len__(self):
        return len(self.list)

if __name__ == "__main__":
    torch.backends.cudnn.benchmark = True  # 加速

    # args, cfg = merge_config()   # 用终端指定配置信息
    dist_print('start testing...')
    assert backbone in ['18', '34', '50', '101', '152', '50next', '101next', '50wide', '101wide']

    if dataset == 'CULane':
        cls_num_per_lane = 18
    elif dataset == 'Tusimple':
        cls_num_per_lane = 56
    else:
        # raise NotImplementedError
        cls_num_per_lane = 56

    net = parsingNet(pretrained=False, backbone=backbone, cls_dim=(griding_num + 1, cls_num_per_lane, 4),
                                    use_aux=False).cuda() # we dont need auxiliary segmentation in testing

    state_dict = torch.load(test_model, map_location='cpu')['model']
    compatible_state_dict = {}
    for k, v in state_dict.items():
        if 'module.' in k:
            compatible_state_dict[k[7:]] = v
        else:
            compatible_state_dict[k] = v

    net.load_state_dict(compatible_state_dict, strict=False)
    net.eval()
    # 图像格式统一:(288, 800),图像张量,归一化
    img_transforms = transforms.Compose([
        transforms.Resize((288, 800)),
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
    ])
    if dataset == 'CULane':
        splits = ['test0_normal.txt', 'test1_crowd.txt', 'test2_hlight.txt', 'test3_shadow.txt', 'test4_noline.txt', 'test5_arrow.txt', 'test6_curve.txt', 'test7_cross.txt', 'test8_night.txt']
        datasets = [LaneTestDataset(data_root,os.path.join(data_root, 'list/test_split/'+split),img_transform = img_transforms) for split in splits]

        img_w, img_h = 1640, 590
        row_anchor = culane_row_anchor
    elif dataset == 'Tusimple':
        splits = ['test.txt']
        datasets = [LaneTestDataset(data_root,os.path.join(data_root, split),img_transform = img_transforms) for split in splits]
        img_w, img_h = 1280, 720
        row_anchor = tusimple_row_anchor
    else:  # 自定义数据集
        # raise NotImplementedError
        datasets = TestDataset(data_root, img_transform=img_transforms)
        img_w, img_h = 1280, 720
        row_anchor = tusimple_row_anchor

    for dataset in zip(datasets): # splits:图片列表 datasets:统一格式之后的数据集
        loader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle = False, num_workers=1)  # 加载数据集
        # fourcc = cv2.VideoWriter_fourcc(*'MJPG')
        # print(split[:-3]+'avi')
        # vout = cv2.VideoWriter(split[:-3]+'avi', fourcc, 30.0, (img_w, img_h))  # 保存结果为视频文件
        for i, data in enumerate(tqdm.tqdm(loader)):  # 进度条显示进度
            imgs, names = data  # imgs:图像张量,图像相对路径:
            imgs = imgs.cuda()  # 使用GPU
            with torch.no_grad():  # 测试代码不计算梯度
                out = net(imgs)  # 模型预测 输出张量:[1,101,56,4]

            col_sample = np.linspace(0, 800 - 1, griding_num)
            col_sample_w = col_sample[1] - col_sample[0]


            out_j = out[0].data.cpu().numpy()  # 数据类型转换成numpy [101,56,4]
            out_j = out_j[:, ::-1, :]  # 将第二维度倒着取[101,56,4]
            prob = scipy.special.softmax(out_j[:-1, :, :], axis=0)  # [100,56,4]softmax 计算(概率映射到0-1之间且沿着维度0概率总和=1)
            idx = np.arange(griding_num) + 1  # 产生 1-100
            idx = idx.reshape(-1, 1, 1)  # [100,1,1]
            loc = np.sum(prob * idx, axis=0)  # [56,4]
            out_j = np.argmax(out_j, axis=0)  # 返回最大值的索引
            loc[out_j == griding_num] = 0  # 若最大值的索引=griding_num,归零
            out_j = loc  # [56,4]

            # import pdb; pdb.set_trace()
            vis = cv2.imread(os.path.join(data_root,names[0]))  # 读取图像 [720,1280,3]
            for i in range(out_j.shape[1]):  # 遍历列
                if np.sum(out_j[:, i] != 0) > 2:  # 非0单元格的数量大于2
                    sum1 = np.sum(out_j[:, i] != 0)
                    for k in range(out_j.shape[0]):  # 遍历行
                        if out_j[k, i] > 0:
                            ppp = (int(out_j[k, i] * col_sample_w * img_w / 800) - 1, int(img_h * (row_anchor[cls_num_per_lane-1-k]/288)) - 1 )
                            cv2.circle(vis,ppp,5,(0,255,0),-1)
            # 保存检测结果图
            cv2.imwrite(os.path.join(data_save,os.path.basename(names[0])),vis)

        # 保存视频结果(注释掉)
        #     vout.write(vis)
        #
        # vout.release()

测试结果图保存在D:\Alian\Ultra-Fast-Lane-Detection-master\test_img\out文件夹下,但是预训练模型在笔者自定义的数据集测试结果并不理想,还是重新训练自己的数据集可能结果会更加理想。
在这里插入图片描述

5 训练自定义数据库

5.1 数据集准备

用labelme完成数据标注得到原始图片以及对应的标注文件.json(这里笔者不做过多的赘述),分别放在两个文件夹下:
在这里插入图片描述
生成实例掩膜图像,即开源数据中黑黑的什么也看不到的图像,代码如下:

"""
2021.8.16
author:alian
function:
根据labelme标注的文件生成实例掩膜
"""

import argparse
import glob
import json
import os
import os.path as ops

import cv2
import numpy as np


def init_args():
    """

    :return:
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--img_dir', type=str, help='The origin path of image')
    parser.add_argument('--json_dir', type=str, help='The origin path of json')

    return parser.parse_args()

# 获得原始图像(.png),二值化图像以及实例分割图像
def process_json_file(img_path, json_path, instance_dst_dir):
    """
    :param img_path:
    :param ori_dst_dir:
    :param binary_dst_dir:
    :param instance_dst_dir:
    :return:
    """

    assert ops.exists(img_path), '{:s} not exist'.format(img_path)
    image = cv2.imread(img_path, cv2.IMREAD_COLOR)
    binary_image = np.zeros([image.shape[0], image.shape[1]], np.uint8)
    instance_image = np.zeros([image.shape[0], image.shape[1]], np.uint8)
    with open(json_path, 'r',encoding='utf8') as file:
        info_dict = json.load(file)
        for ind,info in enumerate(info_dict['shapes']):
            contours = info['points']
            contours = np.array(contours,dtype=int)
            # 绘制多边形
            cv2.fillPoly(binary_image, [contours], (255, 255, 255))
            cv2.fillPoly(instance_image, [contours], (ind, ind, ind)) #  * 50 + 20

        instance_image_path = img_path.replace(os.path.dirname(img_path),instance_dst_dir)
        cv2.imwrite(instance_image_path.replace('.jpg','.png'), instance_image)  # 实例分割图像

# 训练库构建
def process_tusimple_dataset(src_dir,json_dir):
    """

    :param src_dir:
    :return:
    """
    traing_folder_path = ops.join(os.path.dirname(src_dir), 'training')

    os.makedirs(traing_folder_path, exist_ok=True)
    
    gt_instance_dir = ops.join(traing_folder_path, 'label')

    os.makedirs(gt_instance_dir, exist_ok=True)

    for img_path in glob.glob('{:s}/*.jpg'.format(src_dir)):
        json_path = img_path.replace(src_dir,json_dir).replace('.jpg','.json')
        process_json_file(img_path, json_path, gt_instance_dir)
    return


if __name__ == '__main__':
    args = init_args()
    # 方法1:在终端指定配置信息
    # process_tusimple_dataset(args.img_dir,args.json_dir)  # 在终端指定配置信息
    # 方法2:直接在代码中输入
    img_dir = r'./pic'  # 原始图片路径
    json_dir = r'./json'  # 标注文件路径
    process_tusimple_dataset(img_dir,json_dir)

在这里插入图片描述

5.2 开始训练

打开./data/dataset.py在最后加入如下代码,类ClsDataset用来生成加载自定义数据集

# 加载自定义的数据集
class ClsDataset(torch.utils.data.Dataset):
    def __init__(self, path, img_transform=None, target_transform=None, simu_transform=None, griding_num=50,
                 load_name=False,
                 row_anchor=None, use_aux=False, segment_transform=None, num_lanes=4):
        super(ClsDataset, self).__init__()
        self.img_transform = img_transform
        self.target_transform = target_transform
        self.segment_transform = segment_transform
        self.simu_transform = simu_transform
        self.path = path
        self.griding_num = griding_num
        self.load_name = load_name
        self.use_aux = use_aux
        self.num_lanes = num_lanes

        self.row_anchor = row_anchor
        self.row_anchor.sort()

    def __getitem__(self, index):  # 获得图像数组
        labels = glob.glob('%s/label/*.png'%self.path)
        label_path = labels[index]
        label = loader_func(label_path)

        imgs = glob.glob('%s/pic/*.jpg'%self.path)
        img_path = imgs[index]
        img = loader_func(img_path)  # 读取图像

        if self.simu_transform is not None:
            img, label = self.simu_transform(img, label)
        lane_pts = self._get_index(label)
        # get the coordinates of lanes at row anchors

        w, h = img.size
        cls_label = self._grid_pts(lane_pts, self.griding_num, w)
        # make the coordinates to classification label
        if self.use_aux:
            assert self.segment_transform is not None
            seg_label = self.segment_transform(label)

        if self.img_transform is not None:
            img = self.img_transform(img)

        if self.use_aux:
            return img, cls_label, seg_label
        if self.load_name:
            return img, cls_label, img_name

        return img, cls_label

    def __len__(self):
        return len(glob.glob('%s/label/*.png'%self.path))

    def _grid_pts(self, pts, num_cols, w):  # 获得网格数
        # pts : numlane,n,2
        num_lane, n, n2 = pts.shape
        col_sample = np.linspace(0, w - 1, num_cols)

        assert n2 == 2
        to_pts = np.zeros((n, num_lane))
        for i in range(num_lane):
            pti = pts[i, :, 1]
            to_pts[:, i] = np.asarray(
                [int(pt // (col_sample[1] - col_sample[0])) if pt != -1 else num_cols for pt in pti])
        return to_pts.astype(int)

    def _get_index(self, label):
        w, h = label.size

        if h != 288:
            scale_f = lambda x: int((x * 1.0 / 288) * h)
            sample_tmp = list(map(scale_f, self.row_anchor))

        all_idx = np.zeros((self.num_lanes, len(sample_tmp), 2))
        for i, r in enumerate(sample_tmp):
            label_r = np.asarray(label)[int(round(r))]
            for lane_idx in range(1, self.num_lanes + 1):
                pos = np.where(label_r == lane_idx)[0]
                if len(pos) == 0:
                    all_idx[lane_idx - 1, i, 0] = r
                    all_idx[lane_idx - 1, i, 1] = -1
                    continue
                pos = np.mean(pos)
                all_idx[lane_idx - 1, i, 0] = r
                all_idx[lane_idx - 1, i, 1] = pos

        # data augmentation: extend the lane to the boundary of image

        all_idx_cp = all_idx.copy()
        for i in range(self.num_lanes):
            if np.all(all_idx_cp[i, :, 1] == -1):
                continue
            # if there is no lane

            valid = all_idx_cp[i, :, 1] != -1
            # get all valid lane points' index
            valid_idx = all_idx_cp[i, valid, :]
            # get all valid lane points
            if valid_idx[-1, 0] == all_idx_cp[0, -1, 0]:
                # if the last valid lane point's y-coordinate is already the last y-coordinate of all rows
                # this means this lane has reached the bottom boundary of the image
                # so we skip
                continue
            if len(valid_idx) < 6:
                continue
            # if the lane is too short to extend

            valid_idx_half = valid_idx[len(valid_idx) // 2:, :]
            p = np.polyfit(valid_idx_half[:, 0], valid_idx_half[:, 1], deg=1)
            start_line = valid_idx_half[-1, 0]
            pos = find_start_pos(all_idx_cp[i, :, 0], start_line) + 1

            fitted = np.polyval(p, all_idx_cp[i, pos:, 0])
            fitted = np.array([-1 if y < 0 or y > w - 1 else y for y in fitted])

            assert np.all(all_idx_cp[i, pos:, 1] == -1)
            all_idx_cp[i, pos:, 1] = fitted
        if -1 in all_idx[:, :, 0]:
            pdb.set_trace()
        return all_idx_cp  # [4,56,2]

打开./data/dataloder.py,修改else:如下:

    if dataset == 'CULane':
        train_dataset = LaneClsDataset(data_root,
                                           os.path.join(data_root, 'list/train_gt.txt'),
                                           img_transform=img_transform, target_transform=target_transform,
                                           simu_transform = simu_transform,
                                           segment_transform=segment_transform, 
                                           row_anchor = culane_row_anchor,
                                           griding_num=griding_num, use_aux=use_aux, num_lanes = num_lanes)
        cls_num_per_lane = 18

    elif dataset == 'Tusimple':
        train_dataset = LaneClsDataset(data_root,
                                           os.path.join(data_root, 'train_gt.txt'),
                                           img_transform=img_transform, target_transform=target_transform,
                                           simu_transform = simu_transform,
                                           griding_num=griding_num, 
                                           row_anchor = tusimple_row_anchor,
                                           segment_transform=segment_transform,use_aux=use_aux, num_lanes = num_lanes)
        cls_num_per_lane = 56
    else:  # 自定义数据集
        # raise NotImplementedError
        train_dataset = ClsDataset(data_root,
                                       img_transform=img_transform, target_transform=target_transform,
                                       simu_transform=simu_transform,
                                       griding_num=griding_num,
                                       row_anchor=tusimple_row_anchor,
                                       segment_transform=segment_transform, use_aux=use_aux, num_lanes=num_lanes)
        cls_num_per_lane = 56

打开配置文件./configs/tusimple.py,修改配置信息如下:

# DATA
# dataset= 'Tusimple'  # 开源数据集
dataset= 'realway'  # 自定义数据集
# data_root = 'D:/Alian/Ultra-Fast-Lane-Detection-master/TUSIMPLEROOT/'  # 开源数据集
data_root = 'D:/Alian/Ultra-Fast-Lane-Detection-master/realway/'  # 自定义

# TRAIN
epoch = 100
batch_size = 32
optimizer = 'Adam'    #['SGD','Adam']
# learning_rate = 0.1
learning_rate = 4e-4
weight_decay = 1e-4
momentum = 0.9

scheduler = 'cos'     #['multi', 'cos']
# steps = [50,75]
gamma  = 0.1
warmup = 'linear'
warmup_iters = 100

# NETWORK
backbone = '18'
griding_num = 100
use_aux = True

# LOSS
sim_loss_w = 1.0
shp_loss_w = 0.0

# EXP
note = ''

log_path = 'D:/Alian/Ultra-Fast-Lane-Detection-master/log/'  # 模型保存路径

# FINETUNE or RESUME MODEL PATH
finetune = None
resume = None

# TEST
test_model = None
test_work_dir = None

num_lanes = 4

在终端输入训练指令:

python train.py configs/tusimple.py

笔者遇到的报错:

Traceback (most recent call last):
  File "train.py", line 152, in <module>
    train(net, train_loader, loss_dict, optimizer, scheduler,logger, epoch, metric_dict, cfg.use_aux)
  File "train.py", line 68, in train
    loss = calc_loss(loss_dict, results, logger, global_step)  # 构建损失函数
  File "train.py", line 49, in calc_loss
    logger.add_scalar('loss/'+loss_dict['name'][i], loss_cur, global_step)
  File "D:\Alian\Ultra-Fast-Lane-Detection-master\utils\dist_utils.py", line 142, in add_scalar
    super(DistSummaryWriter, self).add_scalar(*args, **kwargs)
  File "D:\Anaconda3\envs\lane\lib\site-packages\torch\utils\tensorboard\writer.py", line 345, in add_scalar
    scalar(tag, scalar_value), global_step, walltime)
  File "D:\Anaconda3\envs\lane\lib\site-packages\torch\utils\tensorboard\summary.py", line 247, in scalar
    scalar = make_np(scalar)
  File "D:\Anaconda3\envs\lane\lib\site-packages\torch\utils\tensorboard\_convert_np.py", line 23, in make_np
    return _prepare_pytorch(x)
  File "D:\Anaconda3\envs\lane\lib\site-packages\torch\utils\tensorboard\_convert_np.py", line 31, in _prepare_pytorch
    x = x.cpu().numpy()
RuntimeError: CUDA error: device-side assert triggered
  0%|                                                                                           | 0/32 [00:19<?, ?it/s]

上述错误是由于数据集的类别数与指定的类别数不一致导致的,解决方法:
在这里插入图片描述
上述的检查代码如下:

import os
import cv2

path = r'D:\Alian\Ultra-Fast-Lane-Detection-master\realway\label'  # 生成的实例掩膜图像路径,即漆黑什么也看不见的图像
a = os.listdir(path)
print(a)
for i in a:
    img = cv2.imread(os.path.join(path,i),-1)
    print(set((img.flatten())))

成功训练在终端显示如下:
在这里插入图片描述

5.3 可视化训练过程

tensorboard --logdir=D:\Alian\Ultra-Fast-Lane-Detection-master\log\20210816_081017_lr_4e-04_b_32  # events.out.tfevents保存路径

在这里插入图片描述

后记

综上基本就实现了Ultra-Fast-Lane-Detection 的复现

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Lane】 Ultra-Fast-Lane-Detection 复现 的相关文章

  • Fast Planner——代码解读参考资料整理

    1 地图部分 1 1 EGO Swarm代码解读 地图部分 参数解读 主要函数解读 1 2 EGO Swarm代码阅读笔记之GridMap类 1 3 EGO PLANNER代码阅读 xff08 地图部分 xff09 1 4 欧几里得距离转换
  • PX4的中间件Fast DDS

    本文参考官网 xff1a RTPS DDS Interface PX4 Fast RTPS DDS Bridge PX4 User Guide 版本说明 xff1a PX4固件版本 xff1a 1 13 0d 自驾仪 xff1a PIXHA
  • PX4模块设计之六:PX4-Fast RTPS(DDS)简介

    64 TOC PX4模块设计之六 xff1a PX4 Fast RTPS DDS 简介 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分析内部模块功能设计 PX4 Fast RTPS DDS 具有实时发布 订阅uORB消息接口
  • windows配置tensorflow python object detection 环境

    option 1 pip install lt binary gt pip install upgrade https storage googleapis com tensorflow mac cpu tensorflow 1 12 0
  • 【Lane】 Ultra-Fast-Lane-Detection 复现

    引言 笔者Ultra Fast Lane Detection专栏链接 x1f517 导航 xff1a Lane Ultra Fast Lane Detection 复现 Lane Ultra Fast Lane Detection xff0
  • 【Lane】Ultra-Fast-Lane-Detection(1)自定义数据集训练

    引言 笔者Ultra Fast Lane Detection专栏链接 x1f517 导航 xff1a Lane Ultra Fast Lane Detection 复现 Lane Ultra Fast Lane Detection xff0
  • FasterTransformer 安装

    第一 安装TensorRT FasterTransformer 支持cuda10 0 所以TensorRT也下cuda10 0对应版本 1 下载TensorRT https developer nvidia com nvidia tenso
  • 检测用户所在国家/地区的最快方法

    我需要检测用户的国家 地区并按他 她的国家 地区显示网站的语言 土耳其人用土耳其语 其他人用英语 我怎样才能以最快的方式做到这一点 表现对我来说很重要 我在看IPInfoDB 的 API 还有更好的选择吗 我使用的是PHP 对于可能在 20
  • 检测图像是否嵌入

    我开始编写自己的图像主机 但我有一个小问题 如果您通过浏览器直接查看链接 例如 Domain com img 123 我想显示一个 HTML 页面 如果您通过以下方式嵌入链接 我想显示一个图像 img src Domain com img
  • 如何在 PHP 中检查重复的电子邮件地址,考虑 Gmail([电子邮件受保护])

    如何在 PHP 中检查重复的电子邮件地址 考虑到 Gmail 自动标签和标点符号的可能性吗 例如 我希望这些地址被检测为重复 email protected email protected email protected email pro
  • 检测 iPhone 中的 GPS 硬件

    我想知道如何检测 iPhone 中是否存在 GPS 硬件 你不能detect硬件 至少不是通过官方SDK 但是 您可以interact从您的应用程序 通过 CoreLocation 框架 使用它 即从中获取信息 自 iPhone OS 2
  • Dialogflow,从音频中检测意图

    我正在尝试将音频文件发送到对话流 API 进行意图检测 我已经有一个工作得很好的代理 但只能处理文本 我正在尝试添加音频功能 但没有成功 我正在使用此页面中提供的示例 Java https cloud google com dialogfl
  • 在 C# 中检测多个同时按键

    我希望通过检测某些无法键入的组合键 转义序列 的按键来模拟 C 中的串行通信的超级终端功能 例如 Ctrl C Ctrl Z 等 我知道这些键有其 ASCII等价物 并且可以按原样传输 但我在检测多个按键时遇到问题 我提供一些代码作为参考
  • Apache代理负载均衡后端服务器故障检测

    这是我的场景 由我的前任设计 两台 Apache 服务器为多个混合后端 Web 服务器 Apache IIS Tomcat 等 提供反向代理服务 有些网站我们有多个后端 Web 服务器 在这些情况下 我们会执行以下操作
  • 如何判断 HTML5 音频元素是否正在使用 Javascript 播放

    我有一个audio网页中的元素 我想确保用户在离开页面时不会仍在播放它 我怎样才能确定audio页面卸载时元素未播放 到目前为止 我有以下代码 但它似乎不起作用 卸载报告时弹出的对话框playing is false即使音频正在播放
  • 如何从 silverlight 应用程序检测操作系统?

    我有一个 Silverlight3 应用程序 旨在在 Windows 和 Mac OS 环境上运行 我想在运行时知道我的应用程序是在 Windows 还是 Mac 上运行 这样我就可以根据用户在他们选择的操作系统中习惯的方式进行一些调整 例
  • 每个请求上的 51Degrees 重新加载会减慢 ASP.NET MVC 的速度

    添加 51Degrees 移动检测库后 我的 ASP NET MVC 3 项目速度慢得像爬行一样 51Degrees 日志文件定义为
  • 如何识别“hw.machine”标识符可靠?

    我正在寻找最官方的来源来完成 维护此方法 NSString platformString NSString platform self platform if platform isEqualToString iPhone1 1 retur
  • 从网络浏览器中检测和访问 USB 设备 - 即使用插件

    是否可以通过插件 activeX Java 或 Flex 编写一个能够检测从 USB 设备通道读取数据流的浏览器插件 我做了一些研究 但没有找到答案 http support microsoft com kb 832678 http sup
  • 改进 cvFindChessboardCorners

    不幸的是 我无法找到我的问题的任何解决方案 我想做的是使用 OpenCV 方法改进结果cvFindChessboardCorners为了能够实现更好的相机校准 因为我认为这就是为什么我在不扭曲 校正图像时得到较差结果的原因 就像我之前的问题

随机推荐

  • 虚拟机分配的硬盘太大怎么办?

    虚拟机分配的硬盘太大怎么办 xff1f 虚拟机分配的硬盘太大怎么办 xff1f 文章来源说明 xff1a 开始1 首先需要将虚拟机中多余的硬盘空间删除 xff0c 在此电脑中右键管理 xff0c 然后在磁盘管理中右键有多余空间的磁盘进行压缩
  • QT界面窗口的显示和隐藏,关闭

    这里写目录标题 QT窗口的显示和隐藏 xff1a 1 隐藏窗口1 1 介绍 xff1a 2 显示窗口2 1 介绍 xff1a 3 关闭窗口常用函数有 xff1a QT窗口的显示和隐藏 xff1a 1 隐藏窗口 span class toke
  • QT的中文显示乱码问题解决

    QT的中文显示乱码问题解决 QT的中文显示乱码问题解决 xff1a 1 查看源文件的编码格式 xff0c 有必要的话转换源文件的编码格式再重新编译运行尝试汉字能否正常显示 2 在代码里面解决 xff1a 3 用法 xff1a QT的中文显示
  • 0.9 - GPIO寄存器的C语言映射与STM32库函数雏形构建思路

    首先 xff0c 从参考手册可知 xff0c 程序存储器 xff08 flash xff09 数据存储器 SRAM 寄存器 外设控制 和输入输出端口被组织在同一个4GB的线性地址空间内 数据字节以小端格式存放在存储器中 一个字里的最低地址字
  • Linux文件/文件夹建立软硬链接

    建立软连接 xff1a sudo ln s home spike Downloads redis src redis server usr local bin redis server 源文件 链接到 目标文件 xff0c 这两个文件目录都
  • Linux中记录终端(Terminal)输出到文本文件四种方法

    Linux中记录终端 xff08 Terminal xff09 输出到文本文件 Linux中记录终端 xff08 Terminal xff09 输出到文本文件 一 xff0c 如何把命令运行的结果保存到文件当中 二 command gt f
  • C++ 标准库头文件汇集:

    C 43 43 标准库头文件汇集 xff1a C 43 43 标准库的接口由下列头文件的汇集定义 C 43 43 标准库头文件汇集 xff1a 概念库协程库工具库动态内存管理数值极限错误处理字符串库容器库迭代器库范围库算法库数值库本地化库输
  • C++开源库列表总结记录

    开源 C 43 43 库列表 前言包管理器库音频 音频指纹格式标签CD 性能测试 通信 并发 配置 XMLJSONYAMLTOMLHOCONCSS容器 密码学 数据库 嵌入语言绑定 嵌入式 实时 文件元数据 金融计算 游戏引擎架构 通用多媒
  • C++转义序列和操作符优先级

    C 43 43 转义序列和操作符优先级 1 转义序列 xff1a 2 C 43 43 运算符优先级注解 1 转义序列 xff1a 转义序列 描述 表示 简单转义序列 39 单引号 ASCII 编码中为字节 0x27 34 双引号 ASCII
  • PX4:Policy “CMP0097“ is not known to this version of CMake.

    make px4 fmu v3 时报的错 CMake版本的问题 由https blog csdn net zhizhengguan article details 118380965推测 xff0c 删除cmake policy也没事 ma
  • 安装Anaconda3后再安装ROS(用于PX4)

    记录一下安装anaconda后再安装ROS xff0c 方便未来找错误 出现no module wstool 仔细观察报错信息发现调用的库都在anaconda3 lib python3 7里面了 随后按照https www cnblogs
  • Offboard仿真时出现CMD: Unexpected command 176, result 0

    在用PX4 43 gazebo 43 ROS仿真offboard例程时 xff0c 如果出现以下问题 xff1a 运行以下命令 xff1a roslaunch mavros px4 launch fcu url span class tok
  • Offboard例程的python版本

    因为python的库很丰富 xff0c 有现成的解方程库 xff0c 比如sympy 自己写了一份python版本的自动起飞2m的程序 假设自定义的包名为offb xff0c 在offb下新建scripts文件夹 xff0c 将py文件放在
  • 子类与父类构造函数调用顺序

    子类与父类构造函数调用顺序 构造函数 当创建子类对象时 构造函数的调用顺序 xff1a 静态数据成员的构造函数 gt 父类的构造函数 gt 非静态的数据成员的构造函数 gt 自己的构造函数 注意 无论创建几个对象 该类的静态成员只构建一次
  • 0.1- 机械加工工艺-----切削加工基础

    1 钳工 xff1a 通过工人手持工具进行切削加工 机械加工 xff1a 采用不同的机床 xff08 如车床 铣 床 刨床 磨床 钻床等 xff09 对工 件进行切削加工 2 零件几何参数 xff1a 1 宏观几何参数 xff1a 包括 x
  • 判断当前机器的字节序是大端还是小端?

    字节序 字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序 大端字节序 xff08 Big endian xff09 大端存储模式是指数据的高字节保存在内存的低地址中 xff0c 而数据的低字节保存在内存的高地址中 小端字
  • Qt简易计算器实现复数运算绘图等等

    太久没更新博客了前段时间弄了个计算器 实现了加减乘除复数 带记忆 绘图计算二维图形等功能 先简单讲解下我代码的分块 用图片描述虽然画的丑 实现效果图片 代码放心使用转载请通知 1 Ui 2 在Maindow 类实现计算 maindow h
  • 【tensorboard】可视化events.out.tfevents文件

    介绍 笔者训练Mask RCNN模型时 xff0c 在生成权重 xff08 h5 xff09 文件的同时会实时更新events out tfevents szfj文件 xff0c 通过tensorboard可视化events out tfe
  • 【tensorflow】缺少libcudart.so.11.0和libcudnn.so.8解决方法

    问题 xff1a 安装tensorflow gpu xff0c 在测试是否调用GPU时出现如下问题 xff1a Could not load dynamic library libcudart so 11 0 dlerror libcuda
  • 【Lane】 Ultra-Fast-Lane-Detection 复现

    引言 笔者Ultra Fast Lane Detection专栏链接 x1f517 导航 xff1a Lane Ultra Fast Lane Detection 复现 Lane Ultra Fast Lane Detection xff0