最近在做目标检测相关的工作,先用faster R-CNN训练了一下,感觉效果不是很好,换成了res101特征提取,mAP也只达到了30+,于是想换个模型试试,就选择了yolov3
yolov3的训练需要用到自己的标签格式,我就直接拿了上次制作的VOC格式数据集进行处理和训练。https://blog.csdn.net/qq_36852276/article/details/100154097
记录一下
https://blog.csdn.net/helloworld1213800/article/details/79749359
https://blog.csdn.net/weixin_41813620/article/details/92799338
https://blog.csdn.net/xuanlang39/article/details/88642010

常见问题和注释

https://blog.csdn.net/maweifei/article/details/81137563

笔记

将文件夹内的绝对路径写入txt文件

ls -R /home/datalab/work/datasets/test_7pilang/*.jpg > file.txt

无绝对路径,当前文件夹文件名写入txt文件

ls -R *.jpg > file.txt

训练自己数据集的流程

下载darknet项目

git clone https://github.com/pjreddie/darknet
cd darknet

修改Makefile

主要是修改3处
一是GPU、CUDNN、OPENCV
二是修改算力符合自己的显卡
三是cudnn路径改成自己的GPU=1
CUDNN=1
OPENCV=1
OPENMP=0
DEBUG=0ARCH= -gencode arch=compute_61,code=sm_61
#      -gencode arch=compute_35,code=sm_35 \
#      -gencode arch=compute_50,code=[sm_50,compute_50] \
#      -gencode arch=compute_52,code=[sm_52,compute_52]
#      -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif



修改完之后执行编译 make

准备自己的数据集

我使用的是labelme进行标注,然后把产生的json文件转化成xml格式,接着进行数据增强,我自己的脚本如下所示
https://blog.csdn.net/qq_36852276/article/details/102539858

有了图片和标签后,把图片和标签整理成VOC数据集的格式,为了方便放在scripts文件夹下
文件夹结构是

VOCdevkit
—VOC2007
——Annotations
——ImageSets
———Layout
———Main
———Segmentation
——JPEGImages

其中Main下又分别是四个文件 train.txt trainval.txt val.txt test.txt
它们分别是不带后缀的文件名

接着利用项目中的./scripts/voc_label.py 直接生成yolo所需的文件
要修改一部分适应自己的数据,这里一共三处,注释掉的是原来的,我只需要识别一类boat
分别是
sets
classes
os.system

准备预训练权重

从官网上就可以下载

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

为了方便放在model文件下

修改配置文件cfg/voc.data

这个要修改成适应自己数据的地方
classes改为类别数
train,valid是生成的yolo所需的绝对路径的txt文件序列
names是类别的txt文件序列

classes= 1
train  = /home/xxx/darknet_2/darknet/scripts/2007_train.txt
valid  = /home/xxx/darknet_2/darknet/scripts/2007_val.txt
names = /home/xxx/darknet_2/darknet/data/voc.names
backup = backup

修改配置文件data/voc.name

改成自己的标签名

修改配置文件cfg/yolov3-voc.cfg

这个就是模型的各项配置,各项介绍如下

[net]
# Testing            ### 测试模式
# batch=1
# subdivisions=1
# Training           ### 训练模式,每次前向的图片数目 = batch/subdivisions
batch=64
subdivisions=16
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 = 5000  ### 迭代次数
policy=steps         ### 学习率策略
steps=40000,45000    ### 学习率变动步长
scales=.1,.1         ### 学习率变动因子  [convolutional]
batch_normalize=1    ### BN
filters=32           ### 卷积核数目
size=3               ### 卷积核尺寸
stride=1             ### 卷积核步长
pad=1                ### pad
activation=leaky     ### 激活函数

这个文件共需要修改6处
其实是有一个一模一样的结构出现了3次,每个都要修改2个地方,就是下面的结构,建议搜索yolo关键字就能找到这三处

[convolutional]
size=1
stride=1
pad=1
filters=18   #修改这里,3*(类别数+4+1)
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=1  #修改这里,改成你自己的类别数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1

上述的filters、classes需要修改 修改方式看上面注释
除此之外,还有几个关键的地方要考虑

#batch表示每次多少张图被读取,subdivisions表示它们在训练上被分了多少份,因此batch_size = batch/subdivisions,所以可以按照它适当调节来适应你的显存大小,这个除法结果越小,需要显存越少
batch=64
subdivisions=16
#max_batches是迭代次数,且默认保存方式是1000以前每100保存一次,1000以后每10000保存一次
max_batches = 5000
#random是多尺度训练,就是图像会被初始化成某个范围内的随机大小进行训练,因此占用显存是浮动的,要是显存紧张可以设为0,就会每次固定成width=416,height=416(设置里有)的大小进行训练

开始训练

#三个路径分别是修改好的  数据集文件、模型配置文件、预训练权重
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg ./model/darknet53.conv.74 -gpus 0

训练好的模型测试

方法1

#这个是默认使用了coco.names,有80类
./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights data/dog.jpg

方法2

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights xxx/xxx.jpg

调用python接口

darknet项目下有一个python文件夹,里面的darknet.py就是官方给出的python接口,将darknet.py移动到darknet项目路径下,然后可以对着它进行修改即可,注意它产生的结果是x,y,w,h的格式,就是中心点坐标、宽高
下面是我直接使用的例子

if __name__ == "__main__":#net = load_net("cfg/densenet201.cfg", "/home/pjreddie/trained/densenet201.weights", 0)#im = load_image("data/wolf.jpg", 0, 0)#meta = load_meta("cfg/imagenet1k.data")#r = classify(net, meta, im)#print r[:10]net = load_net(b"cfg/yolov3-voc.cfg", b"backup/yolov3-voc_final.weights", 0)meta = load_meta(b"cfg/voc.data")root_path = "/home/xxx/wurenting/dataset_total/"save_path = "/home/xxx/guangdong/guangdong_yolov3/"path_list = os.listdir(root_path)for filename in path_list:r = detect(net, meta, (root_path+filename).encode('utf-8'),thresh=.3,nms=.3)#draw triangleimg = cv2.imread(root_path + filename)weight_img = img.shape[1]height_img = img.shape[0]for r_res in r:cls = r_res[0]score = r_res[1]x = r_res[2][0]y = r_res[2][1]w = r_res[2][2]h = r_res[2][3]x_left_top = float("%.2f"%(x - w/2))y_left_top = float("%.2f"%(y - h/2))x_right_bottom = float("%.2f"%(x + w/2))y_right_bottom = float("%.2f"%(y + h/2))if x_left_top > weight_img:x_left_top = weight_imgif x_right_bottom > weight_img:x_right_bottom = weight_imgif y_left_top > height_img:y_left_top = height_imgif y_right_bottom > height_img:y_right_bottom = height_imgif x_left_top<0:x_left_top = 0if x_right_bottom<0:x_right_bottom = 0if y_left_top < 0:y_left_top = 0if y_right_bottom < 0:y_right_bottom = 0bbox = (x_left_top,y_left_top,x_right_bottom,y_right_bottom)with open('/home/xxx/guangdong/test_b_yolo.txt','a') as xxx_obj:xxx_obj.write(filename + '_' + cls.decode('utf-8') + '_' + str(bbox) + '_' + str(score) + '_\n') cv2.namedWindow("res", cv2.WINDOW_NORMAL)cv2.rectangle(img, (int(x_left_top),int(y_left_top)),(int(x_right_bottom),int(y_right_bottom)), (0, 204, 0), 2)cv2.putText(img, '%s: %.3f' % (str(cls)[2:-1], score), (int(x_left_top), int(y_left_top) + 15), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 255), thickness=2)
#        cv2.imwrite(save_path +filename,img)cv2.imshow("res",img)if cv2.waitKey(0)==ord('q'):sys.exit()
#        print(r)cv2.destroyAllWindows()

使用python接口对视频、图像进行处理

预留的端口只能输入路径,也就是只能进行单张离线图片测试,不是很方便,于是可以对源码进行修改,将接口输入路径修改为输入图片
看这位大佬的博客,亲测可用

https://blog.csdn.net/phinoo/article/details/83009061

修改后就为所欲为,放一个我读取RTSP网络视频流进行处理的例子

from ctypes import *
import math
import random
import cv2
import os
import sys
import threading#define global variable
count = 0
flag = 0def sample(probs):s = sum(probs)probs = [a/s for a in probs]r = random.uniform(0, 1)for i in range(len(probs)):r = r - probs[i]if r <= 0:return ireturn len(probs)-1def c_array(ctype, values):arr = (ctype*len(values))()arr[:] = valuesreturn arrclass BOX(Structure):_fields_ = [("x", c_float),("y", c_float),("w", c_float),("h", c_float)]class DETECTION(Structure):_fields_ = [("bbox", BOX),("classes", c_int),("prob", POINTER(c_float)),("mask", POINTER(c_float)),("objectness", c_float),("sort_class", c_int)]class IMAGE(Structure):_fields_ = [("w", c_int),("h", c_int),("c", c_int),("data", POINTER(c_float))]class METADATA(Structure):_fields_ = [("classes", c_int),("names", POINTER(c_char_p))]#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
lib = CDLL("/home/xxx/darknet_1/darknet/libdarknet.so", RTLD_GLOBAL)
lib.network_width.argtypes = [c_void_p]
lib.network_width.restype = c_int
lib.network_height.argtypes = [c_void_p]
lib.network_height.restype = c_intndarray_image = lib.ndarray_to_image
ndarray_image.argtypes = [POINTER(c_ubyte), POINTER(c_long), POINTER(c_long)]
ndarray_image.restype = IMAGEpredict = lib.network_predict
predict.argtypes = [c_void_p, POINTER(c_float)]
predict.restype = POINTER(c_float)set_gpu = lib.cuda_set_device
set_gpu.argtypes = [c_int]make_image = lib.make_image
make_image.argtypes = [c_int, c_int, c_int]
make_image.restype = IMAGEget_network_boxes = lib.get_network_boxes
get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int)]
get_network_boxes.restype = POINTER(DETECTION)make_network_boxes = lib.make_network_boxes
make_network_boxes.argtypes = [c_void_p]
make_network_boxes.restype = POINTER(DETECTION)free_detections = lib.free_detections
free_detections.argtypes = [POINTER(DETECTION), c_int]free_ptrs = lib.free_ptrs
free_ptrs.argtypes = [POINTER(c_void_p), c_int]network_predict = lib.network_predict
network_predict.argtypes = [c_void_p, POINTER(c_float)]reset_rnn = lib.reset_rnn
reset_rnn.argtypes = [c_void_p]load_net = lib.load_network
load_net.argtypes = [c_char_p, c_char_p, c_int]
load_net.restype = c_void_pdo_nms_obj = lib.do_nms_obj
do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]do_nms_sort = lib.do_nms_sort
do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]free_image = lib.free_image
free_image.argtypes = [IMAGE]letterbox_image = lib.letterbox_image
letterbox_image.argtypes = [IMAGE, c_int, c_int]
letterbox_image.restype = IMAGEload_meta = lib.get_metadata
lib.get_metadata.argtypes = [c_char_p]
lib.get_metadata.restype = METADATAload_image = lib.load_image_color
load_image.argtypes = [c_char_p, c_int, c_int]
load_image.restype = IMAGErgbgr_image = lib.rgbgr_image
rgbgr_image.argtypes = [IMAGE]predict_image = lib.network_predict_image
predict_image.argtypes = [c_void_p, IMAGE]
predict_image.restype = POINTER(c_float)def nparray_to_image(img):data = img.ctypes.data_as(POINTER(c_ubyte))image = ndarray_image(data, img.ctypes.shape, img.ctypes.strides)return imagedef classify(net, meta, im):out = predict_image(net, im)res = []for i in range(meta.classes):res.append((meta.names[i], out[i]))res = sorted(res, key=lambda x: -x[1])return resdef detect(net, meta, im, thresh=.5, hier_thresh=.5, nms=.45):num = c_int(0)pnum = pointer(num)predict_image(net, im)dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum)num = pnum[0]if (nms): do_nms_obj(dets, num, meta.classes, nms);res = []for j in range(num):for i in range(meta.classes):if dets[j].prob[i] > 0:b = dets[j].bboxres.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))res = sorted(res, key=lambda x: -x[1])free_image(im)free_detections(dets, num)return resdef deal_img():global arrglobal countglobal netglobal metaglobal flag
#    global video_writerwhile True:arr_temp = arrif flag==1:if count%3==0:cv2.imwrite('/home/xxx/wurenting/dataset_10_21/' +str(int(count/3))+'.jpg',arr_temp)count += 1img = nparray_to_image(arr_temp)r = detect(net, meta, img,thresh=.6,nms=.3)#draw triangleweight_img = arr_temp.shape[1]height_img = arr_temp.shape[0]for r_res in r:cls = r_res[0]score = r_res[1]x = r_res[2][0]y = r_res[2][1]w = r_res[2][2]h = r_res[2][3]x_left_top = float("%.2f"%(x - w/2))y_left_top = float("%.2f"%(y - h/2))x_right_bottom = float("%.2f"%(x + w/2))y_right_bottom = float("%.2f"%(y + h/2))if x_left_top > weight_img:x_left_top = weight_imgif x_right_bottom > weight_img:x_right_bottom = weight_imgif y_left_top > height_img:y_left_top = height_imgif y_right_bottom > height_img:y_right_bottom = height_imgif x_left_top<0:x_left_top = 0if x_right_bottom<0:x_right_bottom = 0if y_left_top < 0:y_left_top = 0if y_right_bottom < 0:y_right_bottom = 0bbox = (x_left_top,y_left_top,x_right_bottom,y_right_bottom)#            with open('/home/xxx/guangdong/test_b_yolo.txt','a') as xxx_obj:#                xxx_obj.write(filename + '_' + cls.decode('utf-8') + '_' + str(bbox) + '_' + str(score) + '_\n') cv2.rectangle(arr_temp, (int(x_left_top),int(y_left_top)),(int(x_right_bottom),int(y_right_bottom)), (0, 204, 0), 2)cv2.putText(arr_temp, '%s: %.3f' % (str(cls)[2:-1], score), (int(x_left_top), int(y_left_top) + 15), cv2.FONT_HERSHEY_PLAIN,1.0, (0, 0, 255), thickness=2)cv2.namedWindow("res", cv2.WINDOW_NORMAL)cv2.imshow("res",arr_temp)#    video_writer.write(arr_temp)if cv2.waitKey(1)==ord('k'):flag = 1elif cv2.waitKey(1)==ord('q'):flag = 0#        video_writer.release()#        print(r)
def change_arr():global countglobal arrglobal vidwhile True:return_value , arr = vid.read()#cv2.imwrite('/home/xxx/wurenting/dataset_10_17/' +str(count)+'.jpg',arr_temp)#count+=1if __name__ == "__main__":#net = load_net("cfg/densenet201.cfg", "/home/pjreddie/trained/densenet201.weights", 0)#im = load_image("data/wolf.jpg", 0, 0)#meta = load_meta("cfg/imagenet1k.data")#r = classify(net, meta, im)#print r[:10]#加载官方参数#net = load_net(b"cfg/yolov3.cfg", b"yolov3.weights", 0)#meta = load_meta(b"cfg/coco.data")#加载船只检测参数net = load_net(b"/homexxx/darknet_2/darknet/cfg/yolov3-voc.cfg", b"/home/xxx/darknet_2/darknet/backup/yolov3-voc_final.weights", 0)meta = load_meta(b"/home/xxx/darknet_2/darknet/cfg/voc.data")vid = cv2.VideoCapture("rtsp://admin:12345@192.168.1.113:554/")#vid = cv2.VideoCapture("rtsp://127.0.0.1:8554/test")#vid = cv2.VideoCapture("rtsp://192.168.1.146:8553/PSIA/Streaming/channels/0?videoCodecType=H.264")#vid = cv2.VideoCapture("/home/xxx/wurenting/2019_10_16_16_07_IMG_1522.mp4")return_value , arr = vid.read()#video_writer = cv2.VideoWriter('/home/xxx/wurenting/video_result_10_21/result.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 30, (1920,1080))thread_1 = threading.Thread(target=deal_img)   # 定义线程 1thread_2 = threading.Thread(target=change_arr) # 定义线程 2thread_1.start()  # 让线程1开始工作thread_2.start()  # 让线程2开始工作

其他的问题,例如修改保存权重的迭代值之类的问题,看最上面的常见问题、注释那篇博客

使用已知json和图片将目标切割出来代码

import os
from lxml.etree import Element, SubElement, tostring
from xml.dom.minidom import parseString
from PIL import Image
import json
import cv2json_dir = '/home/xbw/wurenting/train_buoy_1117/red/json/'
img_dir = '/home/xbw/wurenting/train_buoy_1117/red/img/'
json_list = os.listdir(json_dir)
json_list.sort(key=lambda x:int(x[:-5]))
for image_name in json_list:print(image_name)img_source = cv2.imread(img_dir+image_name[:-5]+'.jpg')with open(json_dir+image_name) as obj:nums = json.load(obj)labels = []bboxes = []for i in nums['shapes']:labels.append(i['label'])bboxes.append([min(i['points'][0][0],i['points'][1][0]),min(i['points'][0][1],i['points'][1][1]),max(i['points'][0][0],i['points'][1][0]),max(i['points'][0][1],i['points'][1][1])])bbox = bboxes[0]crop = img_source[int(bbox[1]):int(bbox[3]),int(bbox[0]):int(bbox[2])]cv2.imwrite("/home/xbw/wurenting/train_buoy_1117/red/crop/"+image_name[:-5]+'.jpg',crop)cv2.imshow("res",crop)cv2.waitKey(1)

YOLOv3训练自己的数据集相关推荐

  1. win10下yolov3训练自己的数据集

    在win10下用yolov3训练自己的数据集 1.  在darknet-master\build\darknet\x64 新建yolo-obj.cfg文件(可以直接复制yolov3.cfg,然后重命名 ...

  2. YOLOV3训练自己的数据集(PyTorch版本)

    由于这一段时间从事目标检测相关工作,因而接触到yolov3,进行目标检测,具体原理大家可以参考大神的博客目标检测(九)--YOLO v1,v2,v3,我就不细讲了,直接进入正题,如何利用深度学习框架P ...

  3. 『论文笔记』TensorFlow1.6.0+Keras 2.1.5+Python3.5+Yolov3训练自己的数据集!

    TensorFlow1.6.0+Keras 2.1.5+Python3.5+Yolov3训练自己的数据集! 文章目录 前期准备 一. Yolov3简要介绍 1.1. Yolov3网络结构图 1.2. ...

  4. 小白教程:Ubuntu下使用Darknet/YOLOV3训练自己的数据集

    小白教程:Ubuntu下使用Darknet/YOLOV3训练自己的数据集 YOLOV3官网教程:https://pjreddie.com/darknet/yolo/ 使用预训练模型进行检测 git c ...

  5. yolov3 训练自己的数据集 手把手教学 ubuntu 18.04 显卡1650 显存4g 跟着操作做保证学会

    yolov3 训练自己的数据集 手把手教学 ubuntu 18.04 显卡1650 显存4g 跟着操作做保证学会 这是我的训练效果,成功实现裂痕检测 演示视频:https://b23.tv/Ccmwi ...

  6. yolov3训练自己的数据集——第一次实操完整记录

    参考: yolov3 darknet yolo源码解析 bacth参数对性能影响 backpropogation算法 yolo中7*7个grid和rpn中的9个anchors darknet源码学习 ...

  7. Windows10下使用darknet和YOLOV3训练自己的数据集

    前言 1.我的环境是windows10,vs2015,cuda9.1,cudnn7.1. 2. darknet加yoloV3,用cmake和vs2015编译成darknet.exe. 3. 我的目录结 ...

  8. 第十一节,利用yolov3训练自己的数据集

    1.环境配置 tensorflow1.12.0 Opencv3.4.2 keras pycharm 2.配置yolov3 下载yolov3代码:https://github.com/qqwweee/k ...

  9. graphpad如何加标注_如何以YOLOv3训练自己的数据集 以小蕃茄为例

    在人工智能的计算机视觉领域中,最常见的应用包括影像分类.对象侦测.像素级对象影像分割(语义分割及实例分割),其中以对象侦测的应用范围最广. 近年来对象侦测的算法(模型)不断推陈出新,从最早的二阶式(R ...

  10. Win7+keras+tensorflow使用YOLO-v3训练自己的数据集

    一.下载和测试模型 1. 下载YOLO-v3 git clone https://github.com/qqwweee/keras-yolo3.git 这是在Ubuntu里的命令,windows直接去 ...

最新文章

  1. 最后3天,BDTC 2019早鸟票即将售罄,超强阵容及议题抢先曝光!
  2. 消息队列面试 - 如何保证消息的可靠性传输?
  3. 【爬虫剑谱】三卷3章 拾遗篇-有关于bs4库中的BeautifulSoup模块使用小结
  4. csharp为何不流行_“我太南了”这些年度流行语到底是怎么选的?
  5. 遗传优化算法优化LSTM-MSE
  6. 永久修改MySQL字符集(适用Mysql5.5、Mysql5.6、Mysql5.7以上)
  7. linux运行h3c校园网,H3C Lite轻量级校园网认证Linux客户端(For SHNU)
  8. windows内核驱动
  9. python音频提取pcm_python 实现录音pcm格式功能
  10. Python 智能检测编码的工具
  11. 通达OA2013完美平台补丁以及手机短信服务配置
  12. 本篇文章带你秒懂——区块链到底是什么鬼?
  13. 电脑DNS被劫持怎么办
  14. 当神话故事邂逅 NFT数字藏品:知名艺术家张宏携《西游》拉开元宇宙序幕
  15. 解决torch.cuda.is_available()返回False的问题
  16. 阿里云ecs 与nas挂载
  17. 人工神经网络及其应用,人工神经网络的实现
  18. 网站推荐-极简壁纸网站
  19. POW,POS,DPOS共识机制简单介绍
  20. 自己写的C盘清理工具 Ver1.0.0

热门文章

  1. NVIDIA VPI -1
  2. Linux Foundation (LSB and FHS)
  3. Linux系统介绍及安装
  4. 简历模板(建议收藏)
  5. maya如何让控制器跟随模型,不脱节?
  6. 《码农翻身》读后感第三天
  7. 常见的神经网络控制结构,神经网络分子结构模型
  8. Linux DNS服务详解——DNS实战配置
  9. 并行和并发哪个好?并行和并发的概念和区别
  10. 高中数学必修4知识点:第三章三角恒等变形