1
1

pipeline.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/env python
  2. """pipeline: Detection and other model pipeline."""
  3. import json
  4. import os.path
  5. from PIL import Image
  6. from pycs.utils import Errorable
  7. from pycs.utils import Video
  8. from .detection import Detector
  9. from .features import Features
  10. class Pipeline(Errorable):
  11. def __init__(self, config):
  12. Errorable.__init__(self)
  13. self.config = config
  14. self.detector, self.features = self._load_distribution()
  15. self._err_children += [self.detector, self.features]
  16. def _load_distribution(self):
  17. try:
  18. distribution_path = self.config['model-distribution']
  19. with open(os.path.join(distribution_path, 'distribution.json'), 'r') as distribution_json_file:
  20. distribution_json = json.load(distribution_json_file)
  21. detector_config = distribution_json['detection']
  22. features_config = distribution_json['features']
  23. except:
  24. self._report_error("Could not parse the distribution configuration")
  25. # TODO nothing is returned if no exception occurs
  26. return None, None
  27. try:
  28. detector = self._load_detector(detector_config)
  29. except:
  30. self._report_error("Could not load the detector")
  31. return None, None
  32. try:
  33. features = self._load_features(features_config)
  34. except:
  35. # TODO detector should not be closed manually
  36. detector.close()
  37. self._report_error("Could not load the feature extraction mechanism")
  38. return None, None
  39. return detector, features
  40. def _load_detector(self, config):
  41. detector = Detector(config={**config, 'distribution-root': self.config['model-distribution']})
  42. return detector
  43. def _load_features(self, config):
  44. features = Features(config={**config, 'distribution-root': self.config['model-distribution']})
  45. return features
  46. def execute(self, subjobs, callback):
  47. callback(0)
  48. subjob_count = float(len(subjobs))
  49. for index, subjob in enumerate(subjobs):
  50. subjob_name = subjob['subjob']
  51. prediction = subjob['prediction']
  52. jobinfo = subjob['jobinfo']
  53. jobinfo[subjob_name] = {'done-by': 'pipeline'}
  54. if subjob_name == 'detect-faces':
  55. # Run face detection
  56. if self.detector.last_error is not None:
  57. jobinfo[subjob_name]['error'] = self.detector.last_error
  58. jobinfo[subjob_name]['result'] = False
  59. else:
  60. filename = subjob['filename']
  61. # Acquire image
  62. if subjob['filetype'] == 'image':
  63. img = Image.open(filename)
  64. elif subjob['filetype'] == 'video':
  65. if 'cap' in subjob.keys():
  66. cap = subjob['cap']
  67. else:
  68. cap = Video(filename)
  69. if cap.last_error is None:
  70. jobinfo[subjob_name]['error'] = cap.last_error
  71. else:
  72. jobinfo[subjob_name]['result'] = False
  73. continue
  74. img = cap.get_frame(subjob['frame'])
  75. else:
  76. jobinfo[subjob_name]['error'] = 'File format not supported!'
  77. jobinfo[subjob_name]['result'] = False
  78. continue
  79. faces = self.detector.detect_faces(img)
  80. if self.detector.last_error is not None:
  81. jobinfo[subjob_name]['error'] = self.detector.last_error
  82. jobinfo[subjob_name]['result'] = False
  83. else:
  84. prediction['faces'] = faces
  85. jobinfo[subjob_name]['result'] = True
  86. else:
  87. jobinfo[subjob_name]['result'] = False
  88. callback(float(index) / subjob_count)
  89. callback(1)
  90. def close(self):
  91. self.detector.close()
  92. self.features.close()