前序


1、环境配置

  • 请自行参考其他博客
  • 本机环境
    • ubuntu16.04
    • python3
    • 英伟达显卡驱动:nvidia-396
    • OpenCV3.4.5
    • CUDNN7.0.5
    • CUDA9.0

2、ubuntu16.04下安装OpenCV

参考:ubuntu16.04安装C++版本的OpenCV3.4.5


                                                 一、数据集图片的标注


1、使用labelImg标注软件进行数据集中图像的标注

参考:LabelImg的详细使用和图像标注

2、具体改动的标注步骤

        注:不同的是,我们在标注的时候就让每张图片生成的是txt文件,而不是xml文件,这样就省去了xml转txt这个步骤

(1)红色方框处选择yolo,而非默认的PascalVOC

(2)每标注一张图片点击保存,就会生成对应的图片名的txt文件,在保存txt文件夹中也会存在一个所有类别的文件

  • 每个图片标注后的文件

  • 类别txt文件

(3)对于每个标注后生成的txt文件,其格式是如下所示


                                                   

                                                  二、VOC2019数据集的制作 


 1、建立层次文件夹

  •    在下载的YOLOV3代码目录下,即darnet-master下建立voc/VOCdevkit/VOC2019层次目录,自己的建立的数据集为               VOC2019
  •    然后在VOC2019目录下建立三个文件夹:Annotations、ImageSets、JPEGImages

一级:darknet-master

二级:——backup  (存储训练好的模型)

二级:——cfg  (用于存放.cfg和.data文件)

二级:——data  (存放标签文件、图片、名字文件(.name))

三级:————data下的目录 :images(存放图片和yolo的txt文件,图片名和txt文本名要对应,但是后面我们在                                                                              JPEGImages中这样做了,因此此步就做了)

三级:————data下的目录:labels (存放用于opencv回执图片框的图片文件)

二级:——voc      (voc数据集目录)

三级:————VOCdevkit

四级: ——————VOC2019(这个年号可以自行更换,根据自己的需求吧)

五级:  ————————Annotations (存放使用labelImg软件标注所有数据集图片时生成的txt标注文件)

五级:  ————————ImageSets(用来存放训练和测试数据的名称,其里面存放的是Main文件夹)

五级:  ———————— labels(存放Annotations中相同的内容)

六级: ——————————Main(Main文件夹中存放的是4个txt文件,分别是存训练集图片名的train.txt、存验证集图片                                                                         名的val.txt、存测试集图片名的test.txt、存测试和验证集图片名的trainval.txt,但是                                                                           自己只建了两个,接下来会说明如何生成的)

五级: ————————JPEGImages  (用于存放数据集中的图片,后期还要将labels中的txt全部放到其中)

  • 具体目录层次如下:

             

2、一些txt文件的生成

#####

前提说明:因为我们在标注时就已经生成了每个图片对应的txt文档,因此我们就不使用darknet-master/scripts下的voc_label.py文件了,而是自己写脚本生成我们需要的文件。

######

(1)根据JPEGImages中的数据集图片生成我们需要的ImageSets/Main目录下的train.txt和val.txt,这两个文件存的是每个图片的名字,即.jpg之前的内容

  • 生成如上txt文件的脚本文件make_train_val.py如下
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':source_folder='/*****(自己的路径)/darknet-master/voc/VOCdevkit/VOC2019/JPEGImages/'#地址是所有图片的保存地点dest='/*****(自己的路径)/darknet-master/voc/VOCdevkit/VOC2019/ImageSets/Main/train.txt'  #保存train.txt的地址,对于train.txt(在ImageSets/Main/下)和2019_train.txt(在VOCdevkit下)是不同的路径dest2='/*****(自己的路径)/darknet-master/voc/VOCdevkit/VOC2019/ImageSets/Main/val.txt'  #保存val.txt的地址,对于val.txt(在ImageSets/Main/下)和2019_val.txt(在VOCdevkit下)是不同的路径file_list=os.listdir(source_folder)       #赋值图片所在文件夹的文件列表train_file=open(dest,'a')                 #打开文件val_file=open(dest2,'a')                  #打开文件for file_obj in file_list:                #访问文件列表中的每一个文件file_path=os.path.join(source_folder,file_obj) #file_path保存每一个文件的完整路径file_name,file_extend=os.path.splitext(file_obj)#file_name 保存文件的名字,file_extend保存文件扩展名file_num=int(file_name)  if(file_num<620):                     #保留620个文件用于训练train_file.write(file_name+'\n')  #用于训练前620个的图片路径保存在train.txt里面,结尾加回车换行/生成train.txt是file_name;生成2019_train.txt是file_pathelse :val_file.write(file_name+'\n')    #其余的文件保存在val.txt里面/生成val.txt是file_name;生成2019_val.txt是file_pathtrain_file.close()#关闭文件
val_file.close()
  • 终端运行
python3 make_train_val.py

  • 生成的文件目录和文件内容如下

a)train.txt文件部分内容(保存的是图片名字)

b)val.txt文件中的内容(保存的是图片名字)

(2)在VOCdevkit同级目录下生成2019_train.txt和2019_val.txt两个文件,yolo训练时需要这两个文件

  • 生成如上txt文件的脚本文件make_2019_train_val.py如下
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':source_folder='/*****(自己的路径)/darknet-master/voc/VOCdevkit/VOC2019/JPEGImages/'#地址是所有图片的保存地点dest='/*****(自己的路径)/darknet-master/voc/2019_train.txt'  #保存train.txt的地址,对于train.txt(在ImageSets/Main/下)和2019_train.txt(在VOCdevkit下)是不同的路径dest2='/*****(自己的路径)/darknet-master/voc/2019_val.txt'  #保存val.txt的地址,对于val.txt(在ImageSets/Main/下)和2019_val.txt(在VOCdevkit下)是不同的路径file_list=os.listdir(source_folder)       #赋值图片所在文件夹的文件列表train_file=open(dest,'a')                 #打开文件val_file=open(dest2,'a')                  #打开文件for file_obj in file_list:                #访问文件列表中的每一个文件file_path=os.path.join(source_folder,file_obj) #file_path保存每一个文件的完整路径file_name,file_extend=os.path.splitext(file_obj)#file_name 保存文件的名字,file_extend保存文件扩展名file_num=int(file_name)  if(file_num<620):                     #保留620个文件用于训练train_file.write(file_path+'\n')  #用于训练前620个的图片路径保存在train.txt里面,结尾加回车换行/生成train.txt是file_name;生成2019_train.txt是file_pathelse :val_file.write(file_path+'\n')    #其余的文件保存在val.txt里面/生成val.txt是file_name;生成2019_val.txt是file_pathtrain_file.close()#关闭文件
val_file.close()
  • 终端运行该.py文件
python3 make_2019_train_val.py
  • 生成的文件目录下的文件和每个txt文件中的内容如下

a)2019_train.txt文件中的部分内容如下(保存绝对路径)

b)2019_val.txt文件中的部分内容如下(保存绝对路径)

3、将Annotations中的txt文件(除了classes外)全部复制到labels中

如果不在darknet-master/voc/VOCdevkit/VOC2019/下建立labels文件,则会出现以下错误,因此一定要这样做

4、将labels中的txt全部复制到JPEGImages文件夹中,做到图片和txt一一对应

一开始是要吧JPEGImages文件中的图片放到darknet-master/data/images目录下,现在直接把yolo的标签文件txt即labels中的内容复制到JPEGImages文件夹中就可以了。


三、Imagenet上预训练权重的下载和yolo一些配置文件的修改


1、下载Imagenet上的预训练的权重(将下载的权重文件存在darknet-master/scripts目录下)

  • 方法一:在该文件夹下打开该文件下的终端命令,运行以下命令
wget https://pjreddie.com/media/files/darknet53.conv.74
  • 方法二:直接在浏览器下输入以下网址,然后弹出该权重的下载界面进行下载
https://pjreddie.com/media/files/darknet53.conv.74 

以上两种方式哪个快下载用哪种方式

2、修改darknet-master/cfg/voc.data文件

文件在:

voc.data修改为: 

classes= 9 #classes为训练样本集的类别总数,本实验选的为9类标签
train  = /****(自己的路径自己改)/darknet-master/voc/2019_train.txt  #train的路径为训练样本集所在的路径
valid  = /****(自己的路径自己改)/darknet-master/voc/2019_val.txt #valid的路径为验证样本集所在的路径
names = data/voc.names #names的路径为data/voc.names文件所在的路径
backup = backup

3、修改darknet-master/data/voc.names文件,更换默认的类别为自己的类别,然后保存

文件在:

voc.data修改为: 

  

4、修改darknet-master/cfg/yolov3-voc.cfg文件,根据自己的情况进行修改

 文件在:

yolov3-voc.cfg修改为: 

                        Testing注释掉                                 打开Training

[net]
# Testing
# batch=1        #这里的batch跟subdivisions原来不是注释掉的,但是训练后没成功,有的blog上说为1的时候太小难以收敛,但是不知道下面训练模式的 batch=64 subdivisions=8 会不会覆盖掉,总之注释掉后就成功了,不过这个脚本不是很明白,还来不及验证
# subdivisions=1
# Training            ### 训练模式,每次前向的图片数目 = batch/subdivisions
batch=64             #根据自己的情况进行修改
subdivisions=8        #根据自己的情况进行修改
width=416                      ### 网络的输入宽、高、通道数
height=416
channels=3
momentum=0.9                   ### 动量
decay=0.0005                   ### 权重衰减
angle=0
saturation = 1.5               ### 饱和度
exposure = 1.5                 ### 曝光度
hue=.1                         ### 色调learning_rate=0.001              ### 学习率
burn_in=1000                   ### 学习率控制的参数
max_batches = 50200                ### 迭代次数
policy=steps                   ### 学习率策略
steps=40000,45000              ### 学习率变动步长
scales=.1,.1                   ### 学习率变动因子  ......
......
......[convolutional]
size=1
stride=1
pad=1
filters=42        #---------------修改为3*(classes+5)即3*(9+5)=42
activation=linear
[yolo]
mask = 6,7,8
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=9       #---------------修改为标签类别个数,9类
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0            #1,如果显存很小,将random设置为0,关闭多尺度训练;(转自别的blog,还不太明白)
......
[convolutional]
size=1
stride=1
pad=1
filters=42        #---------------修改同上
activation=linear[yolo]
mask = 3,4,5
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=9        #---------------修改同上
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0
......
[convolutional]
size=1
stride=1
pad=1
filters=42        #---------------修改同上
activation=linear[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=9       #---------------修改同上
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0

注意:在以上源码中不要有中文注释,否则会出错

解决方法:出现以下错误,删除注释后可以训练了

错误提示:

##############

81 Type not recognized: [convolutional]#接下来从此处开始修改
Unused field: 'size = 1'
Unused field: 'stride = 1'
Unused field: 'pad = 1'
Unused field: 'filters = 42#原来是75,现在修改成3*(classes+5)=3*(9+5)=42'
Unused field: 'activation = linear'
   82 Cuda malloc failed
: File exists
darknet: ./src/utils.c:256: error: Assertion `0' failed.
已放弃 (核心已转储)

###############

5、参数详解

     以下参数是yolov3-voc.cfg参数说明:

  • batch:一批训练样本的样本数量,每batch个样本更新一次参数
  • subdivisions:将batch分割为subdivisions个子batch,每个子batch的大小为batch/subdivisions,作为一次性送入训练器的                            样本数量。
  • A.filters数目是怎么计算的:3x(classes数目+5),和聚类数目分布有关,论文中有说明;
  • B.如果想修改默认anchors数值,使用k-means即可
  • C.如果显存很小,将random设置为0,即关闭多尺度训练;

四、YOLOV3的训练过程、参数调节、问题解决、终止训练、继续训练


1 、在darknet-master终端运行如下代码进行训练

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74#注意文件路径

2、训练默认的是前1000轮每100轮保存一次模型,1000轮后每10000轮保存一次模型。可以修改examples/detector.c文件的138行。修改完重新编译一下,在darknet目录下执行make。

make
  • 文件所在目录

  • 代码更改处(根据自己的情况进行修改)

 

3、训练的过程

  • 不保存训练日志的训练执行命令
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74
  • 保存训练日志的训练执行命令
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74 | tee train_yolov3-voc.log

4、训练日志参数说明

  • Region xx:cfg文件中yolo-layer的索引;
  • Avg IOU: 当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1;
  • Class:标注物体的分类准确率,越大越好,期望数值为1;
  • obj:越大越好,期望数值为1;
  • No obj:越小越好;
  • .5R:以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本
  • 0.75R:以IOU=0.75为阈值时候的recall;
  • count:正样本数目。

  • 20277: 指示当前训练的迭代次数
  • 0.38915: 是总体的Loss(损失)
  • 0.42692 avg: 是平均Loss,这个数值应该越低越好,一般来说,一旦这个数值低于0.060730 avg就可以终止训练了
  • 0.000100 rate: 代表当前的学习率,是在.cfg文件中定义的。
  • 0.302128 seconds: 表示当前批次训练花费的总时间。
  • 162216 images: 这一行最后的这个数值表示到目前为止,参与训练的图片的总量。

5、调参中遇到的问题

  • 在Region 82 Avg IOU、Region 94 Avg IOU、Region 106 Avg IOU中出现很多nan

前提说明:在训练过程中,nan的屏幕占比30%是正常的,如果太大,全是nan,则就是训练出了问题

解决方法一:在显存允许的情况下,可以适当增加batch(darknet-master/yolov3-voc.cfg中的batch)的大小(要视自己数据集                          的大小情况来增加batch,不能盲目的改大),这样能够一定程度减少nan的出现。

解决方法二:增加数据集的规模。若是对于10类以内的图片,500张以内的训练集未必是太少了,因此可以增加数据集,实在不                         行的话就进行数据增强,把数据集扩展到原来的几倍到几十倍不等。

  • CUDA Error: out of memory darknet: ./src/cuda.c:36: check_error: Assertio `0' failed.

解决方法:显存不够,调小batch,关闭多尺度训练:random=0.(*************亲测有用**************)

random所在(darknet-master/cfg/yolov3-voc.cfg):

更多问题可以参考此篇大佬的详解:YOLOV3训练调参详解

6、训练结果

  • 在训练20000步以后可以看到在backup生成如下训练过程中的权重文件

  • 保存的训练日志文件

7、在avg低于0.06以后,如何停止训练

ubuntu系统下,在训练终端处,使用ctrl+c终止训练。

8、如何接着上一步停止处的训练状态继续训练

在终端输入:

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc.backup

如下:

9、训练日志的可视化

因为我们在训练的时候已经保存了训练日志,因此我们使用以下python脚本对训练日志进行可视化,得到loss变化曲线Avg IOU曲线(Avg IOU是标记的框和预测的框重复的部分除以他们的和,这个值越接近1越好)

(1)visualization_train_yolov3-voc_log.py

# -*- coding: utf-8 -*-
# @Func    :yolov3 训练日志可视化,把该脚本和日志文件放在同一目录下运行。import pandas as pd
import matplotlib.pyplot as plt
import os# ==================可能需要修改的地方=====================================#
g_log_path = "train_yolov3-voc.log"  # 此处修改为你的训练日志文件名
# ==========================================================================#def extract_log(log_file, new_log_file, key_word):''':param log_file:日志文件:param new_log_file:挑选出可用信息的日志文件:param key_word:根据关键词提取日志信息:return:'''with open(log_file, "r") as f:with open(new_log_file, "w") as train_log:for line in f:# 去除多gpu的同步logif "Syncing" in line:continue# 去除nan logif "nan" in line:continueif key_word in line:train_log.write(line)f.close()train_log.close()def drawAvgLoss(loss_log_path):''':param loss_log_path: 提取到的loss日志信息文件:return: 画loss曲线图'''line_cnt = 0for count, line in enumerate(open(loss_log_path, "rU")):line_cnt += 1result = pd.read_csv(loss_log_path, skiprows=[iter_num for iter_num in range(line_cnt) if ((iter_num < 500))],error_bad_lines=False,names=["loss", "avg", "rate", "seconds", "images"])result["avg"] = result["avg"].str.split(" ").str.get(1)result["avg"] = pd.to_numeric(result["avg"])fig = plt.figure(1, figsize=(6, 4))ax = fig.add_subplot(1, 1, 1)ax.plot(result["avg"].values, label="Avg Loss", color="#ff7043")ax.legend(loc="best")ax.set_title("Avg Loss Curve")ax.set_xlabel("Batches")ax.set_ylabel("Avg Loss")def drawIOU(iou_log_path):''':param iou_log_path: 提取到的iou日志信息文件:return: 画iou曲线图'''line_cnt = 0for count, line in enumerate(open(iou_log_path, "rU")):line_cnt += 1result = pd.read_csv(iou_log_path, skiprows=[x for x in range(line_cnt) if (x % 39 != 0 | (x < 5000))],error_bad_lines=False,names=["Region Avg IOU", "Class", "Obj", "No Obj", "Avg Recall", "count"])result["Region Avg IOU"] = result["Region Avg IOU"].str.split(": ").str.get(1)result["Region Avg IOU"] = pd.to_numeric(result["Region Avg IOU"])result_iou = result["Region Avg IOU"].values# 平滑iou曲线for i in range(len(result_iou) - 1):iou = result_iou[i]iou_next = result_iou[i + 1]if abs(iou - iou_next) > 0.2:result_iou[i] = (iou + iou_next) / 2fig = plt.figure(2, figsize=(6, 4))ax = fig.add_subplot(1, 1, 1)ax.plot(result_iou, label="Region Avg IOU", color="#ff7043")ax.legend(loc="best")ax.set_title("Avg IOU Curve")ax.set_xlabel("Batches")ax.set_ylabel("Avg IOU")if __name__ == "__main__":loss_log_path = "train_log_loss.txt"iou_log_path = "train_log_iou.txt"if os.path.exists(g_log_path) is False:exit(-1)if os.path.exists(loss_log_path) is False:extract_log(g_log_path, loss_log_path, "images")if os.path.exists(iou_log_path) is False:extract_log(g_log_path, iou_log_path, "IOU")drawAvgLoss(loss_log_path)drawIOU(iou_log_path)plt.show()

(2) 将上述python脚本文件和训练日志放在同一目录下,打开此目录下的终端,运行上述.py文件可以得到loss变化曲线和Avg IOU变化曲线。同时,在当前目录下生成了train_log_iou.txt和train_log_loss.txt文件。

  • loss变化曲线和Avg IOU变化曲线(仅供参考)

  • train_log_iou.txt和train_log_loss.txt文件

训练日志可视化参考博客: YOLO-V3可视化训练过程中的参数,绘制loss、IOU、avg Recall等的曲线图

YOLOv3训练自己的数据集(3)——小技巧和训练日志可视化


五、模型的测试


                        注:测试的时候要更改cfg/yolov3-voc.cfg文件,将Testing启用,Training禁用

1、单张图片测试

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_20000.weights voc/VOCdevkit/VOC2019/JPEGImages/0000629.jpg

2、摄像头实时测试

./darknet detector demo cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_20000.weights

批量测试


测试集:130张图片


3、批量测试一下,并输出记录目标位置信息的txt文件存在darknet/result下,可以使用valid命令

./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_50000.weights
  • 对于cfg/voc.data为测试路径的配置,因此需要根据个人情况进行更改,2019_test.txt里面的都是绝对路径

  • 检测阈值的设定

在detector.c文件中,validate_detector函数下,有个阈值设置thresh,默认是0.005,根据个人情况进行设置

  • 在darknet文件目录下打开终端执行上面的命令,可以在darknet/results/目录下生成9类所对应的测试结果文件,其文件格式为comp4_det_test_[类名].txt,保存的即为测试结果
./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_50000.weights

  • 对于以上每个文件打开如下,按列来看,分别是: 图像名称 置信度 xmin ymin xmax ymax

参考博客


4、针对测试集,批量测试图片并将测试的图片显示结果保存在自定义的文件夹下

(1)用下面的代码替换detector.c文件(example文件夹下)的void test_detector函数此处有三处需要改成自己的路径

void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{list *options = read_data_cfg(datacfg);char *name_list = option_find_str(options, "names", "data/names.list");char **names = get_labels(name_list);image **alphabet = load_alphabet();network *net = load_network(cfgfile, weightfile, 0);set_batch_network(net, 1);srand(2222222);double time;char buff[256];char *input = buff;float nms=.45;int i=0;while(1){if(filename){strncpy(input, filename, 256);image im = load_image_color(input,0,0);image sized = letterbox_image(im, net->w, net->h);//image sized = resize_image(im, net->w, net->h);//image sized2 = resize_max(im, net->w);//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);//resize_network(net, sized.w, sized.h);layer l = net->layers[net->n-1];float *X = sized.data;time=what_time_is_it_now();network_predict(net, X);printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);int nboxes = 0;detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);//printf("%d\n", nboxes);//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);if (nms) do_nms_sort(dets, nboxes, l.classes, nms);draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);free_detections(dets, nboxes);if(outfile){save_image(im, outfile);}else{save_image(im, "predictions");
#ifdef OPENCVcvNamedWindow("predictions", CV_WINDOW_NORMAL); if(fullscreen){cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);}show_image(im, "predictions");cvWaitKey(0);cvDestroyAllWindows();
#endif}free_image(im);free_image(sized);if (filename) break;} else {printf("Enter Image Path: ");fflush(stdout);input = fgets(input, 256, stdin);if(!input) return;strtok(input, "\n");list *plist = get_paths(input);char **paths = (char **)list_to_array(plist);printf("Start Testing!\n");int m = plist->size;if(access("/home/FENGsl/darknet/data/out",0)==-1)//"/home/FENGsl/darknet/data"修改成自己的路径{if (mkdir("/home/FENGsl/darknet/data/out",0777))//"/home/FENGsl/darknet/data"修改成自己的路径{printf("creat file bag failed!!!");}}for(i = 0; i < m; ++i){char *path = paths[i];image im = load_image_color(path,0,0);image sized = letterbox_image(im, net->w, net->h);//image sized = resize_image(im, net->w, net->h);//image sized2 = resize_max(im, net->w);//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);//resize_network(net, sized.w, sized.h);layer l = net->layers[net->n-1];float *X = sized.data;time=what_time_is_it_now();network_predict(net, X);printf("Try Very Hard:");printf("%s: Predicted in %f seconds.\n", path, what_time_is_it_now()-time);int nboxes = 0;detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);//printf("%d\n", nboxes);//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);if (nms) do_nms_sort(dets, nboxes, l.classes, nms);draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);free_detections(dets, nboxes);if(outfile){save_image(im, outfile);}else{char b[2048];sprintf(b,"/home/FENGsl/darknet/data/out/%s",GetFilename(path));//"/home/FENGsl/darknet/data"修改成自己的路径save_image(im, b);printf("save %s successfully!\n",GetFilename(path));
#ifdef OPENCVcvNamedWindow("predictions", CV_WINDOW_NORMAL); if(fullscreen){cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);}show_image(im, "predictions");cvWaitKey(0);cvDestroyAllWindows();
#endif}free_image(im);free_image(sized);if (filename) break;}}}
}

(2)在detector.c文件的最前面加上*GetFilename(char *p)函数(根据自己的情况更改注释处的内容)

#include "darknet.h"static int coco_ids[] = {1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90};char *GetFilename(char *p)
{ static char name[20]={""};char *q = strrchr(p,'/') + 1;strncpy(name,q,7);//注意后面的7,如果你的测试集的图片的名字字符(不包括后缀)是其他长度,请改为你需要的长度(官方的默认的长度是6)return name;
}

(3)在darknet下重新进行make一下

注:在make的时候可能会出现如下错误

#ifdef OPENCV cvNamedWindow("predictions", CV_WINDOW_NORMAL); 提示找不到CV_WINDOW_NORMAL的定义? 报错: error: ‘CV_WINDOW_NORMAL’ undeclared (first use in this function)

解决方法:

找到darknet下的Makefile文件将OPENCV=0

(4)开始批量测试

  • 在此终端下输入批量测试的命令
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_50000.weights
  • 接下来会让输入:Enter Image Path:

后面输入你的txt文件路径(你准备好的所有测试图片的路径全部存放在一个txt文件里),你可以复制voc.data文件里的valid后面的路径,就可以了。

  • 批量测试过程

  • 批量测试结果

在darknet下的data中生成out文件夹,里面存放的是批量测试后的图片标注结果


ubuntu16.04下使用YOLOV3训练自己做的VOC数据集(VOC数据集制作+模型训练步骤+训练参数解析和问题解决+训练日志可视化(loss、IOU)+模型测试(单张、摄像头、批量测试))相关推荐

  1. ubuntu16.04下使用mktorrent代替utorrent做种生成.torrent文件

    1.下载mktorrent.github链接在这里 git clone https://github.com/Rudde/mktorrent.git 2.下载完成后进入到文件夹里面 例如:cd mkt ...

  2. Ubuntu16.04下Neo4j图数据库官网安装部署步骤(图文详解)(博主推荐)

    不多说,直接上干货! 说在前面的话  首先,查看下你的操作系统的版本. root@zhouls-virtual-machine:~# cat /etc/issue Ubuntu 16.04.1 LTS ...

  3. Ubuntu16.04下基于opencv--实现图像SIFT特征与全景图片的生成

    Ubuntu16.04下基于opencv--实现图像SIFT特征与全景图片的生成 一. 理解和实践SIFT特征提取与匹配 二. 全景图片的生成 三.循环依次读取一个序列图片,进行匹配连线 一. 理解和 ...

  4. Ubuntu16.04下caffe CPU版的详细安装步骤

    一.caffe简介 Caffe,是一个兼具表达性.速度和思维模块化的深度学习框架. 由伯克利人工智能研究小组和伯克利视觉和学习中心开发. 虽然其内核是用C++编写的,但Caffe有Python和Mat ...

  5. Ubuntu16.04下ROS Kinetic的安装(2022)

    文章目录 Ubuntu16.04下ROS Kinetic的安装(2022) 一.Ubuntu16.04配置 二.ROS Kinetic安装过程 1.软件中心配置 2.ROS的下载安装 2.1添加源和密 ...

  6. ubuntu16.04下 1080ti显卡驱动384.98+cuda9.0+cudnn+caffe 安装过程,本人新测,没毛病

    ubuntu16.04下 显卡驱动384.98+cuda9.0+cudnn9.0+caffe 安装 我自己尝试的在16.04下安装如上所述,系统安装不多说,主要说显卡驱动往下的部分,和我自己遇到的问题 ...

  7. Ubuntu16.04下配置ORB-SLAM2与运行单目实例

    Ubuntu16.04下配置ORB-SLAM2与运行单目实例 一.安装相关工具 二.安装Pangolin 三.安装opencv 四.安装Eigen 五.安装ORB_SLAM2 六.安装usb_cam ...

  8. ubuntu16.04 下安装Opencv2.4.9

    ubuntu16.04 下安装Opencv2.4.9 OpenCV的源码download from:  https://sourceforge.net/projects/opencvlibrary/? ...

  9. ubuntu16.04下ROS最新换源方法,解决Hash sum mismatch 问题

    1.更换源 备份原始数据 cd /etc/apt/ sudo cp sources.list sources.list.bak sudo gedit sources.list 科大源: deb htt ...

最新文章

  1. 注册页面所涉及的知识
  2. 【转摘】PYTHON 正则表达式
  3. python圆的周长和面积返回2个值的元组_初见Python2:列表和元组
  4. 吴裕雄--天生自然 高等数学学习:多元函数的概念
  5. python bosonnlp_BosonNLP分词技术解密
  6. 优化Image设置Tiled类型产生过多的三角形顶点
  7. n个字符串按照字典序排列
  8. python语言编程基础视频_网络编程-5_ Python系列视频(一)——Python语言基础_Python视频-51CTO学院...
  9. 【opencv】【mediapipe】手势检测的有趣玩法
  10. 计算机考研问题,考研计算机常见的6个问题
  11. CEGUI添加自定义控件
  12. Python学习【第二篇】 : Python入门
  13. saltstack处理xml文件_saltstack部署returner [三]
  14. ASP.NET实现日期转为大写的汉字
  15. 磁盘性能指标监控实战
  16. centos 8 的图形操作界面在哪_【行测备考】立体图形截面有哪些实用技法?
  17. html根据ip和mac地址,关于怎么通过IE浏览器获取客户端的IP地址和Mac地址
  18. 小学生C++编程基础 课程20(共7题)
  19. 使用freemarker导出html格式的word(调整页边距,页面视图,正常表格样式)
  20. 解决If you see valid patterns in the file then the issue is probably caused by a circular import

热门文章

  1. 松耦合和紧耦合的架构设计及性能对比
  2. MySQL技术内幕-InnoDB存储引擎:第一章阅读
  3. OWASP Security Shepherd
  4. 视力矫正黑幕笼罩 该如何拯救下一代近视青少年的眼睛?
  5. “锤子科技2017春季新品发布会”能否带领罗永浩度过难关?
  6. React Native 学习资源精选仓库(汇聚知识,分享精华)
  7. SAP成都C4C小李探花:浅谈Fiori Design Guidelines
  8. Access to script at ‘file:///C:/study...‘ from origin ‘null‘has been blocked by CORS policy
  9. 二进制转base64,图片的处理
  10. 2019E0_G 生日宴会