tensorflow object detection api 安装完之后,你需要下载一下已有的整理好的代码:
Windows 10
raccoon_dataset
这些代码写好了必要的流程文件。当然还有很多,大同小异。
1、物体检测数据标注
一般都用下面这个软件. 该软件是用python+Qt编写的,最终的标注文件为XML文件,以PASCAL VOC格式进行存储。安装的时候一定要注意python版本和Qt版本的对应,建议通过anaconda创建一个Python2的虚拟环境来进行此软件的安装。
LabelImg is a graphical image annotation tool and label object bounding boxes in images
这里 有一些关于安装LabelImage的讨论,如果遇到问题可以参考。
标注之后的文件大概是如下格式:
<annotation>
<folder>save62</folder>
<filename>6_td_6_1_5.jpg.bmp</filename>
<path>C:\Users\Desktop\6\save62\6_td_6_1_5.jpg.bmp</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>160</width>
<height>120</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>coffee</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>144</xmin>
<ymin>50</ymin>
<xmax>159</xmax>
<ymax>91</ymax>
</bndbox>
</object>
</annotation>
还有另外一个软件FIAT,想尝试的可以去玩一下。
2、标注数据转化为Tfrecord格式
(1)将标注数据转换为CSV格式,使用xml_to_csv.py. 当然我给的这个链接里的代码需要你的文件路径设置为./Images/train 和test文件夹,这都没关系,路径写好就行。不过在读取xml的时候可能因为标注的时候发生错误而导致读取失败,所以在下面的代码外面加一下try except.
value = (root.find('filename').text,
int(root.find('size')[].text),
int(root.find('size')[].text),
member[].text,
int(member[][].text),
int(member[][].text),
int(member[][].text),
int(member[][].text)
)
xml_list.append(value)
(2)将csv和原始图数据一起,转化为tfrecord格式文件,使用generate_tfrecord.py
I)根据你自己的数据来修改下面的部分代码:
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'nine':
return
elif row_label == 'ten':
return
elif row_label == 'jack':
return
elif row_label == 'queen':
return
elif row_label == 'king':
return
elif row_label == 'ace':
return
else:
None
比如你的数据集只有一类物体,假设只有猫,那就改成下面的样子:
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'cat':
return
else:
None
II)在终端运行如下代码:
python generate_tfrecord.py --csv_input=images/train_labels.csv
--image_dir=images/train --output_path=train.record
其中 csv_input, image_dir,output_path 分别对应刚才产出的csv文件路径,原图的文件路径,及tfrecord的存储路径。
III) 一个坑点
def create_tf_example(group, path):
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
注意: 这里读取图片数据用的PIL的Image,这个读出来的图片的通道顺序是RGB,因此之后的所有训练数据输入的都是RGB顺序的图片数据。 为什么要提这一点? 因为模型训练完后,在真实图片上进行测试时,如果你用opencv的imread来读入测试图片,那基本就入坑了,完全检测的乱七八糟,这是因为imread读取的是BGR顺序的图片。这肯定是不行的。具体的更改可以如下:
frame = cv2.imread("图片地址")
b,g,r = cv2.split(frame) // 将b,g,r通道数据读出
frame = cv2.merge([r,g,b]) // 重新归序为 rgb
参考 Python之cv2.imread与PIL库中Image.open读入图像颜色顺序比较,
cv2.imread BGR模式,
OpenCV读取的图片从BGR转换为RGB
Opencv Imread 文档
IV) 什么是tfrecord?
tfrecord数据文件是一种将图像数据和标签统一存储的二进制文件,能更好的利用内存,在tensorflow中快速的复制,移动,读取,存储等。当然你也可以在训练模型的时候使用python来把数据喂给神经网络,那也是一种方式。可以参看下面的一些资料。
tensorflow读取数据-tfrecord格式
Tensorflow Records? What they are and how to use them
TFRecord-formatted files