darknet训练自己的数据集

2023-05-16

参考博客https://blog.csdn.net/lilai619/article/details/79695109

 

系统环境 Ubuntu 16.04

-1.在制作数据时最好先将所有图片重新命名,这样会方便后面数据集的制作,比如这次我演示的是只训练一个杯子(也就是训练一个类),那么我把所有的图片的名字都改为bottle_*.jpg。这可以自己写一个脚本去重命名。制作好后如下图

 

0.先使用labelimg标注图片数据,把生成的xml文件放在同一个文件夹,比如名为xml

 

1.在自己喜欢的目录下新建一个文件夹,比如命名为voc_mybottle(因为自己要训练的数据是我的一个杯子)。在这个文件夹下新建一个名为images的文件(一定要是images,原因等下会说)。在新建一个叫labels的文件夹(一定要是labels)。把训练的所有图片放在images的文件夹中。(如第一张图)

2.为了方便我把images labels xml三个文件夹下,然后把下面这个python脚本放在同一个目录下然后执行,labels就会添加所有照片的labels.txt文件,和一个叫img_list.txt的文件,内容是所用图片的路径

#!/usr/bin/env python
# coding: utf-8

# In[3]:


import os

pre_path = os.getcwd()
print(pre_path)


# In[16]:


img_pre_path = pre_path + "/images"
print(img_pre_path)

IMG_txt = "img_list.txt"  
img_list = os.listdir(img_pre_path)

with open(IMG_txt, "w") as f:
    for index in img_list:
        img_path = img_pre_path + '/' + index
        print(img_path)
        f.write(img_path + '\n')
        
    


# In[39]:


import xml.etree.ElementTree as ET
xml_path = pre_path + '/xml'
label_pre_path = pre_path + '/labels'
xml_list = os.listdir(xml_path)
print(xml_path)
print(label_pre_path)
print(xml_list[3])
for index in xml_list:
    print(xml_path + '/' + index)


# In[41]:


classes = ["mybottle"]

def convert(size, box):
    print(size[0], size[1])
    dw = 1.0 / size[0]
    dh = 1.0 / size[1]
    x = (box[0] + box[1])/2.0
    y = (box[2] + box[3])/2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return (x,y,w,h)


def convert_xml(in_path, out_path):
    in_file = open(in_path)
    out_file = open(out_path, 'w')
    tree=ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    # w = int(size.find('width').text)
    # h = int(size.find('height').text)
    print("w,h", w, h)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
        bb = convert((w,h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


for index in xml_list:
    xml_file_path = xml_path + '/' +  index
    # print(index.split('.')[0])
    lable_txt_path = pre_path + '/labels/' + index.split('.')[0] + '.txt'
    print("xml:" + xml_file_path)
    print("label" + lable_txt_path)
    convert_xml(xml_file_path, lable_txt_path)

里面的内容是这样的

0 0.571875 0.500925925925926 0.3979166666666667 0.5851851851851853

代表物体的分类编号和两个坐标的xy在图片中的归一化的值

3.执行下面两句指令,使图片分成两份数据,分别为train和test两个数据的图片路径,18是把头18张图片归为train,19以后的图片归为test,这里自行修改

cat img_list.txt | head -n 18 > train_list.txt
cat img_list.txt | tail -n +19 > test_list.txt
~                                                     

4.根据官网提示我们要制作一个xxx.data的文件,用来给程序传递参数的。

根据自己的需求建立

比如我的是voc_mybottle.data 内容为


classes = 1 # 训练一个类
train =<path>/voc_mybottle/train_list.txt #path 自己电脑的路径
valid = <path>/voc_mybottle/test_list.txt
names = <path>/voc_mybottle/mybottle.names
backup = mybottle_backup      #自己在darknet下建立的mybottle_backup文件夹,用来放训练的模型


.names文件是用来存放分类的名字,在这里我只有一个mybottle的类,所以只有mybottle这行内容

5.修改关于训练的cfg文件,里面是关于网络的参数

因为这里我们用的是yolov3去训练voc格式数据,所以要修改darknet/cfg/yolov3-voc.cfg文件,为了方便我自己新创了一个mybottle_yolov3-voc.cfg文件。把yolov3-voc.cfg复制过来,改参数。主要改的参数是这些

按照需求改,这里可以去参考其他文章,这里不过多描述。

还有就是改网络结构,因为voc是有20个类,而我现在是只有一个类,所以要把网络调整。每个yolo层都有一个filter=75的参数(3*(num_class + 5)), 这里改成18(3×(1+5))。一共要改3处。

到这里数据就准备好了。

最后一部是下载预权重文件放在darknet文件夹下

wget https://pjreddie.com/media/files/darknet53.conv.74

安装官网训练的例子进行修改运行的参数

cfg/voc.data修改成自己创建的.data文件路径,cfg/yolov3-voc.cfg修改成自己创建的.cfg文件路径。执行就能训练了

运行界面

 

 

每默认100步保存一次模型,只保存十次模型,最后一次会被每次更新覆盖。

训练到此结束。


说一下我遇到的坑

在读取照片的时候遇到读取的labels中的文件不在images文件夹的问题。这很奇怪,于是我去找源码,发现一定要把图片的文件夹命名为images才能读取同一个目录下的labels文件夹中的文件

//data.c
void fill_truth_detection(char *path, int num_boxes, float *truth, int classes, int flip, float dx, float dy, float sx, float sy)
{
    char labelpath[4096];
    find_replace(path, "images", "labels", labelpath);
    find_replace(labelpath, "JPEGImages", "labels", labelpath);

    find_replace(labelpath, "raw", "labels", labelpath);
    find_replace(labelpath, ".jpg", ".txt", labelpath);
    find_replace(labelpath, ".png", ".txt", labelpath);
    find_replace(labelpath, ".JPG", ".txt", labelpath);
    find_replace(labelpath, ".JPEG", ".txt", labelpath);
    int count = 0;
    box_label *boxes = read_boxes(labelpath, &count);

第二个坑是训练好后,模型能识别物体,可是标签是错的

Loading weights from mybottle_backup/mybottle_yolov3-voc_200.weights...Done!
path/images/bottle_1.jpg: Predicted in 0.028537 seconds.
person: 89%
 

查了一下源码,发现原来是我用用了官网的测试图片的指令 detect 

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

 

// darknet.c
if (0 == strcmp(argv[1], "average")){
        average(argc, argv);
    } else if (0 == strcmp(argv[1], "yolo")){
        run_yolo(argc, argv);
    } else if (0 == strcmp(argv[1], "super")){
        run_super(argc, argv);
    } else if (0 == strcmp(argv[1], "lsd")){
        run_lsd(argc, argv);
    } else if (0 == strcmp(argv[1], "detector")){
        run_detector(argc, argv);
    } else if (0 == strcmp(argv[1], "detect")){
        float thresh = find_float_arg(argc, argv, "-thresh", .5);
        char *filename = (argc > 4) ? argv[4]: 0;
        char *outfile = find_char_arg(argc, argv, "-out", 0);
        int fullscreen = find_arg(argc, argv, "-fullscreen");
        test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);
    } else if (0 == strcmp(argv[1], "cifar")){
        run_cifar(argc, argv);
    } else if (0 == strcmp(argv[1], "go")){
        run_go(argc, argv);
    } else if (0 == strcmp(argv[1], "rnn")){
        run_char_rnn(argc, argv);
    } else if (0 == strcmp(argv[1], "coco")){
        run_coco(argc, argv);

 

可以看到当使用detect参数时会使用coco.data,所以应该是调用了coco.data的数据,查看coco.data,第一个类果然是person。

于是换回测试的指令使用test参数,(文件路径是自己的路径)

./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg

测试成功

(训练步数少,只是用来测试的,所以效果不好,别介意,哈哈哈哈)

但是这次以后只是用detect参数也回复正常了,不知道是什么原因。如果您知道,恳请赐教。 

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

darknet训练自己的数据集 的相关文章

随机推荐

  • Ubuntu中USB端口与外设绑定,ROS读取IMU模块数据

    目录 xff1a 1 根据设备ID绑定1 1 查看ID1 2 编写USB规则文件1 3 查看绑定结果 2 根据电脑USB口绑定2 1 找到USB端口名称2 2 编写绑定规则 3 通过ROS读数据 1 根据设备ID绑定 方法原理 xff1a
  • 实现外网Ping通WSL(网卡桥接方式实现)

    目录 xff1a 前言 xff1a 实现原理 xff1a 实现步骤1 开启hyper v2 编写桥接网络powershell脚本3 编写网络配置脚本 实现结果取消桥接最后 前言 xff1a 在我们经常和机器人打交道的这群人中有一个需求 xf
  • 如何在markdown中插入表情包

    我们平时经常使用markdown完成一些诸如博客的文档写作 xff0c 但是有时像我这种语言比较乏力的急需要在文档写作过程中插入表情包来完整的表达我想要表达的意思 xff0c 所以我去网上查了一下 xff0c 还真有 比如我想要表达开心即s
  • ROS多设备组网(WSL+miniPC+Nv Orin)

    目录 xff1a 前言硬件连接组网配置1 获取hostname和IP2 在主机添加从机的host信息3 在从机1中配置4 在从机2中配置 测试test1 话题订阅test2 rqt plot可视化传感器信息 最后 前言 实验室最近购买了两台
  • ZED 2i 双目-IMU标定

    目录 xff1a 前言IMU标定1 编译标定工具2 准备数据集3 标定 Camera IMU标定1 安装依赖2 编译Kaibr3 制作标定板下载标定板生成标定板target yaml文件 4 数据采集5 相机标定标定中遇到的问题问题1 xf
  • gazebo中给机器人添加16线激光雷达跑LIO-SAM

    目录 xff1a 前言1 下载雷达仿真包2 添加雷达支架描述文件3 添加雷达描述文件4 启动仿真5 添加IMU模块6 添加RGB D相机7 LIO SAM仿真安装依赖安装GTSAM编译LIO SAM运行 8 源码 遇到的问题1 error
  • ROS中的多线程使用

    目录 xff1a 单线程多线程订阅多个Topic xff0c 多个Spinner threads订阅一个Topic xff0c 多个Spinner threads订阅多个Topic xff0c 每个Subscriber一个Callback
  • 机器人端的图形界面ssh远程显示方案

    目录 xff1a 前言原理解析实现步骤机器人端 xff08 X client xff09 xff1a 1 安装一些必要的软件2 修改 96 etc ssh sshd config 96 中的四个地方 调试端 xff08 X server x
  • 报错 Key is stored in legacy trusted.gpg keyring

    目录 xff1a 1 找到警告相关源的key2 导出相应key到指定目录3 修改ros2源里指定加载key的路径 最近在安装ROS2的时候遇到一个关于密钥的报错 xff0c 这里记录一下 xff01 在 sudo apt update 的时
  • wsl中使用ROS工具rqt显示界面跑到窗口外面

    问题 xff1a 在WSL中使用ROS时确实会有一些小bug xff0c 比如下面这个 的rqt plot功能包时 xff0c 想通过rqt plot指令查看相应信息 xff0c 但是窗口弹出在窗口是空白的 xff0c 并且rqt那个功能界
  • RS雷达转Velodyne雷达数据Failed to find match for field ‘intensity‘

    目录 xff1a 问题分析解决 问题 因为目前很多SLAM框架支持的激光雷达都是Velodyne型号的 xff0c 对于速腾RS雷达的使用者来说 xff0c 需要对数据进行转换 xff0c 其实现在速腾的雷达已经支持输出XYZI和XYZIR
  • LIO-SAM中的mapOptmization

    前言 最近在学习LIO SAM源码的时候 xff0c 发现LIO SAM这套代码调用了比较多库的内置API xff0c 里面涉及的一些细节也比较多 xff0c 整个工程还是比较清晰的 xff0c 值得学习 xff01 LIO SAM这个框架
  • 使用D435i+Avia跑Fast-LIVO

    前言 最近Fast LIVO开源了 xff0c 之前看它的论文的时候发现效果很优秀 xff0c 于是用实验室现有的设备尝试一下 这里主要记录一下使用不带外触发功能的D435i 43 Avia跑Fast LIVO的过程 xff0c 为了适配代
  • CMakeList 中引用系统环境变量中的 include 文件,以及 lib 文件

    CMakeList 中引用系统环境变量中的 include 文件 xff0c 以及 lib 文件 cmake中对环境变量读写都是通过ENV前缀来访问环境变量 ENV ZLIB DIR 表示系统环境变量ZLIB DIR 所表示的路径 以ZLI
  • GroundTrue和里程计输出的位姿的参考坐标系不一致的情况

    这里写目录标题 前言数据集描述使用TF工具包获取使用Eigen库计算置换输出误差对比没做转换之前转换之后 前言 最近遇到一个数据集的ground true参考坐标和vSLAM输出的位姿的参考坐标不一样的问题 xff0c 记录一下 在之前参加
  • Protobuf报错CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):

    前言 Protobuf全称Protocol buffers xff0c 是Google研发的一种跨语言 跨平台的序列化结构的数据格式 xff0c 是一个灵活的 高效的用于序列化数据的协议 使用protobuf时 xff0c 既可以采用动态链
  • Ceres的自动求导实现原理剖析

    目录 数学原理实现原理总结 首先注意数值求导和自动求导在使用的时候的不同之处 实际上 xff0c 正是自动求导这个地方使用了类模板 xff0c 导致它不仅可以传入参数 xff0c 还可以传入Jet类型的数据 xff0c 从而实现了参数的雅可
  • SciPy 关于RBF插值出现Singular Matrix错误

    在使用SciPy的 RBFInterpolator 进行RBF模型插值时 xff0c 出现了Singular Matrix错误 xff0c 报错信息为 xff1a line 127 in build and solve system rai
  • Latex数学字体

    默认 mathsf mathtt mathit 花体 mathcal 空心体 mathbb
  • darknet训练自己的数据集

    参考博客https blog csdn net lilai619 article details 79695109 系统环境 Ubuntu 16 04 xff0d xff11 xff0e 在制作数据时最好先将所有图片重新命名 xff0c 这