class ExtractFaces(Subject): def __init__(self): Subject.__init__(self) self._color = Colors() self._path = PATH() self._serializer = Serializer() self._facesThreads = [] self._faces = [] self._imgfaces = [] self._running = 0 self._total = 0 # =========================================================================== # Function of main # =========================================================================== def run(self): self._color.printing("info", "[LOADING] Quantifying faces...") # Get list of Folder train_paths = glob.glob("IMAGE_DB_RAW/*") # print(train_paths) data = self._format_data(train_paths) self._thread_init(data) self._color.printing("success", "[SUCCESS] Quantifying faces Finished\n") self._launch_detect_face() self._waiting_end_thread() # Saving Images self._saving() # =========================================================================== # Create the Data Frame with Panda # =========================================================================== """ @:parameter train_path = Path from glog (UNIX LIKE) """ def _format_data(self, train_paths): data = pd.DataFrame(columns=['image', 'label', 'name']) for i, train_path in tqdm(enumerate(train_paths)): name = train_path.split("/")[-1] images = glob.glob(train_path + "/*") for image in images: data.loc[len(data)] = [image, i, name] # print(data) return data # =========================================================================== # Get the Notify from DP Observer # =========================================================================== """ @:update """ def update(self, value, message): self._faces.append(value) self._imgfaces.append(message) self._running -= 1 # =========================================================================== # Initialize the list of threads # =========================================================================== """ @:parameter data = DataFrame """ def _thread_init(self, data): total = 0 for img_path in data.image: # self._color.printing("info", "[LOADING] Create Threading {}/{}".format(total + 1, len(data.image))) # print(img_path) # Create the Thread frame = cv2.imread(img_path) self._facesThreads.append(FaceDetector(frame, img_path, self)) total += 1 self._color.printing("success", "[SUCCESS] Create Threading Completed\n") def _waiting_end_thread(self): while self._running > 0: self._color.printing("info", "[WAITING] Waiting the end of Threads...") time.sleep(0.5) self._color.printing("success", "[SUCCESS] Thread Finished !\n") # =========================================================================== # Launch the Threads # =========================================================================== """ @:parameter data = the DataFrame from Panda @:parameter max = The maximum of Threads """ def _launch_detect_face(self, max=15): while self._total < len(self._facesThreads): if self._running <= max: self._facesThreads[self._total].start() self._running += 1 self._total += 1 self._color.printing( "info", "[PROCESSING] Processing image {}/{}".format( self._total, len(self._facesThreads))) else: while self._running == 5: time.sleep(0.1) self._color.printing("success", "[SUCCESS] Processing image completed\n") def _saving(self): os.system("rsync -a " + self._path.IMAGE_DB_RAW + "/* " + self._path.IMAGE_DB) os.system("rm -rf " + self._path.IMAGE_DB_RAW + "/*") # Get list of Folder train_paths = glob.glob("Data/IMAGE_DB/*") data = self._format_data(train_paths) self._color.printing("success", "[SUCCESS] Extraction Completed\n") # print(data) # print(self._faces) self._serializer.saving_data(data) self._serializer.saving_faces(self._faces)
return True else: del path return False def check_file_to_detect(): path = PATH() # print(path.IMAGE_DB_RAW) if len(list(paths.list_images(path.IMAGE_TO_DETECT))) > 0: del path return True else: del path return False if __name__ == "__main__": color = Colors() if check_new_files(): color.printing("info", "[NEW] New Image Detected Run Analyse...\n") fd = ExtractFaces() fd.run() del fd if check_file_to_detect(): color.printing("info", "[NEW] New Image To Detect Run Recognizing...\n") reco = Recognizer() reco.run()
class FaceDetector(Thread, Observer): def __init__(self, frame, img_path, subject): # =============== # Use the Builder # =============== Thread.__init__(self) Observer.__init__(self) self._color = Colors() # ==================== # Register the Subject # ==================== self.register(subject) # ================================================================ # OpenCV DNN supports 2 networks. # 1. FP16 version of the original caffe implementation ( 5.4 MB ) # 2. 8 bit Quantized version using Tensorflow ( 2.7 MB ) # ================================================================ self.DNN = "TF" # ======================================= # Select the Network CAFFE or TensorFlow # ======================================== if self.DNN == "CAFFE": self._modelFile = "Data/Model/res10_300x300_ssd_iter_140000_fp16.caffemodel" self._configFile = "Data/Model/deploy.prototxt" self._net = cv2.dnn.readNetFromCaffe(self._configFile, self._modelFile) else: self._modelFile = "Data/Model/opencv_face_detector_uint8.pb" self._configFile = "Data/Model/opencv_face_detector.pbtxt" self._net = cv2.dnn.readNetFromTensorflow(self._modelFile, self._configFile) # Select the confidence (0 to 1) self.conf_threshold = 0.8 self.faces = frame self._img_path = img_path # =========================================================================== # Override the start Thread # =========================================================================== def run(self): self._detect_face(self.faces) # =========================================================================== # Detect and return faces the face from Frame # =========================================================================== def _detect_face(self, frame): frame_copy = frame.copy() frameHeight = frame_copy.shape[0] frameWidth = frame_copy.shape[1] blob = cv2.dnn.blobFromImage(frame_copy, 1.0, (300, 300), [104, 117, 123], False, False) self._net.setInput(blob) detections = self._net.forward() faces = [] for i in range(detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > self.conf_threshold: x1 = int(detections[0, 0, i, 3] * frameWidth) y1 = int(detections[0, 0, i, 4] * frameHeight) x2 = int(detections[0, 0, i, 5] * frameWidth) y2 = int(detections[0, 0, i, 6] * frameHeight) faces.append([x1, y1, x2, y2]) try: imsave(self._img_path, frame_copy[y1:y2, x1:x2]) except: self._color.printing( "error", "Error write detecting Faces : " + self._img_path) os.system("rm -rf " + self._img_path) finally: pass # print(faces) self.update_observer(faces, "Finished")