mirror of https://github.com/open-mmlab/mmpose
183 lines
5.5 KiB
Python
183 lines
5.5 KiB
Python
# 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)
|