【图像识别与处理】darket-训练自己的yolov3模型

1 安装darknet
1.1下载库文件
git clone https://github.com/pjreddie/darknet
cd darknet
1.2 修改Makefile
GPU=1
CUDNN=1
OPENCV=1
OPENMP=0
DEBUG=0
1.3 编译
make

编译错误: error: /usr/bin/ld: cannot find -lcudnn
解决办法:

cd  ~/tools/cuda/lib64
sudo cp libcudnn.so /usr/lib
sudo gedit /etc/ld.so.conf     最后一行添加include /usr/lib
ldconfig
复制cudnn.h到/usr/local/cuda-9.0/include
复制lib64的内容到/usr/local/cuda-9.0/lib64/
make all -j8

在这里插入图片描述

1.4 下载预训练模型
wget https://pjreddie.com/media/files/yolov3.weights
1.5 用预训练模型进行简单的测试
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

报错:cuda error: out of memory darknet: ./src/cuda.c:36: check_error: Assertion `0’ failed.
原因:内存溢出

解决办法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190417171247717.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1MTEyOTAwNTE2NQ==,size_16,color_FFFFFF,t_70

如果上面这样做还是出现内存不足的现象,那么只有两种方案了,要么用小一点的模型,要么就更改cfg目录下yolov3.cfg第8、9行height和width值了,我修改为宽高都为416,再测试就没问题了。修改后的yolo.cfg文件:

在这里插入图片描述成功运行:
在这里插入图片描述

2 训练Pascal VOC格式的数据
2.1 准备训练数据

在深度学习的模型训练中,数据的收集十分重要,取得足够的数据集对于最终模型的表现有十分重要的意义。但是开源的数据集都指定了特定的目标进行标注,如行人,车辆。当要训练自己所需要的特定检测模型,却又没有开源数据集的时候,就需要自己去收集和标注图像数据用于训练了。

1…收集数据
通过从百度图片上爬图片来进行数据收集

# coding=utf-8
"""根据搜索词下载百度图片"""
import re
import sys
import urllib

import requests


def get_onepage_urls(onepageurl):
    """获取单个翻页的所有图片的urls+当前翻页的下一翻页的url"""
    if not onepageurl:
        print('已到最后一页, 结束')
        return [], ''
    try:
        html = requests.get(onepageurl).text
    except Exception as e:
        print(e)
        pic_urls = []
        fanye_url = ''
        return pic_urls, fanye_url
    pic_urls = re.findall('"objURL":"(.*?)",', html, re.S)
    fanye_urls = re.findall(re.compile(r'<a href="(.*)" class="n">下一页</a>'), html, flags=0)
    fanye_url = 'http://image.baidu.com' + fanye_urls[0] if fanye_urls else ''
    return pic_urls, fanye_url


def down_pic(pic_urls):
    """给出图片链接列表, 下载所有图片"""
    for i, pic_url in enumerate(pic_urls):
        try:
            pic = requests.get(pic_url, timeout=15)
            string = str(i + 1) + '.jpg'
            with open(string, 'wb') as f:
                f.write(pic.content)
                print('成功下载第%s张图片: %s' % (str(i + 1), str(pic_url)))
        except Exception as e:
            print('下载第%s张图片时失败: %s' % (str(i + 1), str(pic_url)))
            print(e)
            continue


if __name__ == '__main__':
    keyword = '车'  # 关键词, 改为你想输入的词即可, 相当于在百度图片里搜索一样
    url_init_first = r'http://image.baidu.com/search/flip?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1497491098685_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&ctd=1497491098685%5E00_1519X735&word='
    url_init = url_init_first + urllib.quote(keyword, safe='/')
    all_pic_urls = []
    onepage_urls, fanye_url = get_onepage_urls(url_init)
    all_pic_urls.extend(onepage_urls)

    fanye_count = 0  # 累计翻页数
    while 1:
        onepage_urls, fanye_url = get_onepage_urls(fanye_url)
        fanye_count += 1
        print('第%s页' % fanye_count)
        if fanye_url == '' and onepage_urls == []:
            break
        all_pic_urls.extend(onepage_urls)

    down_pic(list(set(all_pic_urls)))

在这里插入图片描述2.数据标定
图像标注格式PASCAL VOC
1)安装labelimage

下载labelImg源码: https://github.com/tzutalin/labelImg
sudo apt-get install pyqt4-dev-tools
cd labelImg
make all

运行 labelimage.py
在这里插入图片描述2) 使用labelimage做图像标注

a. 将图片文件保存在一个文件夹内,里面最好不要包含子文件夹
b. 图片文件名不要出现两个“.”(例如dog.1.jpg建议改成dog_1.jpg) 不然无法正确导出xml
c.打开labelImage, 点击左边工具栏"Open Dir"找到你保存图片的文件夹再点击"choose",之后在右下角File List你可以看到文件夹内全部图片的列表
d.按快捷键“W”松开后用鼠标可对物体进行框选,同时弹出对话框。如果列表内没有标签直接输入后回车即可,新标签就加入到列表里。如果列表内已含有标签,双击即可
e.确定标注无误后,按快捷键ctrl+s保存xml文件,对话框直接点save,会保存成与图片文件同名的xml文件
在这里插入图片描述在这里插入图片描述

2.1 处理数据

利用以下脚本生成train.txt:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 12 17:50:26 2017

@author: seven
"""

import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
    source_folder='/home/xuxuejie/software/python/pictures/cat/'#地址是所有图片的保存地点
    dest='/home/xuxuejie/software/python/pictures/cat/train.txt' #保存train.txt的地址
    file_list=os.listdir(source_folder)       #赋值图片所在文件夹的文件列表
    train_file=open(dest,'a')                 #打开文件
    for file_obj in file_list:                #访问文件列表中的每一个文件
        file_path=os.path.join(source_folder,file_obj)
        file_name,file_extend=os.path.splitext(file_obj)
        #file_name 保存文件的名字,file_extend保存文件扩展名
        file_num=int(file_name)
        train_file.write(file_name+'\n')
    train_file.close()#关闭文件

生成的train.txt包含着训练集每一张图片的文件名,之后利用train.txt通过下面的脚本生成每个图像对应的(图像名).txt文件和infrared_train.txt文件。(图像名).txt文件中包含着图像中目标的位置和类别标签,infrared_train.txt文件中包含着每个图片的完整路径。

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 12 17:50:26 2017

@author: seven
"""

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
classes = ["plate"]#类别改为自己需要检测的所有类别
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(image_id):
    in_file = open('/home/seven/darknet/infrared/plate/xml/%s.xml'%(image_id))#与图片对应的xml文件所在的地址
    out_file = open('/home/seven/darknet/infrared/plate/txt/%s.txt'%(image_id),'w') #与此xml对应的转换后的txt,这个txt的保存完整路径
    tree=ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')  #访问size标签的数据
    w = int(size.find('width').text)#读取size标签中宽度的数据
    h = int(size.find('height').text)#读取size标签中高度的数据

    for obj in root.iter('object'):
       # difficult = obj.find('difficult').text   #没设difficult,所以屏蔽
        cls = obj.find('name').text
        if cls not in classes :#or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')   #访问boundbox标签的数据并进行处理,都按yolo自带的代码来,没有改动
        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')


image_ids = open('/home/seven/darknet/infrared/train.txt').read().strip().split()  
list_file = open('/home/seven/darknet/infrared/infrared_train.txt', 'w')    
for image_id in image_ids:
    list_file.write('/home/seven/darknet/infrared/plate/image/%s.jpg\n'%(image_id))  #把每一用于训练或验证的图片的完整的路径写入到infrared_train.txt中  这个文件会被voc.data yolo.c调用
    convert_annotation(image_id)   #把图片的名称id传给函数,用于把此图片对应的xml中的数据转换成yolo要求的txt格式
list_file.close() #关闭文件

至此,我们成功生成了一个文件夹的(图片名).txt文件和一个infrared_train.txt文件。将那一个文件夹的(图片名).txt文件复制到图片所在的文件夹中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿着帆布鞋也能走猫步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值