forked from shaoshengsong/MobileNetV3-SSD-Compact-Version
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_data.py
179 lines (167 loc) · 5.86 KB
/
create_data.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
from pycocotools.coco import COCO
import os
from tqdm import tqdm
# import skimage.io as io
# import matplotlib.pyplot as plt
import cv2
from PIL import Image, ImageDraw, ImageFile
import PIL
import shutil
headstr = """\
<annotation>
<folder>VOC</folder>
<filename>%s</filename>
<source>
<database>My Database</database>
<annotation>COCO</annotation>
<image>flickr</image>
<flickrid>NULL</flickrid>
</source>
<owner>
<flickrid>NULL</flickrid>
<name>company</name>
</owner>
<size>
<width>%d</width>
<height>%d</height>
<depth>%d</depth>
</size>
<segmented>0</segmented>
"""
bboxstr = """\
<object>
<name>%s</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>%d</xmin>
<ymin>%d</ymin>
<xmax>%d</xmax>
<ymax>%d</ymax>
</bndbox>
</object>
"""
tailstr = '''\
</annotation>
'''
def mkr(path):
if not os.path.exists(path):
print("creating path %s" % path)
os.makedirs(path) # 可以创建多级目录
def id2name(coco):
"""
通过标签的id得到标签的name,因为写xml时需要标签的name,但是annnotation里只有标签的id
"""
classes = dict()
for cls in coco.dataset['categories']:
classes[cls['id']] = cls['name']
return classes
def geAllImagesId(coco):
"""
得到传入数据集里所有图片的id,1.得到标签的种类;2.通过遍历图片种含有该标签来得到图片id
:param coco: 传入数据集
:return all_img_ids: list 所有图片的id
"""
all_class_ids = [] # 所有class的id,这里有90种
for ls in coco.dataset['categories']:
all_class_ids.append(int(ls['id']))
print("All class ids:")
print(all_class_ids)
all_img_ids = []
for cls_id in all_class_ids:
img_ids = coco.getImgIds(catIds=cls_id) # 含有这个标签的所有图片
for img_id in tqdm(img_ids):
if img_id not in all_img_ids: # 防止出现重复的id
all_img_ids.append(img_id)
print("All img ids got, total: %d" % len(all_img_ids))
return all_img_ids
def parseAnnotations(anns, filename):
"""
把coco的ann解析成一个list bboxes,里边存放的是这个图片里的所有bbox信息
"""
bboxes=[]
for ann in anns: # 遍历这个图片的所有标注
class_name = classes[ann['category_id']] # 从id得到这个标注的名字,
if 'bbox' in ann: # 如果标注信息里有bbox
bbox = ann['bbox']
xmin = int(bbox[0])
ymin = int(bbox[1])
xmax = int(bbox[2] + bbox[0])
ymax = int(bbox[3] + bbox[1])
if (ymax==ymin) or (xmax==xmin):
print("bad annotation!!!!!!!! w or h is zero!")
print(filename)
return
bbox = [class_name, xmin, ymin, xmax, ymax]# 一个目标的信息
bboxes.append(bbox)# 这个图片里所有目标的信息
return bboxes
def saveXmlAndImg(coco_dataset_dir, savepath, dataset, filename, bboxes):
# 将图片转为xml,例:COCO_train2017_000000196610.jpg-->COCO_train2017_000000196610.xml
# anno
dst_anno_dir = os.path.join(savepath, dataset, 'Annotations')
mkr(dst_anno_dir)
anno_path = dst_anno_dir + '/' + filename[:-3] + 'xml'
# img
img_path = coco_dataset_dir + dataset + '/' + filename # 从这里读取图片
dst_img_dir = os.path.join(savepath, dataset, 'JPEGImages')
mkr(dst_img_dir)
dst_imgpath = dst_img_dir + '/' + filename
img = cv2.imread(img_path)
shutil.copy(img_path, dst_imgpath)
# txt
dst_txt_dir = os.path.join(savepath, dataset)
mkr(dst_txt_dir)
dst_txt_path = dst_txt_dir + '/image_idx.txt'
# write xml
global headstr
global tailstr
global bboxstr
head = headstr % (filename, img.shape[1], img.shape[0], img.shape[2])
tail = tailstr
f = open(anno_path, "w")
f.write(head)
for bbox in bboxes:
f.write(bboxstr % (bbox[0], bbox[1], bbox[2], bbox[3], bbox[4]))
f.write(tail)
# write txt
f = open(dst_txt_path, "a")
f.write(filename[:-4]+'\n')
f.close()
if __name__ == '__main__':
"""
把输入的coco数据集转换成 xml 和 jpg 和所有filename的txt
"""
home_path = os.environ['HOME']
coco_dataset_dir = home_path + '/coco_dataset/' # 存放coco数据集的文件夹
datasets_list = ['train2017']#'train2017','val2017'
# 转换文件保存路径
savepath = home_path + "/COCO/"
miss = 0
count = 0
# 遍历train val test
for dataset in datasets_list:
annFile = '{}/annotations/instances_{}.json'.format(coco_dataset_dir, dataset)
coco = COCO(annFile)
classes = id2name(coco) # 类别 name -> id
print("Going to get all image ids. This will take a while...")
all_img_ids = geAllImagesId(coco)# 所有图片的id
# counter = 0
# 遍历所有图片
for imgId in tqdm(all_img_ids):
# counter += 1
# print('image %d'%(counter))
img = coco.loadImgs(imgId)[0]# 得到img信息
filename = img['file_name']
# print(filename)
annIds = coco.getAnnIds(imgIds=img['id'], iscrowd=None) # 根据图片id得到标注的id
anns = coco.loadAnns(annIds) # 得到这个图片的标注信息
bboxes = parseAnnotations(anns, filename) # 解析这个图片的标注
if(bboxes):#如果这个图片里有bbox
saveXmlAndImg(coco_dataset_dir, savepath, dataset, filename, bboxes)
count += 1
else:
print("No bbox found in this img.Skip it!")
miss += 1
print("Successfully generate %d images." % count)
print("Miss %d images." % miss)