3508|11

1366

帖子

6

TA的资源

版主

楼主
 

jeston nano使用Yolov4训练自己的数据集(一类物体) [复制链接]

 

RCSN

1. 制作自己的数据集

本次训练的目标是为了能够检测出一类不同的物体,即香砂六君丸的药品,如图所示:

该种物体采集27张(可加大),命名方式以数字形式进行命名

1.1 准备数据集

然后切换到darkent根目录,依次建立如下几个文件夹:

cd scripts

mkdir -p VOCdevkit && cd VOCdevkit

mkdir -p VOC2019  && cd VOC2019

mkdir -p Annotations && mkdir -p ImageSets && mkdir -p  JPEGImages && mkdir -p labels

1.2 打乱顺序并重命名

JPEGImages文件夹下的图像文件打乱顺序并重新命名.方法是执行如下的python脚本文件:

 

# -*- coding:utf-8 -*-

import os

import random

class ImageRename():

    def __init__(self):

        self.path = '/home/jetbot/darknet-master/scripts/VOCdevkit/VOC2019/JPEGImages'#图片所在文件夹

 

    def rename(self):

        filelist = os.listdir(self.path)

        random.shuffle(filelist)

        total_num = len(filelist)

        i = 0

        for item in filelist:

            if item.endswith('.jpg'):

                src = os.path.join(os.path.abspath(self.path), item)

                dst = os.path.join(os.path.abspath(self.path), '0000' + format(str(i), '0>3s') + '.jpg')

                os.rename(src, dst)

                print ('converting %s to %s ...' % (src, dst))

                i = i + 1

        print ('total %d to rename & converted %d jpgs' % (total_num, i))

 

if __name__ == '__main__':

    newname = ImageRename()

    newname.rename()

 

执行命令之后:

1.3 数据标注(labelImg)

该步骤用于对每张图片生成描述文件,我们需要认为指定图片里哪一块区域是我们要检测的物体.每张图片都要以一个xml文件进行描述.数据标注的工具很多,在这里我们选择labelImg.首先安装,在这里该插件对python版本有要求,python2和python3的安装方式不同,选择任意一种即可,区别在于最后执行过程.

若为python3,安装过程如下:

 sudo apt-get install pyqt5-dev-tools

 sudo pip3 install lxml

 cd darknet &&  mkdir -p software && cd software

 git clone https://github.com/tzutalin/labelImg.git

 cd labelImg

 make all(可不用)

 

若为python2,安装过程如下:

 sudo apt-get install pyqt4-dev-tools

 sudo pip install lxml

 cd darknet &&  mkdir -p software && cd software

 git clone https://github.com/tzutalin/labelImg.git

 cd labelImg

 make all(可不用)

 

至此,安装已完成,下面可以运行如下命令打开该软件进行标注了:

若为python3安装,则打开软件的方式为:

 python3 labelImg.py  #打开labelImg

 

若为python2安装,则打开软件的方式为

 python labelImg.py  #打开labelImg

 

软件界面如下:

然后点击左侧的"Open Dir"按键,选择我们存放数据图片的文件夹JPEGImages,如下:

然后点击"Open",之后会出现第一张图片,对于一张图片的标注,一般分如下几个步骤:

1)点击左侧的"Create \n RectBox"按键,然后找准我们要识别的物体,从左上角到右下角拖一个矩形,

2) 在弹出的窗口种创建标签,如下图所示,我们需要选择"watermenlon",如果不出现,要手动敲一个,添加进去,并选择,如果图片中有多个待识别的物体,则再此拉矩形框,并选择类别.

3) 选择完成后,点击保存或者键盘按"ctrl+s",则会在JPEGImages文件夹下生成对应00001.jpg的xml文件00001.xml.

4)按键盘"n"来进入下一张图片.

按照上述步骤依次进行,直到标注完毕.

: 若在标注过程中,有些图片比较模糊,我们可以不进行标注,直接进入下一张图片.

标注全部完成后,我们会在JPEGImages文件夹中看到jpg文件和xml文件共存,在这这里还需要删除我们之前没有标注的图片,它们不具备任何作用.所以就需要我们进行排查和清除,方法有两个,对于样本较少的,建议第一种:

打开文件夹,将文件夹水平方向缩小为只能包含两列,即左侧为jpg图片,右侧为xml文件,若某一行出现有两个jpg图片,则删除左边那个,不断向下拖动滑动条,直到尾断即完成了排查和删除.

import os

import os.path

h = 0

a = ''

b = ''

dele = []

pathh = "/home/jetbot/darknet-master/scripts/VOCdevkit/VOC2019/JPEGImages"

#dele.remove(1)

for filenames in os.walk(pathh):

    filenames = list(filenames)

    filenames = filenames[2]

    for filename in filenames:

 

        print(filename)

        if h==0:

            a = filename

            h = 1

        elif h==1:

            #print(filename)

            b = filename

            if a[0:a.rfind('.', 1)]==b[0:b.rfind('.', 1)]:

                h = 0

                #print(filename)

            else:

                h = 1

                dele.append(a)

                a = b

        else:

            print("wa1")

print(dele)

for file in dele:

    os.remove(pathh+file)

    print("remove"+file+" is OK!")

 

#再循环一次看看有没有遗漏的单身文件

for filenames in os.walk(pathh):

    filenames = list(filenames)

    filenames = filenames[2]

    for filename in filenames:

 

        print(filename)

        if h==0:

            a = filename

            h = 1

        elif h==1:

            #print(filename)

            b = filename

            if a[0:a.rfind('.', 1)]==b[0:b.rfind('.', 1)]:

                h = 0

                #print(filename)

            else:

                h = 1

                dele.append(a)

                a = b

        else:

            print("wa1")

print (dele)

 

至此数据标注工作完毕,我们还需要一个小工作,就是将xml文件全部从JPEGImages移出到Annotations文件夹下,方法为:

 cd JPEGImages  mv *.xml ../Annotations/

至此,JPEGImages为全部的图像数据,Annotations中为对应的xml描述文件.

1.4 指定训练集和测试集

我们做好的数据集要一部分作为训练集来训练模型,需要另一部分作为测试集来帮助我们验证模型的可靠性.因此首先要将所有的图像文件随机分配为训练集和测试集.

首先切换到ImageSets目录中,新建Main目录,然后在Main目录中新建两个文本文档train.txt和val.txt.分别用于存放训练集的文件名列表和测试集的文件名列表.

 cd ImageSets   mkdir -p Main && cd Main  touch train.txt test.txt val.txt

然后执行如下脚本文件来生成训练集和测试集,注意该文件中的20为我选择的训练集的个数.400默认为测试集

#coding:utf-8

import os

from os import listdir, getcwd

from os.path import join

if __name__ == '__main__':

    source_folder='/home/rcsn/lrc/darknet/scripts/VOCdevkit/VOC2019/JPEGImages/'     # 修改为自己的路径

    dest='/home/rcsn/lrc/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt' # 修改为自己的路径

    dest2='/home/rcsn/lrc/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/test.txt'  # 修改为自己的路径

    file_list=os.listdir(source_folder)       

    train_file=open(dest,'a')                 

    val_file=open(dest2,'a')   

    count = 0               

    for file_obj in file_list:

        count += 1                      

        file_name,file_extend=os.path.splitext(file_obj)      

        if(count<20):  # 可以修改这个数字,这个数字用来控制训练集合验证集的分割情况          

            train_file.write(file_name+'\n')  

        else :

            val_file.write(file_name+'\n')    

    train_file.close()

    val_file.close()

运行完成后可以在train.txt和val.txt文件如下所示:

 

 

1.5 指定训练集和测试集的实际路径和标签文件

修改script文件夹根目录下的voc_label.py文件,需要修改几处:

1)sets=[ (‘2019’, ‘train’), (‘2019’, ‘val’), ('2019', 'test')] ,2019为我们设置的文件夹标识 ,"train"和"val"指代训练集和测试集

2)classes = ["pill"] ,修改为我们要识别的四类物体名称

如下:

import xml.etree.ElementTree as ET

import pickle

import os

from os import listdir, getcwd

from os.path import join

sets=[ ('2019', 'train'), ('2019', 'val'), ('2019', 'test')]

classes = ["pill"]

def convert(size, box):

    dw = 1./(size[0])

    dh = 1./(size[1])

    x = (box[0] + box[1])/2.0 - 1

    y = (box[2] + box[3])/2.0 - 1

    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_annotation(year, image_id):

    in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))

    out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), '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)

 

    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')

wd = getcwd()

for year, image_set in sets:

    if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):

        os.makedirs('VOCdevkit/VOC%s/labels/'%(year))

    image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()

    list_file = open('%s_%s.txt'%(year, image_set), 'w')

    for image_id in image_ids:

        list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))

        convert_annotation(year, image_id)

    list_file.close()

os.system("cat 2019_train.txt 2019_test.txt > train.txt")

os.system("cat 2019_train.txt 2019_val.txt 2019_test.txt > train.all.txt")

修改完成后,执行如下命令,即可在labels文件夹下生成标签文件.如下:

scripts根目录下,也会生成2019_train.txt和2019_test.txt文件,与之前Main中的train.txt和var.txt文件不同,其内容全部为训练图片或测试图片的实际路径.

 

1.6 增加一些必要文件

1.6.1 增加data目录下的pill.names

1.6.2 增加 cfg目录下的pill_demo.data文件(可从voc.data复制)

主要修改的点为:

1)classes 因为,我们是1类,所以,classes = 1;

2) 修改训练集:train = /home/rcsn/lrc/darknet/scripts/2019_train.txt

3) 修改测试集valid =/home/rcsn/lrc/darknet/scripts/2019_test.txt

4) 修改标签名:names = /home/rcsn/lrc/darknet/data/pill_demo.names

5) 修改训练过程中生成的过程结果存放地址backup = /home/rcsn/lrc/darknet/backup/

修改后,如下:

1.6.3 增加 cfg目录下的yolov4-tiny-rcsn.cfg文件(从yolov4-tiny-custom.cfg复制)

修改地方主要有如下几个:

  1. 有两处需要修改classes和filters,从下往上有两处,类似如下字样处:

classes 修改为1,因为我们只有1类;将卷积层数修改为18 ,计算方式为3*(类别数+5).

我们任务是测试,则需要将该文件上方Testing下两行的batch=1,subdivisions=1全部注释掉,将# Training下两行的batch=64,subdivisions=16全部取消注释.

 

至此,训练前的准备工作已全部完成了.

2.训练

(需要下载yolov4-tiny.conv.29)

 

./darknet detector train cfg/pill_demo.data cfg/yolov4-tiny-rcsn.cfg yolov4-tiny.conv.29 | tee pill_train_log.txt

 

保存log时会生成两个文件,一个保存的是网络加载信息和checkout点保存信息,另一个保存的是训练信息。

训练耗时较长,查看log当loss较小,且不再发生变化时,可按"ctrl+c"终止训练.我训练到了90000次就停止了,在这个过程中在backup文件夹下会保存对应迭代次数的中间结果,前1000次内每100次保存一个,超过1000次,每1000保存一次,依次.在这个过程中,我么可以随时拿中间结果进行测试.

 

3.测试(图片)

./darknet detect cfg/yolov4-tiny-rcsn.cfg yolov4-tiny-rcsn_final.weights data/pill1.jpg

视频测试 csi摄像头 

./darknet detector demo cfg/pill_demo.data cfg/yolov4-tiny-rcsn.cfg yolov4-tiny-rcsn_final.weights "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=1280, height=720, format=NV12, framerate=30/1 ! nvvidconv flip-method=0 ! video/x-raw, width=1280, height=720, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink"

此帖出自ARM技术论坛

最新回复

怎么是person?   详情 回复 发表于 2021-4-7 20:04

赞赏

1

查看全部赞赏

点赞(2) 关注
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 

回复
举报

1万

帖子

203

TA的资源

管理员

沙发
 

赞!RC玩的东西越来越高大上了呀~~

此帖出自ARM技术论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 
 

回复

6815

帖子

0

TA的资源

五彩晶圆(高级)

板凳
 

JPEGImages文件夹下的图像时为什么要打乱顺序并重命名?

此帖出自ARM技术论坛

点评

你也可以不打乱重命名,拍照完之后,一张一张按照不重复序号命名  详情 回复 发表于 2021-4-6 18:18
 
 
 

回复

1366

帖子

6

TA的资源

版主

4
 
Jacktang 发表于 2021-4-6 17:41 将JPEGImages文件夹下的图像时为什么要打乱顺序并重命名?

你也可以不打乱重命名,拍照完之后,一张一张按照不重复序号命名

此帖出自ARM技术论坛

点评

其实是为了程序的便于排序么 还有一个问题,训练图片和测试图片要提前放在不同目录下吗  详情 回复 发表于 2021-4-6 21:33
 
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

回复

6815

帖子

0

TA的资源

五彩晶圆(高级)

5
 
RCSN 发表于 2021-4-6 18:18 你也可以不打乱重命名,拍照完之后,一张一张按照不重复序号命名

其实是为了程序的便于排序么

还有一个问题,训练图片和测试图片要提前放在不同目录下吗

此帖出自ARM技术论坛

点评

只要你能生成标注和训练集,并且指定这个路径,无所谓你的图片路径,放一起都可以,提不提前也无所谓  详情 回复 发表于 2021-4-7 09:00
 
 
 

回复

7640

帖子

2

TA的资源

五彩晶圆(高级)

6
 

终于玩起来了。RC可以搞个手磨蒸馏咖啡机,train一次可以从研磨开始到入口一杯,每天喝5杯就可以下班了。

此帖出自ARM技术论坛

点评

这个还是得骚叔亲自操刀才行  详情 回复 发表于 2021-4-7 09:02
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

1366

帖子

6

TA的资源

版主

7
 
Jacktang 发表于 2021-4-6 21:33 其实是为了程序的便于排序么 还有一个问题,训练图片和测试图片要提前放在不同目录下吗

只要你能生成标注和训练集,并且指定这个路径,无所谓你的图片路径,放一起都可以,提不提前也无所谓

此帖出自ARM技术论坛
 
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

回复

1366

帖子

6

TA的资源

版主

8
 
freebsder 发表于 2021-4-6 22:30 终于玩起来了。RC可以搞个手磨蒸馏咖啡机,train一次可以从研磨开始到入口一杯,每天喝5杯就可以下班了。

这个还是得骚叔亲自操刀才行

此帖出自ARM技术论坛

点评

看你玩,我吃瓜当观众。  详情 回复 发表于 2021-4-7 17:26
 
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

回复

7640

帖子

2

TA的资源

五彩晶圆(高级)

9
 
RCSN 发表于 2021-4-7 09:02 这个还是得骚叔亲自操刀才行

看你玩,我吃瓜当观众。

此帖出自ARM技术论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

1239

帖子

68

TA的资源

纯净的硅(中级)

10
 

怎么是person?

此帖出自ARM技术论坛

点评

哦 这是之前测试的,我晚点上传个正确的  详情 回复 发表于 2021-4-8 09:32
 
 
 

回复

1366

帖子

6

TA的资源

版主

11
 

哦 这是之前测试的,我晚点上传个正确的

此帖出自ARM技术论坛
 
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

回复

1366

帖子

6

TA的资源

版主

12
 

有坛友提出识别是Person的问题,图片测试需要加上完整指令 包含上训练的data文件 

 ./darknet detector test cfg/pill_demo.data cfg/yolov4-tiny-rcsn.cfg yolov4-tiny-rcsn_final.weights data/pill_1.jpg

图片识别效果如下

 

此帖出自ARM技术论坛
 
个人签名

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表