Pipeline.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from os import path
  2. from typing import List
  3. from urllib.request import urlretrieve
  4. import cv2
  5. from pycs.interfaces.MediaFile import MediaFile
  6. from pycs.interfaces.MediaStorage import MediaStorage
  7. from pycs.interfaces.Pipeline import Pipeline as Interface
  8. class Pipeline(Interface):
  9. URL = 'https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml'
  10. def __init__(self, root_folder, distribution):
  11. print('hcffdv1 init')
  12. # get path to xml file
  13. xml_file = path.join(root_folder, 'haarcascade_frontalface_default.xml')
  14. # download
  15. if not path.exists(xml_file):
  16. urlretrieve(self.URL, xml_file)
  17. # load
  18. self.face_cascade = cv2.CascadeClassifier(xml_file)
  19. def close(self):
  20. print('hcffdv1 close')
  21. def collections(self) -> List[dict]:
  22. return [
  23. self.create_collection('face', 'face detected', autoselect=True),
  24. self.create_collection('none', 'no face detected')
  25. ]
  26. def execute(self, storage: MediaStorage, file: MediaFile):
  27. print('hcffdv1 execute')
  28. # load image, convert to grayscale, scale down
  29. image = cv2.imread(file.path)
  30. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  31. height, width = gray.shape
  32. scale_factor = min(2048 / width, 2048 / height, 1.0)
  33. scale_height, scale_width = int(height * scale_factor), int(width * scale_factor)
  34. scaled = cv2.resize(gray, (scale_width, scale_height))
  35. # detect faces
  36. faces = self.face_cascade.detectMultiScale(
  37. scaled,
  38. scaleFactor=1.1,
  39. minNeighbors=5,
  40. minSize=(192, 192)
  41. )
  42. # convert faces to result list
  43. result = False
  44. for x, y, w, h in faces:
  45. file.add_bounding_box(x / scale_width,
  46. y / scale_height,
  47. w / scale_width,
  48. h / scale_height)
  49. result = True
  50. # set file collection
  51. if result:
  52. file.set_collection('face')
  53. else:
  54. file.set_collection('none')