prepare_data_2d_custom.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # Copyright (c) 2018-present, Facebook, Inc.
  2. # All rights reserved.
  3. #
  4. # This source code is licensed under the license found in the
  5. # LICENSE file in the root directory of this source tree.
  6. #
  7. import numpy as np
  8. from glob import glob
  9. import os
  10. import sys
  11. import argparse
  12. from data_utils import suggest_metadata
  13. output_prefix_2d = 'data_2d_custom_'
  14. def decode(filename):
  15. # Latin1 encoding because Detectron runs on Python 2.7
  16. print('Processing {}'.format(filename))
  17. data = np.load(filename, encoding='latin1', allow_pickle=True)
  18. bb = data['boxes']
  19. kp = data['keypoints']
  20. metadata = data['metadata'].item()
  21. results_bb = []
  22. results_kp = []
  23. for i in range(len(bb)):
  24. if len(bb[i][1]) == 0 or len(kp[i][1]) == 0:
  25. # No bbox/keypoints detected for this frame -> will be interpolated
  26. results_bb.append(np.full(4, np.nan, dtype=np.float32)) # 4 bounding box coordinates
  27. results_kp.append(np.full((17, 4), np.nan, dtype=np.float32)) # 17 COCO keypoints
  28. continue
  29. best_match = np.argmax(bb[i][1][:, 4])
  30. best_bb = bb[i][1][best_match, :4]
  31. best_kp = kp[i][1][best_match].T.copy()
  32. results_bb.append(best_bb)
  33. results_kp.append(best_kp)
  34. bb = np.array(results_bb, dtype=np.float32)
  35. kp = np.array(results_kp, dtype=np.float32)
  36. kp = kp[:, :, :2] # Extract (x, y)
  37. # Fix missing bboxes/keypoints by linear interpolation
  38. mask = ~np.isnan(bb[:, 0])
  39. indices = np.arange(len(bb))
  40. for i in range(4):
  41. bb[:, i] = np.interp(indices, indices[mask], bb[mask, i])
  42. for i in range(17):
  43. for j in range(2):
  44. kp[:, i, j] = np.interp(indices, indices[mask], kp[mask, i, j])
  45. print('{} total frames processed'.format(len(bb)))
  46. print('{} frames were interpolated'.format(np.sum(~mask)))
  47. print('----------')
  48. return [{
  49. 'start_frame': 0, # Inclusive
  50. 'end_frame': len(kp), # Exclusive
  51. 'bounding_boxes': bb,
  52. 'keypoints': kp,
  53. }], metadata
  54. if __name__ == '__main__':
  55. if os.path.basename(os.getcwd()) != 'data':
  56. print('This script must be launched from the "data" directory')
  57. exit(0)
  58. parser = argparse.ArgumentParser(description='Custom dataset creator')
  59. parser.add_argument('-i', '--input', type=str, default='', metavar='PATH', help='detections directory')
  60. parser.add_argument('-o', '--output', type=str, default='', metavar='PATH', help='output suffix for 2D detections')
  61. args = parser.parse_args()
  62. if not args.input:
  63. print('Please specify the input directory')
  64. exit(0)
  65. if not args.output:
  66. print('Please specify an output suffix (e.g. detectron_pt_coco)')
  67. exit(0)
  68. print('Parsing 2D detections from', args.input)
  69. metadata = suggest_metadata('coco')
  70. metadata['video_metadata'] = {}
  71. output = {}
  72. file_list = glob(args.input + '/*.npz')
  73. for f in file_list:
  74. canonical_name = os.path.splitext(os.path.basename(f))[0]
  75. data, video_metadata = decode(f)
  76. output[canonical_name] = {}
  77. output[canonical_name]['custom'] = [data[0]['keypoints'].astype('float32')]
  78. metadata['video_metadata'][canonical_name] = video_metadata
  79. print('Saving...')
  80. np.savez_compressed(output_prefix_2d + args.output, positions_2d=output, metadata=metadata)
  81. print('Done.')