parse_macaquepose_dataset.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # Copyright (c) OpenMMLab. All rights reserved.
  2. import csv
  3. import json
  4. import os
  5. import time
  6. import cv2
  7. import numpy as np
  8. np.random.seed(0)
  9. def get_poly_area(x, y):
  10. """Calculate area of polygon given (x,y) coordinates (Shoelace formula)
  11. :param x: np.ndarray(N, )
  12. :param y: np.ndarray(N, )
  13. :return: area
  14. """
  15. return float(0.5 *
  16. np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))))
  17. def get_seg_area(segmentations):
  18. area = 0
  19. for segmentation in segmentations:
  20. area += get_poly_area(segmentation[:, 0], segmentation[:, 1])
  21. return area
  22. def save_coco_anno(data_annotation,
  23. img_root,
  24. save_path,
  25. start_img_id=0,
  26. start_ann_id=0,
  27. kpt_num=17):
  28. """Save annotations in coco-format.
  29. :param data_annotation: list of data annotation.
  30. :param img_root: the root dir to load images.
  31. :param save_path: the path to save transformed annotation file.
  32. :param start_img_id: the starting point to count the image id.
  33. :param start_ann_id: the starting point to count the annotation id.
  34. :param kpt_num: the number of keypoint.
  35. """
  36. images = []
  37. annotations = []
  38. img_id = start_img_id
  39. ann_id = start_ann_id
  40. for i in range(0, len(data_annotation)):
  41. data_anno = data_annotation[i]
  42. image_name = data_anno[0]
  43. img = cv2.imread(os.path.join(img_root, image_name))
  44. kp_string = data_anno[1]
  45. kps = json.loads(kp_string)
  46. seg_string = data_anno[2]
  47. segs = json.loads(seg_string)
  48. for kp, seg in zip(kps, segs):
  49. keypoints = np.zeros([kpt_num, 3])
  50. for ind, p in enumerate(kp):
  51. if p['position'] is None:
  52. continue
  53. else:
  54. keypoints[ind, 0] = p['position'][0]
  55. keypoints[ind, 1] = p['position'][1]
  56. keypoints[ind, 2] = 2
  57. segmentations = []
  58. max_x = -1
  59. max_y = -1
  60. min_x = 999999
  61. min_y = 999999
  62. for segm in seg:
  63. if len(segm['segment']) == 0:
  64. continue
  65. segmentation = np.array(segm['segment'])
  66. segmentations.append(segmentation)
  67. _max_x, _max_y = segmentation.max(0)
  68. _min_x, _min_y = segmentation.min(0)
  69. max_x = max(max_x, _max_x)
  70. max_y = max(max_y, _max_y)
  71. min_x = min(min_x, _min_x)
  72. min_y = min(min_y, _min_y)
  73. anno = {}
  74. anno['keypoints'] = keypoints.reshape(-1).tolist()
  75. anno['image_id'] = img_id
  76. anno['id'] = ann_id
  77. anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0))
  78. anno['bbox'] = [
  79. float(min_x),
  80. float(min_y),
  81. float(max_x - min_x + 1),
  82. float(max_y - min_y + 1)
  83. ]
  84. anno['iscrowd'] = 0
  85. anno['area'] = get_seg_area(segmentations)
  86. anno['category_id'] = 1
  87. anno['segmentation'] = [
  88. seg.reshape(-1).tolist() for seg in segmentations
  89. ]
  90. annotations.append(anno)
  91. ann_id += 1
  92. image = {}
  93. image['id'] = img_id
  94. image['file_name'] = image_name
  95. image['height'] = img.shape[0]
  96. image['width'] = img.shape[1]
  97. images.append(image)
  98. img_id += 1
  99. cocotype = {}
  100. cocotype['info'] = {}
  101. cocotype['info']['description'] = 'MacaquePose Generated by MMPose Team'
  102. cocotype['info']['version'] = '1.0'
  103. cocotype['info']['year'] = time.strftime('%Y', time.localtime())
  104. cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',
  105. time.localtime())
  106. cocotype['images'] = images
  107. cocotype['annotations'] = annotations
  108. cocotype['categories'] = [{
  109. 'supercategory':
  110. 'animal',
  111. 'id':
  112. 1,
  113. 'name':
  114. 'macaque',
  115. 'keypoints': [
  116. 'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear',
  117. 'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow',
  118. 'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee',
  119. 'right_knee', 'left_ankle', 'right_ankle'
  120. ],
  121. 'skeleton': [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12],
  122. [7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11], [2, 3],
  123. [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]]
  124. }]
  125. os.makedirs(os.path.dirname(save_path), exist_ok=True)
  126. json.dump(cocotype, open(save_path, 'w'), indent=4)
  127. print('number of images:', img_id)
  128. print('number of annotations:', ann_id)
  129. print(f'done {save_path}')
  130. dataset_dir = '/data/macaque/'
  131. with open(os.path.join(dataset_dir, 'annotations.csv'), 'r') as fp:
  132. data_annotation_all = list(csv.reader(fp, delimiter=','))[1:]
  133. np.random.shuffle(data_annotation_all)
  134. data_annotation_train = data_annotation_all[0:12500]
  135. data_annotation_val = data_annotation_all[12500:]
  136. img_root = os.path.join(dataset_dir, 'images')
  137. save_coco_anno(
  138. data_annotation_train,
  139. img_root,
  140. os.path.join(dataset_dir, 'annotations', 'macaque_train.json'),
  141. kpt_num=17)
  142. save_coco_anno(
  143. data_annotation_val,
  144. img_root,
  145. os.path.join(dataset_dir, 'annotations', 'macaque_test.json'),
  146. start_img_id=12500,
  147. start_ann_id=15672,
  148. kpt_num=17)