forked from akofman/wider-face-pascal-voc-annotations
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvert.py
executable file
·151 lines (122 loc) · 5.74 KB
/
convert.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
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
from PIL import Image
import os
VARIABILITY_DICT = {
'blur': {
'0': 'clear',
'1': 'normal_blur',
'2': 'heavy blur',
},
'expression': {
'0': 'typical expression',
'1': 'exaggerate expression',
},
'illumination': {
'0': 'normal illumination',
'1': 'extreme illumination',
},
'occlusion': {
'0': 'no occlusion',
'1': 'partial occlusion',
'2': 'heavy occlusion',
},
'pose': {
'0': 'typical pose',
'1': 'atypical pose',
},
'invalid': {
'0': 'valid image',
'1': 'invalid image',
}
}
def createAnnotationPascalVocTree(folder, basename, path, width, height):
annotation = ET.Element('annotation')
ET.SubElement(annotation, 'folder').text = folder
ET.SubElement(annotation, 'filename').text = basename
ET.SubElement(annotation, 'path').text = path
source = ET.SubElement(annotation, 'source')
ET.SubElement(source, 'database').text = 'Unknown'
size = ET.SubElement(annotation, 'size')
ET.SubElement(size, 'width').text = width
ET.SubElement(size, 'height').text = height
ET.SubElement(size, 'depth').text = '3'
ET.SubElement(annotation, 'segmented').text = '0'
return ET.ElementTree(annotation)
def createObjectPascalVocTree(xmin, ymin, xmax, ymax, blur,
expr, illum, invalid, occl, pose):
obj = ET.Element('object')
ET.SubElement(obj, 'name').text = 'face'
ET.SubElement(obj, 'pose').text = 'Unspecified'
ET.SubElement(obj, 'truncated').text = '0'
bndbox = ET.SubElement(obj, 'bndbox')
ET.SubElement(bndbox, 'xmin').text = xmin
ET.SubElement(bndbox, 'ymin').text = ymin
ET.SubElement(bndbox, 'xmax').text = xmax
ET.SubElement(bndbox, 'ymax').text = ymax
ET.SubElement(obj, 'blur').text = blur
ET.SubElement(obj, 'expression').text = expr
ET.SubElement(obj, 'illumination').text = illum
ET.SubElement(obj, 'invalid').text = invalid
ET.SubElement(obj, 'occlusion').text = occl
ET.SubElement(obj, 'pose').text = pose
return ET.ElementTree(obj)
def parseImFilename(imFilename, imPath):
im = Image.open(os.path.join(imPath, imFilename))
folder, basename = imFilename.split('/')
width, height = im.size
return folder, basename, imFilename, str(width), str(height)
def convert_variability_to_string(blur, expr, illum, invalid, occl, pose):
blur = VARIABILITY_DICT['blur'][blur]
expr = VARIABILITY_DICT['expression'][expr]
illum = VARIABILITY_DICT['illumination'][illum]
invalid = VARIABILITY_DICT['invalid'][invalid]
occl = VARIABILITY_DICT['occlusion'][occl]
pose = VARIABILITY_DICT['pose'][pose]
return blur, expr, illum, invalid, occl, pose
def convertWFAnnotations(annotationsPath, targetPath, imPath):
ann = None
basename = ''
with open(annotationsPath) as f:
while True:
imFilename = f.readline().strip()
if imFilename:
folder, basename, path, width, height = parseImFilename(imFilename, imPath)
ann = createAnnotationPascalVocTree(folder, basename, os.path.join(imPath, path), width, height)
nbBndboxes = f.readline()
i = 0
while i < int(nbBndboxes):
i = i + 1
x1, y1, w, h, blur, expr, illum, invalid, occl, pose = [int(j) for j in f.readline().split()]
blur, expr, illum, invalid, occl, pose = convert_variability_to_string(str(blur),
str(expr),
str(illum),
str(invalid),
str(occl),
str(pose))
ann.getroot().append(createObjectPascalVocTree(str(x1),
str(y1),
str(x1 + w),
str(y1 + h),
blur,
expr,
illum,
invalid,
occl,
pose).getroot())
if not os.path.exists(targetPath):
os.makedirs(targetPath)
annFilename = os.path.join(targetPath, basename.replace('.jpg', '.xml'))
ann.write(annFilename)
print('{} => {}'.format(basename, annFilename), flush=True)
else:
break
f.close()
if __name__ == '__main__':
import argparse
PARSER = argparse.ArgumentParser()
PARSER.add_argument('-ap', '--annotations-path', help='the annotations file path. ie:"./wider_face_split/wider_face_train_bbx_gt.txt".')
PARSER.add_argument('-tp', '--target-path', help='the target directory path where XML files will be copied.')
PARSER.add_argument('-ip', '--images-path', help='the images directory path. ie:"./WIDER_train/images"')
ARGS = vars(PARSER.parse_args())
convertWFAnnotations(ARGS['annotations_path'], ARGS['target_path'], ARGS['images_path'])