环境首先要搭建好,没搭建好的童鞋请先搭建环境
在实现我们的目标之前那必须要准备我们的图片素材了,准备一些你想要检测的图片把他们整理到一个文件夹内。
百度上随便搜了一些车牌的图片放在文件夹内。
接下来我们去下载labelImg工具
下载完成后解压出来
data目录里有个predefined_classes文件,这里面就写着我们分类的的名称,我里面就一个类别。
XXXX(有就写没有就不写,每个分类一行),这只是工具的配置文件,不过最好不要用中文,转码这还是比较麻烦的。
接下来我们打开labelimage工具。
Open Dir-->选择我们资源图片所放的位置
快捷键W选择我们需要识别的物体位置
选择识别的物体类别点击ok
我们在我们图片资源目录下新建一个xml文件夹来存放我们的标注文件
在工具中选择我们标注文件所保存的位置
然后Ctrl+S就会将标注信息保存在xml文件里
我们接着工具点击 Next Image继续我们的标注工作
全部标注完成后我们开始编译xml文件将xml和图片转换为我们tf可识别的资源文件。
首先将我们xml文件转为csv文件
创建py文件代码如下(将xml转为csv文件):
import glob
import pandasas pd
import xml.etree.ElementTreeas ET
def xml_to_csv(path):
xml_list = []
# 读取注释文件
for xml_filein glob.glob(path +'/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for memberin 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:]
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)
if __name__ =='__main__':
path =r'E:\pyWork\ziyuan\License_plate\xml' # path参数更具自己xml文件所在的文件夹路径修改
xml_to_csv(path)
print('Successfully converted xml to csv.')
path所指我们xml文件所存放的目录。运行后会在次py文件下data目录下生成两个csv文件,一个训练一个测试
接下来我们将csv转为tfrecord文件,在这之前我们需要写一个labelitem文件
格式就是这样,要是自己解析能力强随你怎么变。
在创建一个py文件代码如下:
import os
import io
import pandas as pd
import tensorflow as tf
from PIL import Image
# from object_detection.utils import dataset_util
from object_detection.utils import dataset_util
from collections import namedtuple, OrderedDict
flags = 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 == 'computer':
return 1
elif row_label == '可自己添加自己的分类':
return 2
else:
print('NONE: ' + row_label)
def 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.size
filename = (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_example
def main(csv_input, output_path, imgPath):
writer = tf.python_io.TFRecordWriter(output_path)
path = imgPath
examples = 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 = r'E:\pyWork\ziyuan\quiz-w8-data\images'
# 生成train.record文件
output_path = 'data/train.record'
csv_input = 'data/train.csv'
main(csv_input, output_path, imgPath)
# 生成验证文件 eval.record
output_path = 'data/eval.record'
csv_input = 'data/eval.csv'
main(csv_input, output_path, imgPath)
运行后会生成record文件。
我们在object_detection/samples目录下将ssd_mobilenet_v1_coco.config复制一份到object_detection/legacy/training目录下,没有training目录的童鞋自己新建一个就好。
然后打开config文件里面凡是有PATH_TO_BE_CONFIGURED的字样都是我们需要指定的目录。
我的分类是1,num_classes:1
提一下这里
这里我们可以从官方下载预训练参数,如果不想用可以把这两端注释掉。
object_detection/legacy目录下有train.py这是官方已经写好的训练代码不需要任何修改,我们只需要传递参数开启训练就好
两个目录,一个是训练输出的目录,一个就是config文件所在位置,我直接吧地址设置成默认值,直接在pycharm里运行。你们也可以在cmd上运行。
在运行过程中会产生
训练步数的保存文件,我们可以用ckpt来测试当前训练是否满足需求