caffe训练自己的数据集——1. 数据准备_carplate 数据集_Kindle君的博客-程序员秘密

技术标签: 重命名  数据  脚本  caffe  制作标签  Caffe  

一、重命名数据

1. 参数说明:

  1. rootPath:指定根目录,default=”J:/datasets/car/”,仅对于存在二级目录的时候生效
  2. inputPath:输入目录,default=”J:/datasets/carPlate/test/”,是核心函数singleFileRename的第一个参数
  3. outputPath:输出目录,default=”J:/datasets/carPlate/test/”,设置输出目录与输出目录相同,即重命名会覆盖源文件。也是核心函数singleFileRename的参数之一
  4. prefix:文件名的前缀,default=”,默认不指定前缀,仅用数字进行重命名
  5. suffix:文件名的后缀,default=”,默认不指定后缀,仅用数字进行重命名
  6. digit:数字形式的文件名所用到的位数,default=6,即用6位数对数据进行重命名
  7. picFormat:一般是图片数据,default=’.jpg’

2. 使用方法

  1. 对于单个文件夹:运行python rename.py 调用rename.singleFileRename(args.inputPath,args.outputPath)
    a. 如果inputPath和outputPath均为单个文件,则直接将inputPath重命名成outputPath
    b. 否则,如果均为文件夹,则将该文件夹下所有文件或文件夹,按照digit的长度进行重命名。
    c. rootPath对于单个文件夹不起作用

  2. 对于第二级目录:运行python rename.py调用rename._2_recursiveRename(args.rootPath)

rootPath = "J:/datasets/carPlate/test/"
    test/no:
        1.jpg
        2.jpg
    test/has:
        11.jpg
        22.jpg
a. rootPath="J:/datasets/carPlate/test/",inputPath和outputPath会自动查找到,不需要赋值。
b. 次函数作用是将第二级目录下,所有文件夹所包含的图片重命名。

3. 对于第三级目录:运行python rename.py调用rename._3_recursiveRename(args.rootPath)

rootPath = "J:/datasets/carPlate/"
    carPlate/train:
                no:
                    1.jpg
                    2.jpg
                has:
                    11.jpg
                    22.jpg  
    carPlate/test:
                no:
                    1.jpg
                has:
                    2.jpg
a. rootPath="J:/datasets/carPlate/",inputPath和outputPath会自动查找到,不需要赋值。
b. 此函数作用是将第三级目录下的第二级目录中所包含的图片重命名。

3. 代码如下

#coding: UTF-8
import os
import argparse

class rename:
    def __init__(self, rootPath, inputPath, outputPath, prefix='', suffix='', digit=5, picFormat = '.jpg'):
        self.rootPath  = rootPath
        self.inputPath = inputPath
        self.outputPath = outputPath
        self.prefix = prefix
        self.suffix = suffix
        self.digit = digit
        self.picFormat = picFormat

    def singleFileRename(self,inputPath,outputPath):
        #获取该目录下所有文件,存入列表中
        if os.path.isfile(inputPath):   #如果是已存在的图片
            os.rename(inputPath, outputPath)
            print(inputPath, '========>', outputPath)
        else:   #如果是路径
            files = os.listdir(inputPath)
            num = 0
            for file in files:
                oldname = inputPath + files[num]
                ex = os.path.splitext(file)
                newname = outputPath + '{0}{1:0{3}d}{2}'.format(self.prefix, num, self.suffix, self.digit) + self.picFormat
                os.rename(oldname,newname)
                print(oldname,'========>',newname)
                num+=1

    #二级目录重命名
    def _2_recursiveRename(self,rootPath):
        rootPath = self.rootPath
        #获取该路径下所有的目录,存入列表
        dirs = os.listdir(rootPath)
        for name in dirs:
            inputPath = os.path.join(rootPath, name) + "/"
            if (name[0] == '.'):    #排除隐藏文件
                pass
            else:
                if os.path.isdir(inputPath):    #判断是否是目录
                    outputPath = inputPath
                    self.singleFileRename(inputPath,outputPath)
    #三级目录重命名
    def _3_recursiveRename(self,rootPath):
        rootPath = self.rootPath
        # 获取该路径下所有的目录,存入列表
        dirs = os.listdir(rootPath)
        for _name in dirs:
            _rootPath = os.path.join(rootPath, _name) + "/"
            if (_name[0] == '.'):  # 排除隐藏文件
                pass
            else:
                if os.path.isdir(_rootPath):
                    self.rootPath = _rootPath
                    self._2_recursiveRename(self.rootPath)

def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--rootPath", type=str, default="J:/datasets/car/",help="rootPath with '/' at the end")
    parser.add_argument("--inputPath", type = str, default="J:/datasets/carPlate/test/",
                                                    help="inputPath with '/' at the end or ‘J:/datasets/carPlate/test/0000000.jpg’")
    parser.add_argument("--outputPath", type = str, default="J:/datasets/carPlate/test/",
                                                    help= "outputPath with '/' at the end or 'J:/datasets/carPlate/test/aaaaaa.jpg'")
    parser.add_argument("--prefix", default='', help="文件名的前缀")
    parser.add_argument("--suffix", default='', help="文件名的后缀")
    parser.add_argument("--digit",  default= 6 ,  help="文件名的数字总长度: [1,~]")
    parser.add_argument("--picFormat", default='.jpg',help="图片的格式")
    args = parser.parse_args()
    return args

if __name__== '__main__':
    args = get_args()
    rename = rename(args.rootPath, args.inputPath,args.outputPath,args.prefix,args.suffix,args.digit,args.picFormat)
    #rename.singleFileRename(args.inputPath,args.outputPath)
    #rename._2_recursiveRename(args.rootPath)
    rename._3_recursiveRename(args.rootPath)

二、制作数据

I. 准备原始数据

1. 批量复制

  1. 管道法
for i in `ls`; do fn=`echo $i | awk -F'.' '{print $1}'`; cp $fn.txt $fn"_bak.jpg"; done
  1. 傻瓜式
#!/bin/bash
cd /home/hsy/datasets/carPlate/train/3
for file in $(ls *)
do
    echo $file
    echo ${file%.*}"_back.jpg"
    cp $file ./${file%.*}"_back.jpg"
done
  1. 复制多次
#!/bin/bash
curPath=pwd
cd /home/hsy/datasets/carPlate/test/a
for file in $(ls *)
do
    echo $file
    echo ${file%.*}"_back.jpg"
    fn=`echo $file | awk -F'.' '{print $1}'`
    cp $file ./$fn"_back_1.jpg"
    cp $file ./$fn"_bach_2.jpg"
#cp $file ./${file%.*}"_back_1.jpg"

done

2. 备份数据

tar -zcvf carPlate_train.tar.gz train

II. 制作标签

1. 参数介绍:

  1. root为根目录,可以是直接包含图片数据的一级目录,也可以是包含文件夹的二级目录。default=”M:/datasets/carPlate/train/”注意斜杠
  2. prefix为train.txt文件的存放目录,default=”M:/datasets/carPlate/train/”注意斜杠
  3. exts用于判断读取到的文件是否是图片格式,default=[‘.bmp’, ‘.jpg’]
  4. chunks表示将一组数据分成多少个小段,help=’number of chunks.例如100个数据集,分成4个chunks,每个chunks25个数据’)
  5. train_ratio:如果小于1,则会设置train_ratio比例的数据集作为训练集,其余作为测试集,分别存放在_train.txt_val.txt中,如果chunks不等于1,’例如4个chunks,对于每个chunks会按照train_ratio分成两组,生发到成_0_train.txt和_1_val_txt,一共生成8个文件’,)
  6. recursive,default=True, help=’If true recursively walk through subdirs and assign an unique label\
    to images in each folder. Otherwise only include images in the root folder and give them label 0.’
  7. 程序这条语句random.shuffle(image_list)设置了数据打乱机制,并未作为参数写出来,是为了将来对数据本身进行有针对性的数据增广

2. 使用说明

a. 目录结构如下:可以将root和prefix设置为相同路径,train.txt会保存在这个路径,但是在运行程序之前请确保这个文件不存在于这个路径,因为会重新创建。

    J:\datasets\carPlate\test
            a:
                1.jpg
                2.jpg
            b:
                1.jpg
                2.jpg

b. 运行python make_list_linux.py,在代码中打开image_list.append((os.path.relpath(fpath, root), cat[path]))可以生成如下格式的相对路径:

    /home/hsy/datasets/carPlate/test/a/000000.jpg 1
    /home/hsy/datasets/carPlate/test/b/000001.jpg 0
    /home/hsy/datasets/carPlate/test/b/000003.jpg 0
    /home/hsy/datasets/carPlate/test/b/000004.jpg 0
    /home/hsy/datasets/carPlate/test/a/000001.jpg 1
    /home/hsy/datasets/carPlate/test/a/000004.jpg 1
    /home/hsy/datasets/carPlate/test/b/000002.jpg 0
    /home/hsy/datasets/carPlate/test/a/000002.jpg 1
    /home/hsy/datasets/carPlate/test/a/000003.jpg 1
    /home/hsy/datasets/carPlate/test/b/000000.jpg 0

c. 使用train_ratio参数,可以先选出一小部分数据集用于预训练,但如果shuffle之后,可能出现正负样本失衡且不可控的情况,所以选择小样本时,最好不要shuffle或者将正负样本分开

  1. 代码如下
#coding: UTF-8
import fnmatch, os
import random
import numpy as np
import argparse


def list_image(root, recursive, exts):
    image_list = []
    if recursive:
        cat = {}
        for path, subdirs, files in os.walk(root):
            print path
            # print subdirs #注释掉
            for fname in files:
                fpath = os.path.join(path, fname)
                suffix = os.path.splitext(fname)[1].lower()
                if os.path.isfile(fpath) and (suffix in exts):
                    if path not in cat:
                        cat[path] = len(cat) #表示第n个文件夹
                print cat[path]
                # os.path.relpath(fpath, root)返回从root到fpath的相对路径
                #image_list.append((os.path.relpath(fpath, root), cat[path]))
                #将图片的绝对路径写入到train.txt,但有时候还会报奇怪的unexpected indent错误,应该是空格问题
                image_list.append((os.path.relpath(fpath, root), cat[path]))
                print fpath #注释掉
                print (cat[path]) #注释掉
    else:
        for fname in os.listdir(root):
            fpath = os.path.join(root, fname)
            suffix = os.path.splitext(fname)[1].lower()
            if os.path.isfile(fpath) and (suffix in exts):
                image_list.append((os.path.relpath(fpath, root), 0))
    return image_list


def write_list(path_out, image_list):
    with open(path_out, 'w') as fout:
        for i in xrange(len(image_list)):
            # fout.write('%d \t %d \t %s\n'%(i, image_list[i][1], image_list[i][0]))
            fout.write('%s %d\n' % (image_list[i][0], image_list[i][1]))  #改为这样的格式


def make_list(prefix_out, root, recursive, exts, num_chunks, train_ratio):
    image_list = list_image(root, recursive, exts)
    random.shuffle(image_list)
    N = len(image_list)
    # num_chunks表示数据的段数,chunk_size表示每段数据的个数
    # N+ (num_chunks-1)是为了保证所有数据都被用上,如果不加,最后计算得到的余数个数据就不会被计算进去
    chunk_size = (N + num_chunks - 1) / num_chunks
    for i in xrange(num_chunks):
        chunk = image_list[i * chunk_size:(i + 1) * chunk_size]
        if num_chunks > 1:
            str_chunk = '_%d' % i
        else:
            str_chunk = ''
        if train_ratio < 1:
            sep = int(chunk_size * train_ratio)
            write_list(prefix_out + str_chunk + '_train.txt', chunk[:sep])  # 输出文件更改为txt
            write_list(prefix_out + str_chunk + '_val.txt', chunk[sep:])
        else:
            write_list(prefix_out + str_chunk + 'train.txt', chunk)


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description='Make image list files that are required by im2rec')
    parser.add_argument('--root', default="M:/datasets/carPlate/train/", help='path to folder that contain images.')
    parser.add_argument('--prefix',default="M:/datasets/carPlate/train/", help='prefix of output list files.')
    parser.add_argument('--exts', type=list, default=['.bmp', '.jpg'],
                        help='list of acceptable image extensions.')  # 注意图片的格式 我这里是bmp  根据实际更改
    parser.add_argument('--chunks', type=int, default=1, help='number of chunks.例如100个数据集,分成4个chunks,每个chunks25个数据')
    parser.add_argument('--train_ratio', type=float, default=1, help='Percent of images to use for training.'
                        '例如4个chunks,对于每个chunks会按照train_ratio分成两组,生发到成_0_train.txt和_1_val_txt,一共生成8个文件',)
    parser.add_argument('--recursive', type=bool, default=True,
                        help='If true recursively walk through subdirs and assign an unique label\
    to images in each folder. Otherwise only include images in the root folder \
                                                                        and give them label 0.')
    args = parser.parse_args()

    make_list(args.prefix, args.root, args.recursive,
              args.exts, args.chunks, args.train_ratio)

if __name__ == '__main__':
    main()

III. 生成标签

0. 数据说明

这里的数据集来自于:
N:\项\车牌项目\唐佩君师姐的资料\training(clib,6.26号,准确度95%)
N:\项\车牌项目\唐佩君师姐的资料\testing

黄色:2000 蓝色:2000 白色:2000 非车牌:13438 
正样本一共6000张
负样本一共13438张
总共19438张
蓝:0 黄:1 白:2 非:3

1. 重命名

这个步骤速度还挺快的

a. 利用第一部分代码(名为```rename_linux.py```)中的rename._2_recursiveRename(args.rootPath)函数,
b. 设置位数digit=6,rootPath="/home/hsy/datasets/carPlate/train/",inputPath和outputPath不用设置
c. 运行python rename_linux.py即可对train下的多个文件夹下的图片进行重命名。

2. 生成样本标签

分三批生成样本,分别占总样本数量的10%,30%,100%,每次都利用代码中random.shuffle(image_list)打乱数据

a. 设置路径:root=prefix="/home/hsy/datasets/carPlate/train/"
b. 设置chunks=1, train_ratio=0.1,生成第一批,并改名为train_10.txt
c. 设置chunks=1, train_ratio=0.3,生成第二批,并改名为train_30.txt
d. 设置chunks=1, train_ratio=1.0,生成第三批,并改名为train_100.txt
每两次之间,记得把生成的train_xx.txt移动到其他文件夹,否则会报错。

IV 数据转换

参考链接http://blog.csdn.net/AlexQiweek/article/details/51281240

1. 示例说明

/opt/caffe/build/tools/convert_imageset \
--resize_height=32 \
--resize_width=32 \
/home/datasets/carPlate/train/  #训练文件的根目录
/home/datasets/carPlate/train/train_10.txt #标签所在目录
/home/datasets/carPlate/train_test_labels/train_10 #生成的lmdb存放目录,必须是未存在过的目录
#--gray=ture #生成灰度图
#--shuffle #随机排序

运行之后会在“/home/datasets/carPlate/train_test_labels/train_10 ”路径下生成data.mdblock.mdb两个文件

2. 批量转换

/opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/train/ /home/datasets/carPlate/train_test_labels/train_10.txt /home/datasets/carPlate/train_test_labels/train_10
 1381  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/train/ /home/datasets/carPlate/train_test_labels/train_50.txt /home/datasets/carPlate/train_test_labels/train_50
 1382  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/train/ /home/datasets/carPlate/train_test_labels/train_30.txt /home/datasets/carPlate/train_test_labels/train_30
 1383  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/train/ /home/datasets/carPlate/train_test_labels/train_100.txt /home/datasets/carPlate/train_test_labels/train_100
 1384  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/test/G1-5/G1/ /home/datasets/carPlate/train_test_labels/val_G1.txt /home/datasets/carPlate/train_test_labels/val_G1
 1385  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/test/G1-5/G2/ /home/datasets/carPlate/train_test_labels/val_G2.txt /home/datasets/carPlate/train_test_labels/val_G2
 1386  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/test/G1-5/G3/ /home/datasets/carPlate/train_test_labels/val_G3.txt /home/datasets/carPlate/train_test_labels/val_G3
 1387  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/test/G1-5/G4/ /home/datasets/carPlate/train_test_labels/val_G4.txt /home/datasets/carPlate/train_test_labels/val_G4
 1388  /opt/caffe/build/tools/convert_imageset --resize_height=32 --resize_width=32 /home/datasets/carPlate/test/G1-5/G5/ /home/datasets/carPlate/train_test_labels/val_G5.txt /home/datasets/carPlate/train_test_labels/val_G5

3. 求取均值

#训练集
/opt/caffe/build/tools/compute_image_mean \
/home/datasets/carPlate/train_test_labels/train_10 \    #lmdb文件所在路径
/home/datasets/carPlate/train_test_labels/train_10/train_10_mean.binaryproto\ #生成的均值文件所在路径
 #测试集
/opt/caffe/build/tools/compute_image_mean \
/home/datasets/carPlate/train_test_labels/val_G1 \
/home/datasets/carPlate/train_test_labels/val_G1/val_G1_mean.binaryproto

V. 训练及测试

参见我写的另一篇博客

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yexiaogu1104/article/details/77932198

智能推荐

usaco 4.4 Frame Up(拓扑排序)_Pira的博客-程序员秘密

Frame UpConsider the following five picture frames shown on an 9 x 8 array:........ ........ ........ ........ .CCC....EEEEEE.. ........ ........ ..BBBB.. .C.C....E....E.. DD

分形<二>分形的递归算法_递归分形算法_幺鸡报晓的博客-程序员秘密

一.canto三分集递归算法。1)核心的自身算法。2)递归调用。3)给定递归深度。**在libgdx框架上有方便绘制几何图形的ShapeRenderer类,它和Batch画笔都封装了调用底层渲染的接口。注:**标签的段落无关分形算法,是渲染框架上的一些笔记。三分集递归算法:private void canto(int ax,int ay,int bx,int by){

开源一款强大的文件服务组件(QJ_FileCenter)(系列二 安装说明)_一朝春尽红颜老的博客-程序员秘密

系列文章1. 开源一款强大的文件服务组件(QJ_FileCenter)(系列一)2. 开源一款强大的文件服务组件(QJ_FileCenter)(系列二 安装说明)3. 开源一款强大的文件服务组件(QJ_FileCenter)(系列三 访问接口与项目集成)计划中...4. 开源一款强大的文件服务组件(QJ_FileCenter)(系列四 文件结构)计划中...5. 开源一款强大的文件服务组件(QJ_...

SpringMvc-Httl-shiro的整合_weixin_33862993的博客-程序员秘密

来到新的公司一个月,以前实习公司的用的是srping+hibernate+struts2,而在这里不在用的这些了,而是用的springMVC和jdbc模板来操作数据了,所以又用了一段时间去慢慢融入这个新的体系中去;但终究这些技术是万变不离其宗的,学习也是很快的事,所以我也就很快的就融入了这个团队;进入正题吧!我这里其实就是想把学习新东西自己记录下来,这有助于我的学习也有助于大家的学习;把spr...

shopnc mysql_shopnc配置_chsqi的博客-程序员秘密

ShopNC B2B2C商城包含多个独立模块,各独立模块均有自己的配置文件,配置文件整理如下:说明目录位置全局配置文件[1](需手动编辑)data/config/config.ini.php全局配置文件[2](后台可自动编辑)data/cache/setting.php后台管理配置文件admin/config/config.ini.phpCMS配置文件cms/config/config.ini.p...

苹果手机刷机显示无法联系软件更新服务器,为什么苹果手机无法自动更新软件怎么办..._haoxiang lin的博客-程序员秘密

1.苹果手机不能自动更新软件了怎么办苹果手机不能自动更新软件的解决办法:苹果手机更新软件需要保存一定的电量和充足的内存1.清空Safari缓存,需要进入【设置】-【Safari】,然后点击“清除历史记录”和“清除Cookies和数据”。2.删除旧的无用照片和视频 删除不必要的文件是加速手机运行速度的主要方式之一。苹果手机删除照片过于麻烦,可以借用第三方软件来清理,苹果已经开放腾讯手机管家权限3.重...

随便推点

通过Boomerang按计划在Gmail中发送或接收电子邮件(并且我们有邀请)_culun797375的博客-程序员秘密

Have you ever needed to send or receive an email at a different time, and wanted to schedule it? Boomerang is a new beta addon for Google Chrome and Firefox that lets you schedule Gmail around your t...

java 代码结构_代码结构说明_陈良乔的博客-程序员秘密

代码结构说明===## 一、JEECG目录结构### 1.配置文件目录结构JEECG中的配置文件目录结构如图3-1所示。![输入图片说明](https://static.oschina.net/uploads/img/201804/17180158_r7Hu.png "在这里输入图片标题")图3-1 JEECG配置文件目录结构### 2.Java源码目录结构JEECG中的Java源码目录结构如图3...

RobotFramework(RF)+Appium完全安装环境搭建和配置的解决方案_猎摘互联网软件测试业界技术文章专用博客的博客-程序员秘密

【本博客原创,都是经过博主本人全程操作安装过的,踩过的坑都记录在本文,有兴趣的读者跟着做一遍~~~】一、搭建环境流程1.先安装python2.7环境(python-2.7.14.amd64.msi),(1)再安装第三方库:wxPython(32位的电脑就安装win32,64位的就安装win64,一旦装错RIDE就会运行不起来)(2)robotframwork(robotframework-2.9....

LeetCode算法题-Perfect Number(Java实现)_程序员小川的博客-程序员秘密

这是悦乐书的第249次更新,第262篇原创01 看题和准备今天介绍的是LeetCode算法题中Easy级别的第116题(顺位题号是507)。我们定义Perfect Number是一个正整数,它等于除了它自己之外的所有正除数之和。现在,给定一个整数n,编写一个函数,当它是一个完美数字时返回true,否则返回false。例如:输入:28输出:true说明:28 = 1 + 2 + 4 + ...

windows +caffe+python2.7或者python3.5编译 。_燕儿归的博客-程序员秘密

caffe 只支持python2.7和3.5。想要编译caffe需要vs2013和vs2015,并且cpu版和gpu版不通用。很坑。python2.7和python3.5中的print方法 一个是 print "hello",一个是print("hello")。有时候需要报错咱们手动改。前期编译的大部分No module错误都可以通过pip install 解决。(另外No module的时候最好到百度搜一下,有个别情况pip安装的包名和报错的包名不一样,但是他们俩是一个。)我安装python3

OSGi (三)_osgi<import-package>_第七感 de秘密的博客-程序员秘密

OSGi (三)1. 什么是 bundlebundle 是以 jar 包形式存在的一个模块化物理单元,里面包含了代码,资源文件和元数据(metadata),并且 jar 包的物理边界也同时是运行时逻辑模块的封装边界。2. MANIFEST.MF 规范位置:META-NF/MANIFEST.MF文件格式属性声明的一般格式是 name: value一行不超过 72 个字符,下一行则由单个空格字符开始3. bundle 常用标识符标识符说明Bundle-Categ

推荐文章

热门文章

相关标签