Spaces:
Build error
Build error
# Copyright (c) OpenMMLab. All rights reserved. | |
import csv | |
import json | |
import os | |
import time | |
import cv2 | |
import numpy as np | |
np.random.seed(0) | |
def get_poly_area(x, y): | |
"""Calculate area of polygon given (x,y) coordinates (Shoelace formula) | |
:param x: np.ndarray(N, ) | |
:param y: np.ndarray(N, ) | |
:return: area | |
""" | |
return float(0.5 * | |
np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))) | |
def get_seg_area(segmentations): | |
area = 0 | |
for segmentation in segmentations: | |
area += get_poly_area(segmentation[:, 0], segmentation[:, 1]) | |
return area | |
def save_coco_anno(data_annotation, | |
img_root, | |
save_path, | |
start_img_id=0, | |
start_ann_id=0, | |
kpt_num=17): | |
"""Save annotations in coco-format. | |
:param data_annotation: list of data annotation. | |
:param img_root: the root dir to load images. | |
:param save_path: the path to save transformed annotation file. | |
:param start_img_id: the starting point to count the image id. | |
:param start_ann_id: the starting point to count the annotation id. | |
:param kpt_num: the number of keypoint. | |
""" | |
images = [] | |
annotations = [] | |
img_id = start_img_id | |
ann_id = start_ann_id | |
for i in range(0, len(data_annotation)): | |
data_anno = data_annotation[i] | |
image_name = data_anno[0] | |
img = cv2.imread(os.path.join(img_root, image_name)) | |
kp_string = data_anno[1] | |
kps = json.loads(kp_string) | |
seg_string = data_anno[2] | |
segs = json.loads(seg_string) | |
for kp, seg in zip(kps, segs): | |
keypoints = np.zeros([kpt_num, 3]) | |
for ind, p in enumerate(kp): | |
if p['position'] is None: | |
continue | |
else: | |
keypoints[ind, 0] = p['position'][0] | |
keypoints[ind, 1] = p['position'][1] | |
keypoints[ind, 2] = 2 | |
segmentations = [] | |
max_x = -1 | |
max_y = -1 | |
min_x = 999999 | |
min_y = 999999 | |
for segm in seg: | |
if len(segm['segment']) == 0: | |
continue | |
segmentation = np.array(segm['segment']) | |
segmentations.append(segmentation) | |
_max_x, _max_y = segmentation.max(0) | |
_min_x, _min_y = segmentation.min(0) | |
max_x = max(max_x, _max_x) | |
max_y = max(max_y, _max_y) | |
min_x = min(min_x, _min_x) | |
min_y = min(min_y, _min_y) | |
anno = {} | |
anno['keypoints'] = keypoints.reshape(-1).tolist() | |
anno['image_id'] = img_id | |
anno['id'] = ann_id | |
anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0)) | |
anno['bbox'] = [ | |
float(min_x), | |
float(min_y), | |
float(max_x - min_x + 1), | |
float(max_y - min_y + 1) | |
] | |
anno['iscrowd'] = 0 | |
anno['area'] = get_seg_area(segmentations) | |
anno['category_id'] = 1 | |
anno['segmentation'] = [ | |
seg.reshape(-1).tolist() for seg in segmentations | |
] | |
annotations.append(anno) | |
ann_id += 1 | |
image = {} | |
image['id'] = img_id | |
image['file_name'] = image_name | |
image['height'] = img.shape[0] | |
image['width'] = img.shape[1] | |
images.append(image) | |
img_id += 1 | |
cocotype = {} | |
cocotype['info'] = {} | |
cocotype['info']['description'] = 'MacaquePose Generated by MMPose Team' | |
cocotype['info']['version'] = '1.0' | |
cocotype['info']['year'] = time.strftime('%Y', time.localtime()) | |
cocotype['info']['date_created'] = time.strftime('%Y/%m/%d', | |
time.localtime()) | |
cocotype['images'] = images | |
cocotype['annotations'] = annotations | |
cocotype['categories'] = [{ | |
'supercategory': | |
'animal', | |
'id': | |
1, | |
'name': | |
'macaque', | |
'keypoints': [ | |
'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear', | |
'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow', | |
'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee', | |
'right_knee', 'left_ankle', 'right_ankle' | |
], | |
'skeleton': [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], | |
[7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11], [2, 3], | |
[1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]] | |
}] | |
os.makedirs(os.path.dirname(save_path), exist_ok=True) | |
json.dump(cocotype, open(save_path, 'w'), indent=4) | |
print('number of images:', img_id) | |
print('number of annotations:', ann_id) | |
print(f'done {save_path}') | |
dataset_dir = '/data/macaque/' | |
with open(os.path.join(dataset_dir, 'annotations.csv'), 'r') as fp: | |
data_annotation_all = list(csv.reader(fp, delimiter=','))[1:] | |
np.random.shuffle(data_annotation_all) | |
data_annotation_train = data_annotation_all[0:12500] | |
data_annotation_val = data_annotation_all[12500:] | |
img_root = os.path.join(dataset_dir, 'images') | |
save_coco_anno( | |
data_annotation_train, | |
img_root, | |
os.path.join(dataset_dir, 'annotations', 'macaque_train.json'), | |
kpt_num=17) | |
save_coco_anno( | |
data_annotation_val, | |
img_root, | |
os.path.join(dataset_dir, 'annotations', 'macaque_test.json'), | |
start_img_id=12500, | |
start_ann_id=15672, | |
kpt_num=17) | |