pipeline.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 .detection import Detector
  7. from .features import Features
  8. from ..utils import Errorable
  9. from ..utils import Video
  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. return None, None
  26. try:
  27. detector = self._load_detector(detector_config)
  28. except:
  29. self._report_error("Could not load the detector")
  30. return None, None
  31. try:
  32. features = self._load_features(features_config)
  33. except:
  34. detector.close()
  35. self._report_error("Could not load the feature extraction mechanism")
  36. return None, None
  37. return detector, features
  38. def _load_detector(self, config):
  39. detector = Detector(config={**config, 'distribution-root': self.config['model-distribution']})
  40. return detector
  41. def _load_features(self, config):
  42. features = Features(config={**config, 'distribution-root': self.config['model-distribution']})
  43. return features
  44. def execute(self, subjobs, callback):
  45. callback(0)
  46. subjob_count = float(len(subjobs))
  47. for index, subjob in enumerate(subjobs):
  48. subjob_name = subjob['subjob']
  49. prediction = subjob['prediction']
  50. jobinfo = subjob['jobinfo']
  51. jobinfo[subjob_name] = {'done-by': 'pipeline'}
  52. if subjob_name == 'detect-faces':
  53. # Run face detection
  54. if self.detector.last_error is not None:
  55. jobinfo[subjob_name]['error'] = self.detector.last_error
  56. jobinfo[subjob_name]['result'] = False
  57. else:
  58. filename = subjob['filename']
  59. # Acquire image
  60. if subjob['filetype'] == 'image':
  61. img = Image.open(filename)
  62. elif subjob['filetype'] == 'video':
  63. if 'cap' in subjob.keys():
  64. cap = subjob['cap']
  65. else:
  66. cap = Video(filename)
  67. if cap.last_error is None:
  68. jobinfo[subjob_name]['error'] = cap.last_error
  69. else:
  70. jobinfo[subjob_name]['result'] = False
  71. continue
  72. img = cap.get_frame(subjob['frame'])
  73. else:
  74. jobinfo[subjob_name]['error'] = 'File format not supported!'
  75. jobinfo[subjob_name]['result'] = False
  76. continue
  77. faces = self.detector.detect_faces(img)
  78. if self.detector.last_error is not None:
  79. jobinfo[subjob_name]['error'] = self.detector.last_error
  80. jobinfo[subjob_name]['result'] = False
  81. else:
  82. prediction['faces'] = faces
  83. jobinfo[subjob_name]['result'] = True
  84. else:
  85. jobinfo[subjob_name]['result'] = False
  86. callback(float(index) / subjob_count)
  87. callback(1)
  88. def close(self):
  89. self.detector.close()
  90. self.features.close()