在上一篇博客"使用tensorflow object detection API 训练自己的目标检测模型 (二)"中介绍了如何使用LabelImg标记数据集,生成.xml文件,经过个人的手工标注,形成了一个大概有两千张图片的数据集。

但是这仍然不满足tensorflow object detection API对训练数据的格式要求(API要求tfrecord个格式的数据),所以下面将.xml文件转化为tfrecord格式的文件,

在models工程下新建文件夹dataset,目录结构如图所示:data文件夹用来存放转换的数据。

转换过程分为两步:

第一步:将标记生成xml文件转换为csv文件,在dataset下新建xml_to_csv.py文件,代码如下:

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ETdef xml_to_csv(path):xml_list = []# 读取注释文件for xml_file in glob.glob(path + '/*.xml'):tree = ET.parse(xml_file)root = tree.getroot()for member in root.findall('object'):value = (root.find('filename').text,int(root.find('size')[0].text),int(root.find('size')[1].text),member[0].text,int(member[4][0].text),int(member[4][1].text),int(member[4][2].text),int(member[4][3].text))xml_list.append(value)column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']# 将所有数据分为样本集和验证集,一般按照3:1的比例train_list = xml_list[0: int(len(xml_list) * 0.67)]eval_list = xml_list[int(len(xml_list) * 0.67) + 1: ]# 保存为CSV格式train_df = pd.DataFrame(train_list, columns=column_name)eval_df = pd.DataFrame(eval_list, columns=column_name)train_df.to_csv('data/train.csv', index=None)eval_df.to_csv('data/eval.csv', index=None)def main():# path = 'E:\\\data\\\Images'  path = r'E:\smart city\data_distribution\xml_new'  # path参数更具自己xml文件所在的文件夹路径修改xml_to_csv(path)print('Successfully converted xml to csv.')main()
  path = r'E:\smart city\data_distribution\xml_new'  # path参数更具自己xml文件所在的文件夹路径修改xml_to_csv(path)print('Successfully converted xml to csv.')main()

修改path路径, 运行代码,就可以进行转换:生成两个csv文件

第二步:将生成的csv文件转换为tfrecord格式

在dataset下新建generate_tfrecord.py文件,代码如下:

from __future__ import division
from __future__ import print_function
from __future__ import absolute_importimport os
import io
import pandas as pd
import tensorflow as tffrom PIL import Image
# from object_detection.utils import dataset_util
from research.object_detection.utils import dataset_util
from collections import namedtuple, OrderedDictflags = tf.app.flags
flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
FLAGS = flags.FLAGS# 将分类名称转成ID号
def class_text_to_int(row_label): if row_label == 'plate':return 1# elif row_label == 'car':#     return 2# elif row_label == 'person':#     return 3# elif row_label == 'kite':#     return 4else:print('NONE: ' + row_label)# Nonedef split(df, group):data = namedtuple('data', ['filename', 'object'])gb = df.groupby(group)return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]def create_tf_example(group, path):print(os.path.join(path, '{}'.format(group.filename)))with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:encoded_jpg = fid.read()encoded_jpg_io = io.BytesIO(encoded_jpg)image = Image.open(encoded_jpg_io)width, height = image.sizefilename = (group.filename + '.jpg').encode('utf8')image_format = b'jpg'xmins = []xmaxs = []ymins = []ymaxs = []classes_text = []classes = []for index, row in group.object.iterrows():xmins.append(row['xmin'] / width)xmaxs.append(row['xmax'] / width)ymins.append(row['ymin'] / height)ymaxs.append(row['ymax'] / height)classes_text.append(row['class'].encode('utf8'))classes.append(class_text_to_int(row['class']))tf_example = tf.train.Example(features=tf.train.Features(feature={'image/height': dataset_util.int64_feature(height),'image/width': dataset_util.int64_feature(width),'image/filename': dataset_util.bytes_feature(filename),'image/source_id': dataset_util.bytes_feature(filename),'image/encoded': dataset_util.bytes_feature(encoded_jpg),'image/format': dataset_util.bytes_feature(image_format),'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),'image/object/class/text': dataset_util.bytes_list_feature(classes_text),'image/object/class/label': dataset_util.int64_list_feature(classes),}))return tf_exampledef main(csv_input, output_path, imgPath):writer = tf.python_io.TFRecordWriter(output_path)path = imgPathexamples = pd.read_csv(csv_input)grouped = split(examples, 'filename')for group in grouped:tf_example = create_tf_example(group, path)writer.write(tf_example.SerializeToString())writer.close()print('Successfully created the TFRecords: {}'.format(output_path))if __name__ == '__main__':# imgPath = 'E:\data\Images' imgPath = r'E:\smart city\data_distribution\picyure_new'# 生成train.record文件output_path = 'data/train.record'csv_input = 'data/train.csv'main(csv_input, output_path, imgPath)# 生成验证文件 eval.recordoutput_path = 'data/eval.record'csv_input = 'data/eval.csv'main(csv_input, output_path, imgPath) if row_label == 'plate':return 1# elif row_label == 'car':#     return 2# elif row_label == 'person':#     return 3# elif row_label == 'kite':#     return 4else:print('NONE: ' + row_label)# Nonedef split(df, group):data = namedtuple('data', ['filename', 'object'])gb = df.groupby(group)return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]def create_tf_example(group, path):print(os.path.join(path, '{}'.format(group.filename)))with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:encoded_jpg = fid.read()encoded_jpg_io = io.BytesIO(encoded_jpg)image = Image.open(encoded_jpg_io)width, height = image.sizefilename = (group.filename + '.jpg').encode('utf8')image_format = b'jpg'xmins = []xmaxs = []ymins = []ymaxs = []classes_text = []classes = []for index, row in group.object.iterrows():xmins.append(row['xmin'] / width)xmaxs.append(row['xmax'] / width)ymins.append(row['ymin'] / height)ymaxs.append(row['ymax'] / height)classes_text.append(row['class'].encode('utf8'))classes.append(class_text_to_int(row['class']))tf_example = tf.train.Example(features=tf.train.Features(feature={'image/height': dataset_util.int64_feature(height),'image/width': dataset_util.int64_feature(width),'image/filename': dataset_util.bytes_feature(filename),'image/source_id': dataset_util.bytes_feature(filename),'image/encoded': dataset_util.bytes_feature(encoded_jpg),'image/format': dataset_util.bytes_feature(image_format),'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),'image/object/class/text': dataset_util.bytes_list_feature(classes_text),'image/object/class/label': dataset_util.int64_list_feature(classes),}))return tf_exampledef main(csv_input, output_path, imgPath):writer = tf.python_io.TFRecordWriter(output_path)path = imgPathexamples = pd.read_csv(csv_input)grouped = split(examples, 'filename')for group in grouped:tf_example = create_tf_example(group, path)writer.write(tf_example.SerializeToString())writer.close()print('Successfully created the TFRecords: {}'.format(output_path))if __name__ == '__main__':# imgPath = 'E:\data\Images' imgPath = r'E:\smart city\data_distribution\picyure_new'# 生成train.record文件output_path = 'data/train.record'csv_input = 'data/train.csv'main(csv_input, output_path, imgPath)# 生成验证文件 eval.recordoutput_path = 'data/eval.record'csv_input = 'data/eval.csv'main(csv_input, output_path, imgPath)

这里有两处需要修改:

第一处:

分类号转换为ID:

# 将分类名称转成ID号
def class_text_to_int(row_label):if row_label == 'plate':return 1# elif row_label == 'car':#     return 2# elif row_label == 'person':#     return 3# elif row_label == 'kite':#     return 4else:print('NONE: ' + row_label)# None

根据自己在LabelImg中打的标签进行修改, 比如我只有plate标签:

第二处:

# imgPath = 'E:\data\Images'
imgPath = r'E:\smart city\data_distribution\picyure_new'

对图片的路径进行修改, 图片应该要与xml文件一一对应的:

运行generate_tfrecord.py文件,可以看到已经生成了两个tfrecord文件:

现在数据转化完毕,开始训练模型之前。要对API做一些配置:

(1)在data文件夹下创建label_map.pbtxtx文件:

文件内容如下:

item {id: 1name: 'plate'
}
item {id: 2name: 'xxx'
}
item {id: 3name: 'xxx'
}

文件中id 和 name应该和上面修改的函数class_text_to_int()中的相对应:如果有多个检测目标,就继续添加item(我的只有plate一项,后面添加的两个item作为示例,实际运行时会删掉),记得保存pbtxt文件()

(2)下载 需要fine-tune的模型:下载的地址为:https://github.com/tensorflow/models/tree/master/research/slim

根据需要下载具体的模型,在dataset文件夹下新建fine_tune_model文件夹,将下载的模型解压后,复制三个.ckpt文件放到fine_tune_model文件夹下。

(3)配置管道文件

找到目录research\object_detection\samples\configs\ssd_inception_v2_pets.config文件,将此文件复制到dataset/data文件夹下:

并对以下的地方做出修改:

第一处:第8-9行ssd {num_classes: 1      # 贼修改为自己检测的目标的类别数, 例如我的是一个   box_coder {
第二处:151-152行
# 贼修改为自己检测的目标的类别数, 例如我的是一个   box_coder {
第二处:151-152行
 
fine_tune_checkpoint: "E:/code/112/models/dataset/fine_tune_model/model.ckpt"   # 注意修改fine_tune_checkpoint
fine_tune_checkpoint_type:  "detection"
第三处:169-175行
train_input_reader: {tf_record_input_reader {# input_path: "PATH_TO_BE_CONFIGURED/pet_train.record"input_path: "E:/code/112/models/dataset/data/train.record"   # 将 input_path参数改为前面生成train.record文件的路径}label_map_path: "E:/code/112/models/dataset/data/label_map.pbtxt"  # 同理将这里的路径改为上面生成的label_map.pbtxt文件的路径
}
  # 将 input_path参数改为前面生成train.record文件的路径}label_map_path: "E:/code/112/models/dataset/data/label_map.pbtxt"  # 同理将这里的路径改为上面生成的label_map.pbtxt文件的路径
}
第四处:184-191
eval_input_reader: {tf_record_input_reader {input_path: "E:/code/112/models/dataset/data/eval.record"       # 将 input_path参数改为前面生成eval.record文件的路径}label_map_path: "E:/code/112/models/dataset/data/label_map.pbtxt"    # 同理将这里的路径改为上面生成的label_map.pbtxt文件的路径shuffle: falsenum_readers: 1
}# 将 input_path参数改为前面生成eval.record文件的路径}label_map_path: "E:/code/112/models/dataset/data/label_map.pbtxt"    # 同理将这里的路径改为上面生成的label_map.pbtxt文件的路径shuffle: falsenum_readers: 1
}

(4).配置完管道文件后,再到models\research\object_detection\train.py文件,如果遇到train.py文件找不到导入的包,(比如报错 no module named object_detection)

按如下方式修改

# from object_detection import trainer
from research.object_detection import trainer
# from object_detection.builders import dataset_builder
from research.object_detection.builders import dataset_builder
# from object_detection.builders import graph_rewriter_builder
from research.object_detection.builders import graph_rewriter_builder
# from object_detection.builders import model_builder
from research.object_detection.builders import model_builder
# from object_detection.utils import config_util
from research.object_detection.utils import config_util
# from object_detection.utils import dataset_util
from research.object_detection.utils import dataset_util

导入他们的完整路径就不会报错了, 对应的models\research\object_detection\trainer.py也要修改:

# from object_detection.builders import optimizer_builder
from research.object_detection.builders import optimizer_builder
# from object_detection.builders import preprocessor_builder
from research.object_detection.builders import preprocessor_builder
# from object_detection.core import batcher
from research.object_detection.core import batcher
# from object_detection.core import preprocessor
from research.object_detection.core import preprocessor
# from object_detection.core import standard_fields as fields
from research.object_detection.core import standard_fields as fields
# from object_detection.utils import ops as util_ops
from research.object_detection.utils import ops as util_ops
# from object_detection.utils import variables_helper
from research.object_detection.utils import variables_helper
# from deployment import model_deploy
from research.slim.deployment import model_deploy

除此之外,运行train.py文件时,还会有大量的no module named object_detection错误,我是一一手动修改导入完整路径,这种方法很不好, 可以通过sys.path.append('上层目录路径')引入上一层的目录:

同时还有找不到no module named net之类的错误, net文件在research/object_detection/slim文件夹下,导入完整的路径就可以解决。

到models\research\object_detection\train.py文件下,在文件中做一些修改:

 
flags.DEFINE_string('train_dir', r'E:\code\112\models\dataset\training',               # 指定模型的输出路径'Directory to save the checkpoints and training summaries.')flags.DEFINE_string('pipeline_config_path', r'E:\code\112\models\dataset\data\ssd_mobilenet_v2_coco_self.config',    # 配置文件路径'Path to a pipeline_pb2.TrainEvalPipelineConfig config ''file. If provided, other configs are ignored')

运行train.py文件就可以开始训练了。。。。

训练结果:

运行代码后发现出现异常:报错的信息为:

INFO:tensorflow:Error reported to Coordinator: <class 'tensorflow.python.framework.errors_impl.ResourceExhaustedError'>, OOM when allocating tensor with shape[1200,1600,3] and type float on /job:localhost/replica:0/task:0/device:CPU:0 by allocator cpu
     [[Node: RandomHorizontalFlip/cond/flip_left_right/ReverseV2 = ReverseV2[T=DT_FLOAT, Tidx=DT_INT32, _device="/job:localhost/replica:0/task:0/device:CPU:0"](RandomHorizontalFlip/cond/Switch_1:1, RandomHorizontalFlip/cond/flip_left_right/ReverseV2/axis, ^RandomHorizontalFlip/cond/flip_left_right/assert_positive/assert_less/Assert/Assert)]]

Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

经过查找,错误的原因应该是显卡内存溢出,我的笔记本跑不了这个模型。

借用了一台1070 16G显卡的游戏本跑一波:

生成的training文件下的模型文件:

(4)导出训练的结果,生成pb文件:

将export_inference_graph.py文件复制到dataset文件夹下,文件的具体内容为:

 
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================r"""Tool to export an object detection model for inference.Prepares an object detection tensorflow graph for inference using model
configuration and an optional trained checkpoint. Outputs inference
graph, associated checkpoint files, a frozen inference graph and a
SavedModel (https://tensorflow.github.io/serving/serving_basic.html).The inference graph contains one of three input nodes depending on the user
specified option.* `image_tensor`: Accepts a uint8 4-D tensor of shape [None, None, None, 3]* `encoded_image_string_tensor`: Accepts a 1-D string tensor of shape [None]containing encoded PNG or JPEG images. Image resolutions are expected to bethe same if more than 1 image is provided.* `tf_example`: Accepts a 1-D string tensor of shape [None] containingserialized TFExample protos. Image resolutions are expected to be the sameif more than 1 image is provided.and the following output nodes returned by the model.postprocess(..):* `num_detections`: Outputs float32 tensors of the form [batch]that specifies the number of valid boxes per image in the batch.* `detection_boxes`: Outputs float32 tensors of the form[batch, num_boxes, 4] containing detected boxes.* `detection_scores`: Outputs float32 tensors of the form[batch, num_boxes] containing class scores for the detections.* `detection_classes`: Outputs float32 tensors of the form[batch, num_boxes] containing classes for the detections.* `detection_masks`: Outputs float32 tensors of the form[batch, num_boxes, mask_height, mask_width] containing predicted instancemasks for each box if its present in the dictionary of postprocessedtensors returned by the model.Notes:* This tool uses `use_moving_averages` from eval_config to decide whichweights to freeze.Example Usage:
--------------
python export_inference_graph \--input_type image_tensor \--pipeline_config_path path/to/ssd_inception_v2.config \--trained_checkpoint_prefix path/to/model.ckpt \--output_directory path/to/exported_model_directoryThe expected output would be in the directory
path/to/exported_model_directory (which is created if it does not exist)
with contents:- graph.pbtxt- model.ckpt.data-00000-of-00001- model.ckpt.info- model.ckpt.meta- frozen_inference_graph.pb+ saved_model (a directory)Config overrides (see the `config_override` flag) are text protobufs
(also of type pipeline_pb2.TrainEvalPipelineConfig) which are used to override
certain fields in the provided pipeline_config_path.  These are useful for
making small changes to the inference graph that differ from the training or
eval config.Example Usage (in which we change the second stage post-processing score
threshold to be 0.5):python export_inference_graph \--input_type image_tensor \--pipeline_config_path path/to/ssd_inception_v2.config \--trained_checkpoint_prefix path/to/model.ckpt \--output_directory path/to/exported_model_directory \--config_override " \model{ \faster_rcnn { \second_stage_post_processing { \batch_non_max_suppression { \score_threshold: 0.5 \} \} \} \}"
"""
import tensorflow as tf
from google.protobuf import text_format
from research.object_detection import exporter
from research.object_detection.protos import pipeline_pb2slim = tf.contrib.slim
flags = tf.app.flagsflags.DEFINE_string('input_type', 'image_tensor', 'Type of input node. Can be ''one of [`image_tensor`, `encoded_image_string_tensor`, ''`tf_example`]')
flags.DEFINE_string('input_shape', None,'If input_type is `image_tensor`, this can explicitly set ''the shape of this input tensor to a fixed size. The ''dimensions are to be provided as a comma-separated list ''of integers. A value of -1 can be used for unknown ''dimensions. If not specified, for an `image_tensor, the ''default shape will be partially specified as ''`[None, None, None, 3]`.')
flags.DEFINE_string('pipeline_config_path', r'E:\code\112\models\dataset\data\ssd_mobilenet_v2_coco_self.config','Path to a pipeline_pb2.TrainEvalPipelineConfig config ''file.')
flags.DEFINE_string('trained_checkpoint_prefix', r'E:\code\112\models\dataset\training\model.ckpt-1500','Path to trained checkpoint, typically of the form ''path/to/model.ckpt')
flags.DEFINE_string('output_directory', r'E:\code\112\models\dataset\data\frozen_inference_graph.pb', 'Path to write outputs.')
flags.DEFINE_string('config_override', '','pipeline_pb2.TrainEvalPipelineConfig ''text proto to override pipeline_config_path.')
tf.app.flags.mark_flag_as_required('pipeline_config_path')
tf.app.flags.mark_flag_as_required('trained_checkpoint_prefix')
tf.app.flags.mark_flag_as_required('output_directory')
FLAGS = flags.FLAGSdef main(_):pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()with tf.gfile.GFile(FLAGS.pipeline_config_path, 'r') as f:text_format.Merge(f.read(), pipeline_config)text_format.Merge(FLAGS.config_override, pipeline_config)if FLAGS.input_shape:input_shape = [int(dim) if dim != '-1' else Nonefor dim in FLAGS.input_shape.split(',')]else:input_shape = Noneexporter.export_inference_graph(FLAGS.input_type, pipeline_config,FLAGS.trained_checkpoint_prefix,FLAGS.output_directory, input_shape)if __name__ == '__main__':tf.app.run()
flags.DEFINE_string('input_type', 'image_tensor', 'Type of input node. Can be ''one of [`image_tensor`, `encoded_image_string_tensor`, ''`tf_example`]')
flags.DEFINE_string('input_shape', None,'If input_type is `image_tensor`, this can explicitly set ''the shape of this input tensor to a fixed size. The ''dimensions are to be provided as a comma-separated list ''of integers. A value of -1 can be used for unknown ''dimensions. If not specified, for an `image_tensor, the ''default shape will be partially specified as ''`[None, None, None, 3]`.')
flags.DEFINE_string('pipeline_config_path', r'E:\code\112\models\dataset\data\ssd_mobilenet_v2_coco_self.config','Path to a pipeline_pb2.TrainEvalPipelineConfig config ''file.')
flags.DEFINE_string('trained_checkpoint_prefix', r'E:\code\112\models\dataset\training\model.ckpt-1500','Path to trained checkpoint, typically of the form ''path/to/model.ckpt')
flags.DEFINE_string('output_directory', r'E:\code\112\models\dataset\data\frozen_inference_graph.pb', 'Path to write outputs.')
flags.DEFINE_string('config_override', '','pipeline_pb2.TrainEvalPipelineConfig ''text proto to override pipeline_config_path.')
tf.app.flags.mark_flag_as_required('pipeline_config_path')
tf.app.flags.mark_flag_as_required('trained_checkpoint_prefix')
tf.app.flags.mark_flag_as_required('output_directory')
FLAGS = flags.FLAGSdef main(_):pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()with tf.gfile.GFile(FLAGS.pipeline_config_path, 'r') as f:text_format.Merge(f.read(), pipeline_config)text_format.Merge(FLAGS.config_override, pipeline_config)if FLAGS.input_shape:input_shape = [int(dim) if dim != '-1' else Nonefor dim in FLAGS.input_shape.split(',')]else:input_shape = Noneexporter.export_inference_graph(FLAGS.input_type, pipeline_config,FLAGS.trained_checkpoint_prefix,FLAGS.output_directory, input_shape)if __name__ == '__main__':tf.app.run()

需要对以下标记为红色的地方做一些修改:

input_ypye :    image_tensor

flags.DEFINE_string('input_type', 'image_tensor', 'Type of input node. Can be ''one of [`image_tensor`, `encoded_image_string_tensor`, ''`tf_example`]')'input_type', 'image_tensor', 'Type of input node. Can be ''one of [`image_tensor`, `encoded_image_string_tensor`, ''`tf_example`]')

pipeline_config_path:   models\dataset\data\ssd_inception_v2_pets.config     # 上面配置的管道文件的路径

flags.DEFINE_string('pipeline_config_path', r'E:\code\112\models\dataset\data\ssd_inception_v2_pets.config','Path to a pipeline_pb2.TrainEvalPipelineConfig config ''file.')'pipeline_config_path', r'E:\code\112\models\dataset\data\ssd_inception_v2_pets.config','Path to a pipeline_pb2.TrainEvalPipelineConfig config ''file.')

trained_checkpoint_prefix: training 文件夹中生成的模型文件。

flags.DEFINE_string('trained_checkpoint_prefix', r'E:\code\112\models\dataset\training\model.ckpt-1500','Path to trained checkpoint, typically of the form ''path/to/model.ckpt')trained_checkpoint_prefix', r'E:\code\112\models\dataset\training\model.ckpt-1500','Path to trained checkpoint, typically of the form ''path/to/model.ckpt')

output_directory:  生成pb文件的存放路径

 
flags.DEFINE_string('output_directory', r'E:\code\112\models\dataset\data\frozen_inference_graph.pb', 'Path to write outputs.')y', r'E:\code\112\models\dataset\data\frozen_inference_graph.pb', 'Path to write outputs.')

接下来运行export_inference_graph.py文件:

最后可以训练的模型进行测试了:

将上一片中配置完object detection API 的测试文件object_detection_tutorial.py复制到dataset文件夹下,并在dataset文件夹新建tesi_image文件夹, 用于存放测试图片,并且对object_detection_tutorial.py文件完整代码:

import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfilefrom collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image# # This is needed to display the images.
# %matplotlib inline# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")# from utils import label_map_util
# from utils import visualization_utils as vis_util
from research.object_detection.utils import label_map_util
from research.object_detection.utils import visualization_utils as vis_util# What model to download.
# MODEL_NAME = 'ssd_mobilenet_v1_coco_11_06_2017'     # 这部分为下载模型的,现在我们不用再下载模型了,所以注释掉
# MODEL_FILE = MODEL_NAME + '.tar.gz'
# DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = r'E:\code\112\models\dataset\data\frozen_inference_graph.pb\frozen_inference_graph.pb'   #上一步生成的.pb文件的路径# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = r'E:\code\112\models\dataset\data\label_map.pbtxt'            #添加pbtxt文件的路径NUM_CLASSES = 1      #我的类别数为1, 这里根据自己的类别数修改# download model                 # 这部分也是下载模型的,注释掉即可
# opener = urllib.request.URLopener()
# 下载模型,如果已经下载好了下面这句代码可以注释掉
# opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
# tar_file = tarfile.open(MODEL_FILE)
# for file in tar_file.getmembers():
#     file_name = os.path.basename(file.name)
#     if 'frozen_inference_graph.pb' in file_name:
#         tar_file.extract(file, os.getcwd())# Load a (frozen) Tensorflow model into memory.
detection_graph = tf.Graph()
with detection_graph.as_default():od_graph_def = tf.GraphDef()with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:serialized_graph = fid.read()od_graph_def.ParseFromString(serialized_graph)tf.import_graph_def(od_graph_def, name='')
# Loading label map
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES,use_display_name=True)
category_index = label_map_util.create_category_index(categories)# Helper code
def load_image_into_numpy_array(image):(im_width, im_height) = image.sizereturn np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)# For the sake of simplicity we will use only 2 images:   # 这里说明测试图片的命名规则为imagen.jpg, 遵守规则即可
# image1.jpg
# image2.jpg# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = r'E:\code\112\models\dataset\tesi_images'    # 存放测试图片的路径
TEST_IMAGE_PATHS = [os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 22)]  # 修改测试图片的张数range(1, n + 1), 为测试图片的张数# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)with detection_graph.as_default():with tf.Session(graph=detection_graph) as sess:# Definite input and output Tensors for detection_graphimage_tensor = detection_graph.get_tensor_by_name('image_tensor:0')# Each box represents a part of the image where a particular object was detected.detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')# Each score represent how level of confidence for each of the objects.# Score is shown on the result image, together with the class label.detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')num_detections = detection_graph.get_tensor_by_name('num_detections:0')for image_path in TEST_IMAGE_PATHS:image = Image.open(image_path)# the array based representation of the image will be used later in order to prepare the# result image with boxes and labels on it.image_np = load_image_into_numpy_array(image)# Expand dimensions since the model expects images to have shape: [1, None, None, 3]image_np_expanded = np.expand_dims(image_np, axis=0)image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')# Each box represents a part of the image where a particular object was detected.boxes = detection_graph.get_tensor_by_name('detection_boxes:0')# Each score represent how level of confidence for each of the objects.# Score is shown on the result image, together with the class label.scores = detection_graph.get_tensor_by_name('detection_scores:0')classes = detection_graph.get_tensor_by_name('detection_classes:0')num_detections = detection_graph.get_tensor_by_name('num_detections:0')# Actual detection.(boxes, scores, classes, num_detections) = sess.run([boxes, scores, classes, num_detections],feed_dict={image_tensor: image_np_expanded})# Visualization of the results of a detection.vis_util.visualize_boxes_and_labels_on_image_array(image_np,np.squeeze(boxes),np.squeeze(classes).astype(np.int32),np.squeeze(scores),category_index,use_normalized_coordinates=True,line_thickness=8)plt.figure(figsize=IMAGE_SIZE)plt.imshow(image_np)plt.show()
# MODEL_NAME = 'ssd_mobilenet_v1_coco_11_06_2017'     # 这部分为下载模型的,现在我们不用再下载模型了,所以注释掉
# MODEL_FILE = MODEL_NAME + '.tar.gz'
# DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = r'E:\code\112\models\dataset\data\frozen_inference_graph.pb\frozen_inference_graph.pb'   #上一步生成的.pb文件的路径# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = r'E:\code\112\models\dataset\data\label_map.pbtxt'            #添加pbtxt文件的路径NUM_CLASSES = 1      #我的类别数为1, 这里根据自己的类别数修改# download model                 # 这部分也是下载模型的,注释掉即可
# opener = urllib.request.URLopener()
# 下载模型,如果已经下载好了下面这句代码可以注释掉
# opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
# tar_file = tarfile.open(MODEL_FILE)
# for file in tar_file.getmembers():
#     file_name = os.path.basename(file.name)
#     if 'frozen_inference_graph.pb' in file_name:
#         tar_file.extract(file, os.getcwd())# Load a (frozen) Tensorflow model into memory.
detection_graph = tf.Graph()
with detection_graph.as_default():od_graph_def = tf.GraphDef()with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:serialized_graph = fid.read()od_graph_def.ParseFromString(serialized_graph)tf.import_graph_def(od_graph_def, name='')
# Loading label map
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES,use_display_name=True)
category_index = label_map_util.create_category_index(categories)# Helper code
def load_image_into_numpy_array(image):(im_width, im_height) = image.sizereturn np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)# For the sake of simplicity we will use only 2 images:   # 这里说明测试图片的命名规则为imagen.jpg, 遵守规则即可
# image1.jpg
# image2.jpg# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = r'E:\code\112\models\dataset\tesi_images'    # 存放测试图片的路径
TEST_IMAGE_PATHS = [os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 22)]  # 修改测试图片的张数range(1, n + 1), 为测试图片的张数# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)with detection_graph.as_default():with tf.Session(graph=detection_graph) as sess:# Definite input and output Tensors for detection_graphimage_tensor = detection_graph.get_tensor_by_name('image_tensor:0')# Each box represents a part of the image where a particular object was detected.detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')# Each score represent how level of confidence for each of the objects.# Score is shown on the result image, together with the class label.detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')num_detections = detection_graph.get_tensor_by_name('num_detections:0')for image_path in TEST_IMAGE_PATHS:image = Image.open(image_path)# the array based representation of the image will be used later in order to prepare the# result image with boxes and labels on it.image_np = load_image_into_numpy_array(image)# Expand dimensions since the model expects images to have shape: [1, None, None, 3]image_np_expanded = np.expand_dims(image_np, axis=0)image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')# Each box represents a part of the image where a particular object was detected.boxes = detection_graph.get_tensor_by_name('detection_boxes:0')# Each score represent how level of confidence for each of the objects.# Score is shown on the result image, together with the class label.scores = detection_graph.get_tensor_by_name('detection_scores:0')classes = detection_graph.get_tensor_by_name('detection_classes:0')num_detections = detection_graph.get_tensor_by_name('num_detections:0')# Actual detection.(boxes, scores, classes, num_detections) = sess.run([boxes, scores, classes, num_detections],feed_dict={image_tensor: image_np_expanded})# Visualization of the results of a detection.vis_util.visualize_boxes_and_labels_on_image_array(image_np,np.squeeze(boxes),np.squeeze(classes).astype(np.int32),np.squeeze(scores),category_index,use_normalized_coordinates=True,line_thickness=8)plt.figure(figsize=IMAGE_SIZE)plt.imshow(image_np)plt.show()

对以上标记为红色代码的部分进行修改即可:运行object_detection_tutorial.py文件,我的测试结果:(贴几张图)

效果还是可以的,关于使用tensorflow object detection API 训练自己的目标检测模型 先介绍到这里

附上完整的项目目录:

-------------------------------------------------------更新2018-12-14-------------------------------------------------------------

最近把之前的东西整理了一下,把完整的代码分享出来

关于使用tensorflow object detection API训练自己的模型-补充部分(代码,数据标注工具,训练数据,测试数据)

使用tensorflow object detection API 训练自己的目标检测模型 (三)相关推荐

  1. 使用tensorflow object detection API 训练自己的目标检测模型 (二)labelImg的安装配置过程

    上一篇博客介绍了goggle的tensorflow object detection API 的配置和使用, 这次介绍一下如何用这个API训练一个私人定制的目标检测模型. 第一步:准备自己的数据集.比 ...

  2. Tensorflow object detection API训练自己的目标检测模型 详细配置教程 (一)

    Tensorflow object detection API 简单介绍Tensorflow object detection API: 这个API是基于tensorflow构造的开源框架,易于构建. ...

  3. Tensorflow object detection API 搭建自己的目标检测模型并迁移到Android上

    参考链接:https://blog.csdn.net/dy_guox/article/details/79111949 之前参考上述一系列博客在Windows10下面成功运行了TensorFlow A ...

  4. 关于使用tensorflow object detection API训练自己的模型-补充部分(代码,数据标注工具,训练数据,测试数据)

    之前分享过关于tensorflow object detection API训练自己的模型的几篇博客,后面有人陆续碰到一些问题,问到了我解决方法.所以在这里补充点大家可能用到的东西.声明一下,本人专业 ...

  5. tensorflow object detection API训练错误解决

    问题描述 tensorflow object detection API训练coco数据集时提示错误:Windows fatal exception: access violation,如下图: Th ...

  6. 基于TensorFlow Object Detection API训练自己的目标识别模型

    基于TensorFlow Object Detection API训练自己的目标识别模型 环境 Windows10 CUDA_9 Cudnn_9.0 Anaconda3-5.2.0 Tensorflo ...

  7. tensorflow object detection API训练公开数据集Oxford-IIIT Pets Dataset

    为了避免不必要的麻烦,先说一下我的系统版本 Python 3.6 tensorflow 1.10 windows 7 object detection API安装 object detection A ...

  8. 使用tensorflow object detection api训练自己的数据集

    简介 使用tensorflow object detection训练自己的数据集时,可能会出现 AttributeError: module 'tensorflow.contrib.data' has ...

  9. 如何用TF Object Detection API训练交通信号灯检测神经网络?

    参加 2019 Python开发者日,请扫码咨询 ↑↑↑ 作者简介:申泽邦(Adam Shan),谷歌认证机器学习专家(Google Developer Expert),兰州大学智能驾驶团队技术负责人 ...

最新文章

  1. 【网络编程】同步IO、异步IO、阻塞IO、非阻塞IO
  2. AlphaGo的原理
  3. vs studio 2017/2015 连接mysql报错 You have a usable connection already.
  4. DCT算法的原理及实现简介
  5. 务实云计算培训:帮您顺利走好云之旅
  6. 深耕边缘计算 揭秘阿里云边缘云网一体化的技术实践
  7. 一秒创建高级查询服务
  8. Mysql主主同步详细操作过程
  9. mysql一:初识数据库
  10. zip在python中的用法_Python中zip()函数用法实例教程
  11. python笔试和面试题汇总(免费下载)
  12. css图片悬停特效,使用CSS3实现图片悬停放大的特效
  13. 优秀后端架构师必会知识:史上最全MySQL大表优化方案总结...
  14. 洛谷 P2873 [USACO07DEC]泥水坑Mud Puddles
  15. 1077E Thematic Contests 【二分答案】
  16. 《遥远的救世主》(摘录)
  17. Real-Time-Voice-Cloning(github声音克隆项目演示)
  18. python数据可视化之Matplotlib
  19. 剑指Offer(JS版)
  20. DolphiScheduler平台上运行spark程序时,外部参数设置

热门文章

  1. Linux工作笔记032---Centos7.3/8.2 下安装mysql_不局限于MySql版本
  2. 正则表达式学习笔记006--转义符的认识与应用
  3. 水表模型更新--170323
  4. 《算法导论》之 Problem 5.1-3(随机函数发生器的设计)
  5. mac模式怎样构造在jsp中_mac下tomcat的配置和jdk的设置 jsp的初级知识
  6. 腾讯云 mysql 密码_腾讯云mysql重新设置密码解决办法
  7. 响应服务器535 5.7.1 unab,带有Gmail的JavaMail:535-5.7.1不接受用户名和密码
  8. 4个独立按键实现对数码管数字显示的加减清零等
  9. pythonguitkinter编程入门_Python Tkinter GUI编程入门介绍
  10. python程序扩展名主要有-python文件的后缀名都有哪些?