| """ |
| @Fire |
| https://github.com/fire717 |
| """ |
| import os |
| import json |
| import pickle |
| import cv2 |
| import numpy as np |
|
|
|
|
|
|
|
|
| """ |
| segmentation格式取决于这个实例是一个单个的对象(即iscrowd=0,将使用polygons格式) |
| 还是一组对象(即iscrowd=1,将使用RLE格式 |
| |
| iscrowd=1时(将标注一组对象,比如一群人) |
| |
| |
| 标注说明:x,y,v,x,y,v,... |
| 其中v:#0没有标注;1有标注不可见(被遮挡);2有标注可见 |
| |
| 关键点顺序:'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'] |
| |
| """ |
|
|
|
|
| def main(img_dir, labels_path, output_name, output_img_dir): |
|
|
| if not os.path.exists(output_img_dir): |
| os.makedirs(output_img_dir) |
|
|
|
|
| with open(labels_path, 'r') as f: |
| data = json.load(f) |
|
|
| |
| |
| |
| |
| """ |
| [{'supercategory': 'person', 'name': 'person', |
| '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]], |
| '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'], 'id': 1}] |
| """ |
| |
|
|
| img_id_to_name = {} |
| img_name_to_id = {} |
| for item in data['images']: |
| idx = item['id'] |
| name = item['file_name'] |
| img_id_to_name[idx] = name |
| img_name_to_id[name] = idx |
| print(len(img_id_to_name)) |
| |
|
|
| anno_by_imgname = {} |
| for annotation in data['annotations']: |
| name = img_id_to_name[annotation['image_id']] |
| if name in anno_by_imgname: |
| anno_by_imgname[name] += [annotation] |
| else: |
| anno_by_imgname[name] = [annotation] |
| print(len(anno_by_imgname)) |
|
|
|
|
|
|
| new_label = [] |
| for k,v in anno_by_imgname.items(): |
| |
| if len(v)>3: |
| continue |
|
|
| |
| |
|
|
| img = cv2.imread(os.path.join(img_dir, k)) |
| if img is None: |
| print(os.path.join(img_dir, k)) |
| continue |
| h,w = img.shape[:2] |
| for idx,item in enumerate(v): |
| if item['iscrowd'] != 0: |
| continue |
|
|
| bbox = [int(x) for x in item['bbox']] |
| |
|
|
| keypoints = item['keypoints'] |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| |
| keypoints = np.array(keypoints).reshape((17,3)) |
|
|
| keypoints_v = keypoints[keypoints[:,2]>0] |
| if len(keypoints_v)<8: |
| continue |
| min_key_x = np.min(keypoints_v[:,0]) |
| max_key_x = np.max(keypoints_v[:,0]) |
| min_key_y = np.min(keypoints_v[:,1]) |
| max_key_y = np.max(keypoints_v[:,1]) |
|
|
| x0 = min(bbox[0], min_key_x) |
| x1 = max(bbox[0]+bbox[2], max_key_x) |
| y0 = min(bbox[1], min_key_y) |
| y1 = max(bbox[1]+bbox[3], max_key_y) |
| |
|
|
| |
| cx = (x0+x1)/2 |
| cy = (y0+y1)/2 |
| |
| half_size = ((x1-x0)+(y1-y0))/2 * EXPAND_RATIO |
| new_x0 = int(cx - half_size) |
| new_x1 = int(cx + half_size) |
| new_y0 = int(cy - half_size) |
| new_y1 = int(cy + half_size) |
|
|
| |
| pad_top = 0 |
| pad_left = 0 |
| pad_right = 0 |
| pad_bottom = 0 |
| if new_x0 < 0: |
| pad_left = -new_x0+1 |
| if new_y0 < 0: |
| pad_top = -new_y0+1 |
| if new_x1 > w: |
| pad_right = new_x1-w+1 |
| if new_y1 > h: |
| pad_bottom = new_y1-h+1 |
|
|
| pad_img = np.zeros((h+pad_top+pad_bottom, w+pad_left+pad_right, 3)) |
| pad_img[pad_top:pad_top+h,pad_left:pad_left+w] = img |
| new_x0 += pad_left |
| new_y0 += pad_top |
| new_x1 += pad_left |
| new_y1 += pad_top |
| |
|
|
| |
| save_name = k[:-4]+"_"+str(idx)+".jpg" |
| new_w = new_x1-new_x0 |
| new_h = new_y1-new_y0 |
| save_img = pad_img[new_y0:new_y1,new_x0:new_x1] |
| save_bbox = [(bbox[0]+pad_left-new_x0)/new_w, |
| (bbox[1]+pad_top-new_y0)/new_h, |
| (bbox[0]+bbox[2]+pad_left-new_x0)/new_w, |
| (bbox[1]+bbox[3]+pad_top-new_y0)/new_h |
| ] |
| save_center = [(save_bbox[0]+save_bbox[2])/2,(save_bbox[1]+save_bbox[3])/2] |
|
|
| save_keypoints = [] |
| for kid in range(len(keypoints)): |
| save_keypoints.extend([(int(keypoints[kid][0])+pad_left-new_x0)/new_w, |
| (int(keypoints[kid][1])+pad_top-new_y0)/new_h, |
| int(keypoints[kid][2]) |
| ]) |
| other_centers = [] |
| other_keypoints = [[] for _ in range(17)] |
| for idx2,item2 in enumerate(v): |
| if item2['iscrowd'] != 0 or idx2==idx: |
| continue |
| bbox2 = [int(x) for x in item2['bbox']] |
|
|
| save_bbox2 = [(bbox2[0]+pad_left-new_x0)/new_w, |
| (bbox2[1]+pad_top-new_y0)/new_h, |
| (bbox2[0]+bbox2[2]+pad_left-new_x0)/new_w, |
| (bbox2[1]+bbox2[3]+pad_top-new_y0)/new_h |
| ] |
| save_center2 = [(save_bbox2[0]+save_bbox2[2])/2, |
| (save_bbox2[1]+save_bbox2[3])/2] |
| if save_center2[0]>0 and save_center2[0]<1 and save_center2[1]>0 and save_center2[1]<1: |
| other_centers.append(save_center2) |
|
|
| keypoints2 = item2['keypoints'] |
| keypoints2 = np.array(keypoints2).reshape((17,3)) |
| for kid2 in range(17): |
| if keypoints2[kid2][2]==0: |
| continue |
| kx = (keypoints2[kid2][0]+pad_left-new_x0)/new_w |
| ky = (keypoints2[kid2][1]+pad_top-new_y0)/new_h |
| if kx>0 and kx<1 and ky>0 and ky<1: |
| other_keypoints[kid2].append([kx,ky]) |
|
|
| save_item = { |
| "img_name":save_name, |
| "keypoints":save_keypoints, |
| "center":save_center, |
| "bbox":save_bbox, |
| "other_centers":other_centers, |
| "other_keypoints":other_keypoints, |
| } |
| |
| |
| |
| new_label.append(save_item) |
|
|
|
|
|
|
| |
| if SHOW_POINTS_ON_IMG: |
| cv2.circle(save_img, (int(save_center[0]*new_w), int(save_center[1]*new_h)), 4, (0,255,0), 3) |
| for show_kid in range(len(save_keypoints)//3): |
| if save_keypoints[show_kid*3+2]==1: |
| color = (255,0,0) |
| elif save_keypoints[show_kid*3+2]==2: |
| color = (0,0,255) |
| else: |
| continue |
| cv2.circle(save_img, (int(save_keypoints[show_kid*3]*new_w), |
| int(save_keypoints[show_kid*3+1]*new_h)), 3, color, 2) |
| cv2.rectangle(save_img, (int(save_bbox[0]*new_w), int(save_bbox[1]*new_h)), |
| (int(save_bbox[2]*new_w), int(save_bbox[3]*new_h)), (0,255,0), 2) |
| for show_c in other_centers: |
| cv2.circle(save_img, (int(show_c[0]*new_w), int(show_c[1]*new_h)), 4, (0,255,255), 3) |
| for show_ks in other_keypoints: |
| for show_k in show_ks: |
| cv2.circle(save_img, (int(show_k[0]*new_w), int(show_k[1]*new_h)), 3, (255,255,0), 2) |
|
|
|
|
| cv2.imwrite(os.path.join(output_img_dir, save_name), save_img) |
| |
| |
|
|
| |
| |
|
|
| with open(output_name,'w') as f: |
| json.dump(new_label, f, ensure_ascii=False) |
| print('Total write ', len(new_label)) |
|
|
|
|
| if __name__ == '__main__': |
|
|
| |
|
|
| SHOW_POINTS_ON_IMG = False |
| |
|
|
| EXPAND_RATIO = 1. |
| |
|
|
|
|
| output_img_dir = "./data/croped/imgs" |
| img_dir = "./data/val2017" |
| labels_path = "./data/annotations/person_keypoints_val2017.json" |
| output_name = "./data/croped/val2017.json" |
| main(img_dir, labels_path, output_name, output_img_dir) |
| img_dir = "./data/train2017" |
| labels_path = "./data/annotations/person_keypoints_train2017.json" |
| output_name = "./data/croped/train2017.json" |
| main(img_dir, labels_path, output_name, output_img_dir) |
| |
|
|