WIN10下配置Yolov3(VS2019,GPU)+opencv训练自己的数据集(绝对详细,小白型记录)

大二菜鸡,因为要准备一个水下识别的比赛,想到了用yolov3这个强大的框架,参考了许多大佬的博客,在这里记录一下自己的配置过程。

**

一、 CUDA和CUDNN配置

**
我的显卡的GTX1060,因为之前为了安装Tensorflow2.0,所以选择CUDA10.0。
下载地址在这:
https://developer.nvidia.com/cuda-10.0-download-archive?target_os=Windows&target_arch=x86_64&target_version=10&target_type=exelocal
下载可能会有点慢,请耐心等待
在这里插入图片描述
CUDA和CUDNN的安装过程参考了这个博客(不用安装tensorflow):
Tensorflow2.0+Anaconda + Windows10+cuda10.0+python3.7+spyder安装教程

在这里要特别提醒一下,在运行CUDA的安装程序的时候记得去C盘找一下C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\extras\visual_studio_integration\MSBuildExtensions这个文件,把它复制一下,之后在配置VS的时候有用。我之后配置的时候在我的CUDA目录下找不到这个文件夹,在网上查了一下这个是只在安装时出现的默认文件,可在"C:\Users\用户名\AppData\Local\Temp\CUDA"下找到。
这是MSBuildExtensions下之后要用到的四个文件
**

二、 OpenCV安装

**
这步很简单,我用的是比较老的3.4.0版,在网站上选择WINDOWS下载即可,网站在这:
官网下载连接
双击下载好的exe文件,选择解压路径后点击Extract即可,解压后会生成一个opencv的文件夹。
在这里插入图片描述将解压后的…opencv\build\x64\vc14\bin添加到环境变量
在这里插入图片描述
到这opencv就安装好了。
**

三、 darknet配置

**
首先在Github官网下载压缩包:
https://github.com/AlexeyAB/darknet
下面可按照这篇博客进行配置(点之前先看一下我下面的说明,配置属性看我的就可以了,我觉得他给的不太详细):
Win10上darknet-yolov3的配置及使用(VS2019)GPU+OpenCV
我们安装的就是CUDA10,博客的步骤一我们可以忽略
步骤二在配置属性->常规->平台工具集处选择Visual Studio 2015(v140),如果你的VS上在Visual Studio 2015(v140)后面显示未安装(我记得是这三个字),请看这里:
在Vistual Studio Installer中选择修改->单个组件->编译器、生成工具和运行时 选择MSVC v140
在这里插入图片描述

步骤四就用到了我在CUDA安装那块提到的4个文件,按照他说的放入对应文件夹。奇怪的是我的MSBuild最初并没有Microsoft.Cpp这个文件,是先把那四个文件放入VS2019的BuildCustomizations目录下运行失败了一次才出现的Microsoft.Cpp\v4.0\V140\BuildCustomizations。
步骤五 配置属性
之前你以前打开了darknet-master\build\darknet\darknet.sln,现在来配置属性,这里我推荐看这篇博客,保证正确,就是注意一下平台工具集咱们用的是2015版的v140工具集和CUDA版本与他不同,无需修改:
win10+vs2017+yolov3+opencv3.4实时目标检测
在所有属性都配置完成后,就可以编译darknet了。

编译成功后下载权重:
https://pjreddie.com/media/files/yolov3.weights
放到darknet-master\build\darknet\x64下
将…\opencv\build\x64\vc14\bin下的opencv_world340.dll 和opencv_world340d.dll 复制到 darknet-master\build\darknet\x64的同级别目录下就可以运行测试图片或视频了,注意视频好像没有例子,自己找一段mp4命名为test放到x64下就可以运行darknet_yolo_v3_video.cmd测试了。

**

四、 训练自己的数据集

**
这里直接给出参考博客,写的很详细,有一些细节我也会列出:
Yolov3:win10下训练自己的数据(GPU版)(详细步骤)
如果没有自己的数据集只是想尝试一下的话可以下载VOC的数据集来当测试,地址如下:
https://pjreddie.com/projects/pascal-voc-dataset-mirror/
因为是测试,在这里我建议选择VOC2007,数据比较少。
在这里插入图片描述
下载之后解压出来是一个叫VOCdevkit的文件夹,我们制作自己的数据集时就按照这种文件格式来就行。
比如我的数据集是自己选取的500张有关海参、海胆、扇贝的图像,标注完的文件在E:\darknet-master\scripts\VOCdevkit\VOC2020下格式如下:
在这里插入图片描述
注意,划掉的labels文件夹在制作时是没有的,是运行voc_label.py之后生成的
Annotations放标注的xml文件,JPEGImages放图片,ImageSets里的Main文件放训练和验证的图片编号,如图:
在这里插入图片描述
在自己制作数据集时可用美图秀秀的批处理软件处理图片编号。
这里给出对应VOC2007和我自己数据集的voc_label.py代码

VOC2007

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

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

classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]


def convert(size, box):
    dw = 1./size[0]
    dh = 1./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_annotation(year, image_id):
    in_file = open('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\Annotations\\%s.xml'%(year, image_id))
    out_file = open('E:\\darknet-master\\scripts\\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('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\labels\\'%(year)):
        os.makedirs('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\labels\\'%(year))
    image_ids = open('E:\\darknet-master\\scripts\\VOCdevkit\\VOC2007\\ImageSets\\Main\\train.txt').read().strip().split()
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('E:\\darknet-master\\build\\darknet\\x64\\data\\obj\\%s.jpg\n'%(image_id))
        convert_annotation(year, image_id)
    list_file.close()

我自己的数据集

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

sets=[('2020', 'train'), ('2020', 'val')]

classes = ["holothurian", "echinus", "scallop"]


def convert(size, box):
    dw = 1./size[0]
    dh = 1./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_annotation(year, image_id):
    in_file = open('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\Annotations\\%s.xml'%(year, image_id))
    out_file = open('E:\\darknet-master\\scripts\\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('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\labels\\'%(year)):
        os.makedirs('E:\\darknet-master\\scripts\\VOCdevkit\\VOC%s\\labels\\'%(year))
    image_ids = open('E:\\darknet-master\\scripts\\VOCdevkit\\VOC2020\\ImageSets\\Main\\train.txt').read().strip().split()
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('E:\\darknet-master\\build\\darknet\\x64\\data\\obj\\%s.jpg\n'%(image_id))
        convert_annotation(year, image_id)
    list_file.close()


运行成功后应该有这些txt文件,就是图片的地址:
在这里插入图片描述
之后继续按照上面博客的内容进行就可以了。在这里特别提醒一下要把之前voc_label.py生成的labels里的txt文件也放入E:\darknet-master\build\darknet\x64\data\obj文件夹,这是由xml转成的txt文件,就是你标注的数据。博客里没细说我忘了放了结果训练了半天一看全是nan…
数据都放好之后在E:\darknet-master\build\darknet\x64下打开cmd,输入:

darknet.exe detector train data/voc.data yolov3-voc.cfg darknet53.conv.74 data/weights  >> yolov3.log

耐心等待就好了,每1000轮会在weights文件夹里生成一个权重,比如1000轮就叫叫yolov3-voc_1000.weights
下面可以用来测试,同样在E:\darknet-master\build\darknet\x64下打开cmd,然后输入:

darknet.exe detector test data/voc.data yolov3-voc.cfg data/yolov3-voc_1000.weights -thresh  0.1

这里的-thresh就是置信度,我一开始测的1000轮的权重发现测试图片没有识别框,因为不加**-thresh 0.1**的话置信度默认0.25,对于训练轮数很少的情况下肯定没有框啦!这个0.1可按自己的情况调整,最后附上我的预测结果:
在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值