def launch_aligner(self): """ Load the aligner plugin to retrieve landmarks """ out_queue = queue_manager.get_queue("out") kwargs = {"in_queue": queue_manager.get_queue("in"), "out_queue": out_queue} for plugin in ("fan", "cv2_dnn"): aligner = PluginLoader.get_aligner(plugin)(loglevel=self.args.loglevel) process = SpawnProcess(aligner.run, **kwargs) event = process.event process.start() # Wait for Aligner to take init # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. event.wait(300) if not event.is_set(): if plugin == "fan": process.join() logger.error("Error initializing FAN. Trying CV2-DNN") continue else: raise ValueError("Error inititalizing Aligner") if plugin == "cv2_dnn": return try: err = None err = out_queue.get(True, 1) except QueueEmpty: pass if not err: break process.join() logger.error("Error initializing FAN. Trying CV2-DNN")
def launch_aligner(self): """ Launch the face aligner """ logger.debug("Launching Aligner") kwargs = {"in_queue": self.queues["extract_align_in"], "out_queue": self.queues["extract_align_out"]} process = SpawnProcess(self.aligner.run, **kwargs) event = process.event error = process.error process.start() self.processes.append(process) # Wait for Aligner to take it's VRAM # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. # TODO investigate why this is and fix if possible for mins in reversed(range(5)): for seconds in range(60): event.wait(seconds) if event.is_set(): break if error.is_set(): break if event.is_set(): break if mins == 0 or error.is_set(): raise ValueError("Error initializing Aligner") logger.info("Waiting for Aligner... Time out in %s minutes", mins) logger.debug("Launched Aligner")
def init_extractor(self, loglevel): """ Initialize FAN """ logger.debug("Initialize Extractor") out_queue = queue_manager.get_queue("out") d_kwargs = {"in_queue": queue_manager.get_queue("in"), "out_queue": queue_manager.get_queue("align")} a_kwargs = {"in_queue": queue_manager.get_queue("align"), "out_queue": out_queue} detector = PluginLoader.get_detector("manual")(loglevel=loglevel) detect_process = SpawnProcess(detector.run, **d_kwargs) d_event = detect_process.event detect_process.start() for plugin in ("fan", "cv2_dnn"): aligner = PluginLoader.get_aligner(plugin)(loglevel=loglevel) align_process = SpawnProcess(aligner.run, **a_kwargs) a_event = align_process.event align_process.start() # Wait for Aligner to initialize # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. a_event.wait(300) if not a_event.is_set(): if plugin == "fan": align_process.join() logger.error("Error initializing FAN. Trying CV2-DNN") continue else: raise ValueError("Error inititalizing Aligner") if plugin == "cv2_dnn": break try: err = None err = out_queue.get(True, 1) except QueueEmpty: pass if not err: break align_process.join() logger.error("Error initializing FAN. Trying CV2-DNN") d_event.wait(10) if not d_event.is_set(): raise ValueError("Error inititalizing Detector") self.extractor["detect"] = detector self.extractor["align"] = aligner logger.debug("Initialized Extractor")
def launch_aligner(self): """ Load the aligner plugin to retrieve landmarks """ out_queue = queue_manager.get_queue("out") kwargs = { "in_queue": queue_manager.get_queue("in"), "out_queue": out_queue } for plugin in ("fan", "cv2_dnn"): aligner = PluginLoader.get_aligner(plugin)( loglevel=self.args.loglevel) process = SpawnProcess(aligner.run, **kwargs) event = process.event process.start() # Wait for Aligner to take init # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. event.wait(300) if not event.is_set(): if plugin == "fan": process.join() logger.error("Error initializing FAN. Trying CV2-DNN") continue else: raise ValueError("Error inititalizing Aligner") if plugin == "cv2_dnn": return try: err = None err = out_queue.get(True, 1) except QueueEmpty: pass if not err: break process.join() logger.error("Error initializing FAN. Trying CV2-DNN")
def launch_aligner(self): """ Load the aligner plugin to retrieve landmarks """ out_queue = queue_manager.get_queue("out") kwargs = {"in_queue": queue_manager.get_queue("in"), "out_queue": out_queue} <<<<<<< HEAD for plugin in ("fan", "dlib"): ======= for plugin in ("fan", "cv2_dnn"): >>>>>>> upstream/master aligner = PluginLoader.get_aligner(plugin)(loglevel=self.args.loglevel) process = SpawnProcess(aligner.run, **kwargs) event = process.event process.start() # Wait for Aligner to take init # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. event.wait(300) if not event.is_set(): if plugin == "fan": process.join() logger.error("Error initializing FAN. Trying CV2-DNN") continue else: raise ValueError("Error inititalizing Aligner") if plugin == "cv2_dnn": return
class Plugins(): """ Detector and Aligner Plugins and queues """ def __init__(self, arguments): logger.debug("Initializing %s", self.__class__.__name__) self.args = arguments self.detector = self.load_detector() self.aligner = self.load_aligner() self.is_parallel = self.set_parallel_processing() self.process_detect = None self.process_align = None self.add_queues() logger.debug("Initialized %s", self.__class__.__name__) def set_parallel_processing(self): """ Set whether to run detect and align together or separately """ detector_vram = self.detector.vram aligner_vram = self.aligner.vram gpu_stats = GPUStats() if (detector_vram == 0 or aligner_vram == 0 or gpu_stats.device_count == 0): logger.debug( "At least one of aligner or detector have no VRAM requirement. " "Enabling parallel processing.") return True if hasattr(self.args, "multiprocess") and not self.args.multiprocess: logger.info("NB: Parallel processing disabled.You may get faster " "extraction speeds by enabling it with the -mp switch") return False required_vram = detector_vram + aligner_vram + 320 # 320MB buffer stats = gpu_stats.get_card_most_free() free_vram = int(stats["free"]) logger.verbose("%s - %sMB free of %sMB", stats["device"], free_vram, int(stats["total"])) if free_vram <= required_vram: logger.warning("Not enough free VRAM for parallel processing. " "Switching to serial") return False return True def add_queues(self): """ Add the required processing queues to Queue Manager """ for task in ("load", "detect", "align", "save"): size = 0 if task == "load" or (not self.is_parallel and task == "detect"): size = 100 queue_manager.add_queue(task, maxsize=size) def load_detector(self): """ Set global arguments and load detector plugin """ detector_name = self.args.detector.replace("-", "_").lower() logger.debug("Loading Detector: '%s'", detector_name) # Rotation rotation = None if hasattr(self.args, "rotate_images"): rotation = self.args.rotate_images detector = PluginLoader.get_detector(detector_name)( loglevel=self.args.loglevel, rotation=rotation) return detector def load_aligner(self): """ Set global arguments and load aligner plugin """ aligner_name = self.args.aligner.replace("-", "_").lower() logger.debug("Loading Aligner: '%s'", aligner_name) aligner = PluginLoader.get_aligner(aligner_name)( loglevel=self.args.loglevel) return aligner def launch_aligner(self): """ Launch the face aligner """ logger.debug("Launching Aligner") out_queue = queue_manager.get_queue("align") kwargs = { "in_queue": queue_manager.get_queue("detect"), "out_queue": out_queue } self.process_align = SpawnProcess(self.aligner.run, **kwargs) event = self.process_align.event self.process_align.start() # Wait for Aligner to take it's VRAM # The first ever load of the model for FAN has reportedly taken # up to 3-4 minutes, hence high timeout. # TODO investigate why this is and fix if possible for mins in reversed(range(5)): event.wait(60) if event.is_set(): break if mins == 0: raise ValueError("Error initializing Aligner") logger.info("Waiting for Aligner... Time out in %s minutes", mins) logger.debug("Launched Aligner") def launch_detector(self): """ Launch the face detector """ logger.debug("Launching Detector") out_queue = queue_manager.get_queue("detect") kwargs = { "in_queue": queue_manager.get_queue("load"), "out_queue": out_queue } mp_func = PoolProcess if self.detector.parent_is_pool else SpawnProcess self.process_detect = mp_func(self.detector.run, **kwargs) event = None if hasattr(self.process_detect, "event"): event = self.process_detect.event self.process_detect.start() if event is None: logger.debug("Launched Detector") return for mins in reversed(range(5)): event.wait(60) if event.is_set(): break if mins == 0: raise ValueError("Error initializing Detector") logger.info("Waiting for Detector... Time out in %s minutes", mins) logger.debug("Launched Detector") def detect_faces(self, extract_pass="******"): """ Detect faces from in an image """ logger.debug("Running Detection. Pass: '******'", extract_pass) if self.is_parallel or extract_pass == "align": out_queue = queue_manager.get_queue("align") if not self.is_parallel and extract_pass == "detect": out_queue = queue_manager.get_queue("detect") while True: try: faces = out_queue.get(True, 1) if faces == "EOF": break if isinstance(faces, dict) and faces.get("exception"): pid = faces["exception"][0] t_back = faces["exception"][1].getvalue() err = "Error in child process {}. {}".format(pid, t_back) raise Exception(err) except QueueEmpty: continue yield faces logger.debug("Detection Complete")