Skip to content

Commit 5961ae3

Browse files
authored
[Feature] add wflw2coco (#2961)
1 parent 10f98b5 commit 5961ae3

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

Diff for: docs/en/dataset_zoo/2d_face_keypoint.md

+2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ mmpose
152152
...
153153
```
154154

155+
We also supply a script which can convert the raw WFLW annotations to COCO style. The script's output is not completely consistent with the annotations downloaded from the URL, but it does not affect training and testing.
156+
155157
## AFLW Dataset
156158

157159
<!-- [DATASET] -->

Diff for: docs/zh_cn/dataset_zoo/2d_face_keypoint.md

+2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ mmpose
152152
...
153153
```
154154

155+
We also supply a script which can convert the raw WFLW annotations to COCO style. The script's output is not completely consistent with the annotations downloaded from the URL, but it does not affect training and testing.
156+
155157
## AFLW Dataset
156158

157159
<!-- [DATASET] -->

Diff for: tools/dataset_converters/wflw2coco.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Copyright (c) OpenMMLab. All rights reserved.
2+
import json
3+
import math
4+
import os
5+
import os.path as osp
6+
7+
import cv2
8+
import numpy as np
9+
10+
11+
def default_dump(obj):
12+
"""Convert numpy classes to JSON serializable objects."""
13+
if isinstance(obj, (np.integer, np.floating, np.bool_)):
14+
return obj.item()
15+
elif isinstance(obj, np.ndarray):
16+
return obj.tolist()
17+
else:
18+
return obj
19+
20+
21+
def convert_wflw_to_coco(ann_file, out_file):
22+
annotations = []
23+
images = []
24+
files = []
25+
cnt = 0
26+
image_cnt = 0
27+
28+
data_infos = open(ann_file).readlines()
29+
data_infos = [x.strip().split() for x in data_infos]
30+
for data in data_infos:
31+
file_name = data[-1]
32+
img_path = osp.join('data/wflw/WFLW_images', file_name)
33+
img = cv2.imread(img_path)
34+
35+
keypoints = []
36+
37+
coordinates = [data[i:i + 2] for i in range(0, 196, 2)]
38+
39+
for coordinate in coordinates:
40+
x, y = coordinate[0], coordinate[1]
41+
x, y = float(x), float(y)
42+
keypoints.append([x, y, 1])
43+
keypoints = np.array(keypoints)
44+
45+
x1, y1, _ = np.amin(keypoints, axis=0)
46+
x2, y2, _ = np.amax(keypoints, axis=0)
47+
w, h = x2 - x1, y2 - y1
48+
scale = math.ceil(max(w, h)) / 200
49+
w_new = w / scale
50+
h_new = h / scale
51+
center = [(x1 + x2) / 2, (y1 + y2) / 2]
52+
x1_new = center[0] - w_new / 2
53+
y1_new = center[1] - h_new / 2
54+
bbox = [x1_new, y1_new, w_new, h_new]
55+
56+
image = {}
57+
# check if the image already exists
58+
if file_name in files:
59+
image = images[files.index(file_name)]
60+
else:
61+
image['id'] = image_cnt
62+
image['file_name'] = f'{file_name}'
63+
image['height'] = img.shape[0]
64+
image['width'] = img.shape[1]
65+
image_cnt = image_cnt + 1
66+
files.append(file_name)
67+
images.append(image)
68+
69+
ann = {}
70+
ann['keypoints'] = keypoints.reshape(-1).tolist()
71+
ann['image_id'] = image['id']
72+
ann['id'] = cnt
73+
ann['num_keypoints'] = len(keypoints)
74+
ann['bbox'] = bbox
75+
ann['is_crowd'] = 0
76+
ann['area'] = w * h
77+
ann['category_id'] = 1
78+
ann['center'] = center
79+
ann['scale'] = scale
80+
annotations.append(ann)
81+
cnt = cnt + 1
82+
83+
cocotype = {}
84+
cocotype['images'] = images
85+
cocotype['annotations'] = annotations
86+
cocotype['categories'] = [{
87+
'supercategory': 'person',
88+
'id': 1,
89+
'name': 'face',
90+
'keypoints': [],
91+
'skeleton': []
92+
}]
93+
94+
json.dump(
95+
cocotype,
96+
open(out_file, 'w'),
97+
ensure_ascii=False,
98+
default=default_dump)
99+
print(f'done {out_file}')
100+
101+
102+
if __name__ == '__main__':
103+
if not osp.exists('data/wflw/annotations'):
104+
os.makedirs('data/wflw/annotations')
105+
root_folder = 'data/wflw'
106+
ann_folder = f'{root_folder}/WFLW_annotations'
107+
for root, dirs, files in os.walk(ann_folder):
108+
for file in files:
109+
if not file.endswith('txt'):
110+
continue
111+
print(f'Processing {file}')
112+
sub_class = file.split('_')[-1].replace('.txt', '')
113+
if sub_class != 'train' and sub_class != 'test':
114+
out_file = f'face_landmarks_wflw_test_{sub_class}.json'
115+
else:
116+
out_file = f'face_landmarks_wflw_{sub_class}.json'
117+
convert_wflw_to_coco(f'{root}/{file}',
118+
f'{root_folder}/annotations/{out_file}')

0 commit comments

Comments
 (0)