Fork版本项目地址:SSD

一、数据格式介绍

数据文件夹命名为VOC2012,内部有5个子文件夹,如下,

我们的检测任务中使用JPEGImages文件夹和Annotations文件夹。

JPEGImages文件夹中包含了PASCAL VOC所提供的所有的图片信息,包括了训练图片和测试图片。

这些图像都是以“年份_编号.jpg”格式命名的。
图片的像素尺寸大小不一,但是横向图的尺寸大约在500*375左右,纵向图的尺寸大约在375*500左右,基本不会偏差超过100。(在之后的训练中,第一步就是将这些图片都resize到300*300或是500*500,所有原始图片不能离这个标准过远。)
这些图像就是用来进行训练和测试验证的图像数据。
Annotations文件夹中存放的是xml格式的标签文件,每一个xml文件都对应于JPEGImages文件夹中的一张图片。

xml文件的具体格式如下:(对于2007_000392.jpg)

<annotation><folder>VOC2012</folder>                           <filename>2007_000392.jpg</filename>             //文件名<source>                                         //图像来源(不重要)<database>The VOC2007 Database</database><annotation>PASCAL VOC2007</annotation><image>flickr</image></source><size>                                     //图像尺寸(长宽以及通道数)                        <width>500</width><height>332</height><depth>3</depth></size><segmented>1</segmented>                   //是否用于分割(在图像物体识别中01无所谓)<object>                                       //检测目标<name>horse</name>                        //物体类别<pose>Right</pose>                        //拍摄角度<truncated>0</truncated>                  //是否被截断(0表示完整)<difficult>0</difficult>                  //目标是否难以识别(0表示容易识别)<bndbox>                                  //bounding-box(包含左上角和右下角xy坐标)<xmin>100</xmin><ymin>96</ymin><xmax>355</xmax><ymax>324</ymax></bndbox></object><object>                                      //多检测目标<name>person</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>198</xmin><ymin>58</ymin><xmax>286</xmax><ymax>197</ymax></bndbox></object>
</annotation>

二、TFR数据生成流程

为了加快数据的读取,框架将数据及标签预先读取并写入tfrecord中,这一部分独立于网络或者说训练结构之外,我们单独介绍这一部分。

启动命令如下,注意需要提前建好OUTPUT_DIR文件夹否则会报错(运行命令时去掉注释),

DATASET_DIR=./VOC2012/
OUTPUT_DIR=./tfrecords
python tf_convert_data.py \--dataset_name=pascalvoc \  # 数据集名称,实际作者就实现了这一个数据集的预处理方法--dataset_dir=${DATASET_DIR} \--output_name=voc_2012_train  # tfr文件名,为了兼容后面的程序,命名格式较为固定--output_dir=${OUTPUT_DIR}

脚本tf_convert_data.py

这个脚本主要用于和命令行交互,核心功能就一句调用命令:

# './VOC2012/' './tfrecords' 'voc2012_tfr'
pascalvoc_to_tfrecords.run(FLAGS.dataset_dir, FLAGS.output_dir, FLAGS.output_name)

脚本datasets.pascalvoc_to_tfrecords.py

run函数是tfr书写的核心函数,在这个函数中,我们确定具体的每一个tfr文件名,循环的读取图片和标签数据名称,按照指定的容量取书写到每一个tfr文件。

def run(dataset_dir, output_dir, name='voc_train', shuffling=False):"""Runs the conversion operation.Args:dataset_dir: The dataset directory where the dataset is stored.output_dir: Output directory."""if not tf.gfile.Exists(dataset_dir):tf.gfile.MakeDirs(dataset_dir)# Dataset filenames, and shuffling.# './VOC2012/' 'Annotations/'path = os.path.join(dataset_dir, DIRECTORY_ANNOTATIONS)filenames = sorted(os.listdir(path))  # 无路径文件名if shuffling:random.seed(RANDOM_SEED)random.shuffle(filenames)# Process dataset files.i = 0fidx = 0while i < len(filenames):  # 循环文件名# Open new TFRecord file.tf_filename = _get_output_filename(output_dir, name, fidx)  # 获取输出文件名with tf.python_io.TFRecordWriter(tf_filename) as tfrecord_writer:j = 0while i < len(filenames) and j < SAMPLES_PER_FILES:  # 一个文件200张图sys.stdout.write('\r>> Converting image %d/%d' % (i+1, len(filenames)))sys.stdout.flush()  # 这两句的输出不会生成多行报告,而是在同一行不断更新数字filename = filenames[i]img_name = filename[:-4]  # 图片名称,去掉字符'.jpg'_add_to_tfrecord(dataset_dir, img_name, tfrecord_writer)  # 获取数据并书写i += 1j += 1fidx += 1# Finally, write the labels file:# labels_to_class_names = dict(zip(range(len(_CLASS_NAMES)), _CLASS_NAMES))# dataset_utils.write_label_file(labels_to_class_names, dataset_dir)print('\nFinished converting the Pascal VOC dataset!')

这其中,确定具体的每一个tfr文件名函数_get_output_filename很简单,而由文件名读取数据并书写进tfr函数也就分为读文件和写文件两步骤,都很直观,

def _add_to_tfrecord(dataset_dir, name, tfrecord_writer):"""Loads data from image and annotations files and add them to a TFRecord.Args:dataset_dir: Dataset directory;name: Image name to add to the TFRecord;tfrecord_writer: The TFRecord writer to use for writing."""image_data, shape, bboxes, labels, labels_text, difficult, truncated = \_process_image(dataset_dir, name)  # 由文件名读取数据example = _convert_to_example(image_data, labels, labels_text,bboxes, shape, difficult, truncated)  # 书写tfrtfrecord_writer.write(example.SerializeToString())def _get_output_filename(output_dir, name, idx):return '%s/%s_%03d.tfrecord' % (output_dir, name, idx)

下面是读取图片、标签数据以及书写example的两个函数,实际工作中就是这样每次读取一个图片文件及其对应的标注文件并处理,

def _process_image(directory, name):"""将图片数据存储为bytes,:param directory: voc文件夹:param name: 图片名:return: 需要写入tfr的数据"""# Read the image file.# DIRECTORY_IMAGES = 'JPEGImages/'filename = directory + DIRECTORY_IMAGES + name + '.jpg'image_data = tf.gfile.FastGFile(filename, 'rb').read()  # 源码中'rb'错写成'r'# Read the XML annotation file.filename = os.path.join(directory, DIRECTORY_ANNOTATIONS, name + '.xml')tree = ET.parse(filename)root = tree.getroot()# Image shape.size = root.find('size')shape = [int(size.find('height').text),int(size.find('width').text),int(size.find('depth').text)]# Find annotations.bboxes = []labels = []labels_text = []difficult = []truncated = []for obj in root.findall('object'):label = obj.find('name').textlabels.append(int(VOC_LABELS[label][0]))labels_text.append(label.encode('ascii'))if obj.find('difficult'):difficult.append(int(obj.find('difficult').text))else:difficult.append(0)if obj.find('truncated'):truncated.append(int(obj.find('truncated').text))else:truncated.append(0)bbox = obj.find('bndbox')bboxes.append((float(bbox.find('ymin').text) / shape[0],float(bbox.find('xmin').text) / shape[1],float(bbox.find('ymax').text) / shape[0],float(bbox.find('xmax').text) / shape[1]))return image_data, shape, bboxes, labels, labels_text, difficult, truncateddef _convert_to_example(image_data, labels, labels_text, bboxes, shape,difficult, truncated):"""Build an Example proto for an image example.Args:image_data: string, JPEG encoding of RGB image;labels: list of integers, identifier for the ground truth;labels_text: list of strings, human-readable labels;bboxes: list of bounding boxes; each box is a list of integers;specifying [xmin, ymin, xmax, ymax]. All boxes are assumed to belongto the same label as the image label.shape: 3 integers, image shapes in pixels.Returns:Example proto"""xmin = []ymin = []xmax = []ymax = []for b in bboxes:assert len(b) == 4# pylint: disable=expression-not-assigned[l.append(point) for l, point in zip([ymin, xmin, ymax, xmax], b)]# pylint: enable=expression-not-assignedimage_format = b'JPEG'example = tf.train.Example(features=tf.train.Features(feature={'image/height': int64_feature(shape[0]),'image/width': int64_feature(shape[1]),'image/channels': int64_feature(shape[2]),'image/shape': int64_feature(shape),'image/object/bbox/xmin': float_feature(xmin),'image/object/bbox/xmax': float_feature(xmax),'image/object/bbox/ymin': float_feature(ymin),'image/object/bbox/ymax': float_feature(ymax),'image/object/bbox/label': int64_feature(labels),'image/object/bbox/label_text': bytes_feature(labels_text),'image/object/bbox/difficult': int64_feature(difficult),'image/object/bbox/truncated': int64_feature(truncated),'image/format': bytes_feature(image_format),  # 图像编码格式'image/encoded': bytes_feature(image_data)}))  # 二进制图像数据return example

至此,数据预处理tfr文件生成步骤就完成了。

附录、Example feature生成函数

具体的example feature生成函数比较简单,为了完整性,下面给出来,位于程序脚本datasets.dataset_utils.py中:

def int64_feature(value):"""Wrapper for inserting int64 features into Example proto."""if not isinstance(value, list):value = [value]return tf.train.Feature(int64_list=tf.train.Int64List(value=value))def float_feature(value):"""Wrapper for inserting float features into Example proto."""if not isinstance(value, list):value = [value]return tf.train.Feature(float_list=tf.train.FloatList(value=value))def bytes_feature(value):"""Wrapper for inserting bytes features into Example proto."""if not isinstance(value, list):value = [value]return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))

标签数字序号对应表

VOC_LABELS = {'none': (0, 'Background'),'aeroplane': (1, 'Vehicle'),'bicycle': (2, 'Vehicle'),'bird': (3, 'Animal'),'boat': (4, 'Vehicle'),'bottle': (5, 'Indoor'),'bus': (6, 'Vehicle'),'car': (7, 'Vehicle'),'cat': (8, 'Animal'),'chair': (9, 'Indoor'),'cow': (10, 'Animal'),'diningtable': (11, 'Indoor'),'dog': (12, 'Animal'),'horse': (13, 'Animal'),'motorbike': (14, 'Vehicle'),'person': (15, 'Person'),'pottedplant': (16, 'Indoor'),'sheep': (17, 'Animal'),'sofa': (18, 'Indoor'),'train': (19, 'Vehicle'),'tvmonitor': (20, 'Indoor'),
}

『TensorFlow』SSD源码学习_其四:数据介绍及TFR文件生成相关推荐

  1. 『TensorFlow』SSD源码学习_其二:基于VGG的SSD网络前向架构

    Fork版本项目地址:SSD 参考自集智专栏 一.SSD基础 在分类器基础之上想要识别物体,实质就是 用分类器扫描整张图像,定位特征位置 .这里的关键就是用什么算法扫描,比如可以将图片分成若干网格,用 ...

  2. Opencascade源码学习之模型数据

    Opencascade源码学习之模型数据 1.模型数据 2.几何工具 1.插值和拟合 1.分析一组点 2.基本插值和近似 3.2D 插值 4.3D 插值 5.2D 拟合 6.3D 拟合 7.曲面拟合 ...

  3. Opencascade源码学习之模型数据——TKGeomBase模块文件介绍

    Opencascade源码学习之模型数据--TKGeomBase模块文件介绍 1.AdvApp2Var 2.AppCont 3.AppDef 4.AppParCurves 5.Approx 6.Bnd ...

  4. 【Qt】通过QtCreator源码学习Qt(一):pro文件

    1.学习目的 学习pro文件的语法规则,这在跨平台项目中会经常用到.和条件编译相似,在pro中可以根据平台选择不同的编译模块.文件,还可以向源码中传递变量等. 2.学习方法 通过学习QtCreator ...

  5. python源码学习_【Python学习】Python源码阅读(一)

    最近想读读Python源码,任何东西学习方法基本都是一样的,先从总体框架进行了解,再从自己侧重的方面逐步深入. 1. Python总体架构 左边是Python提供的大量的模块.库以及用户自定义的模块. ...

  6. [转]『TensorFlow』读书笔记_TFRecord学习

    转自:https://www.cnblogs.com/hellcat/p/8146748.html#_label0_3 目录 程序介绍 包导入 TFRecord录入格式转换 TFRecord文件写入测 ...

  7. 百度Apollo源码学习之Bazel编译介绍

    image.png 什么是Bazel Bazel是一个类似于Make的编译工具,是Google为其内部软件开发的特点量身定制的工具,如今Google使用它来构建内部大多数的软件.(怪不得看起来很像An ...

  8. ThinkPHP源码学习 data_to_xml函数 数据转成xml格式

    /**  * 数据XML编码  * @param mixed  $data 数据  * @param string $item 数字索引时的节点名称  * @param string $id   数字 ...

  9. srsLTE源码学习:协议数据单元PDU:pdu.h

    TX与RX TXD 发送数据 Transmit(tx) Data 的简写形式. RXD 接收数据 Receive(rx) Data 的简写形式. x没有特定的意思,就是一开始这么写,之后都这么用了,约 ...

  10. python 动漫卡通人物图片大全,『TensorFlow』DCGAN生成动漫人物头像_下

    一.计算图效果以及实际代码实现 计算图效果 实际模型实现 相关介绍移步我的github项目. 二.生成器与判别器设计 生成器 相关参量, 噪声向量z维度:100 标签向量y维度:10(如果有的话) 生 ...

最新文章

  1. 动态加载laydate 失效_弹簧的失效分析与预防技术参考
  2. jenkins_使用Jenkins / Hudson远程API检查作业状态
  3. 深度剖析目标检测算法YOLOV4
  4. 电子产品设计流程_指纹锁生产的八大工序流程
  5. 提高抗打击能力_如果提高心理抗打击能力?
  6. 怎样让防火墙跟其他网络设备实现时钟同步
  7. 算法之排序算法-直接插入排序
  8. Bootstrap(一)——简介、布局容器和工具类使用(flex布局)
  9. 通知模式实现两个textField传值及模态视图——iOS开发
  10. python小白从哪来开始-写给小白的工程师入门 - 从 Python 开始
  11. WannaCry深度详细分析报告 转
  12. yolo标签没有字 windows_对yolo系列的理解
  13. 单龙芯3A3000-7A1000PMON研究学习-(3)初步编译
  14. 从零搭建美团饿了么外卖红包CPS小程序教程
  15. osgEarth基础入门
  16. Stata:各类盈余管理指标估算方法
  17. 【mixly】APDS9960第三方库开发
  18. 乌班图好玩的命令_Ubuntu实用命令大全
  19. 2021年特种设备作业锅炉作业-工业锅炉司炉 (G1)考试题库
  20. [NOIP2020]微信步数

热门文章

  1. Java EE Eclipse安装Tomcat插件 “工具栏不显示三只小猫”
  2. 【源码】regtools:离散不适定问题的分析与求解
  3. 习题5.4 找出4*5矩阵中值最小和最大元素,并分别输出其值及所在的行号和列号。
  4. 如何在电脑上用Win11便签备忘录提醒重要工作
  5. 增加网站的档次!网页设计师可在网站中加入暗色调
  6. bitbucket 预览html,BitBucket基本使用操作
  7. 【问题解决】电脑微信聊天记录备份时显示不在同一网络(电脑LAN,手机WIFI)
  8. 手动删除文件夹exe病毒并恢复原来文件夹
  9. cer openssl 转pem_HTTPS证书转换成PEM格式
  10. python计算逆序的四位数_用C语言程序编写:输入一个四位整数(如1234),使其倒序输出(如4321),并求其各位之和。C语言 设计算法输入一个四位正...