123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- from os import path
- from typing import List
- from urllib.request import urlretrieve
- import cv2
- from pycs.interfaces.MediaFile import MediaFile
- from pycs.interfaces.MediaStorage import MediaStorage
- from pycs.interfaces.Pipeline import Pipeline as Interface
- class Pipeline(Interface):
- URL = 'https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml'
- def __init__(self, root_folder, distribution):
- print('hcffdv1 init')
- # get path to xml file
- xml_file = path.join(root_folder, 'haarcascade_frontalface_default.xml')
- # download
- if not path.exists(xml_file):
- urlretrieve(self.URL, xml_file)
- # load
- self.face_cascade = cv2.CascadeClassifier(xml_file)
- def close(self):
- print('hcffdv1 close')
- def collections(self) -> List[dict]:
- return [
- self.create_collection('face', 'face detected', autoselect=True),
- self.create_collection('none', 'no face detected')
- ]
- def execute(self, storage: MediaStorage, file: MediaFile):
- print('hcffdv1 execute')
- # load file and analyze frames
- found = False
- if file.type == 'image':
- found = self.__find(file, cv2.imread(file.path))
- else:
- video = cv2.VideoCapture(file.path)
- index = 0
- ret, image = video.read()
- while ret:
- if self.__find(file, image, index):
- found = True
- ret, image = video.read()
- index += 1
- video.release()
- # set file collection
- if found:
- file.set_collection('face')
- else:
- file.set_collection('none')
- def __find(self, file: MediaFile, image, frame=None):
- # convert to grayscale, scale down
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- height, width = gray.shape
- scale_factor = min(2048 / width, 2048 / height, 1.0)
- scale_height, scale_width = int(height * scale_factor), int(width * scale_factor)
- scaled = cv2.resize(gray, (scale_width, scale_height))
- # detect faces
- faces = self.face_cascade.detectMultiScale(
- scaled,
- scaleFactor=1.1,
- minNeighbors=5,
- minSize=(192, 192)
- )
- # add faces to results
- for x, y, w, h in faces:
- file.add_bounding_box(x / scale_width,
- y / scale_height,
- w / scale_width,
- h / scale_height,
- frame=frame)
- return len(faces) > 0
|