Пример #1
0
    def __init__(
        self,
        model_loc: str = "./models",
        persistent_data_loc="data/facial_data.json",
        face_detection_threshold: int = 0.99,
        face_detector: str = "dlib",
    ) -> None:
        """Constructor

        Args:
            model_loc (str, optional): Path where model files are saved. Defaults to "./models".
            persistent_data_loc (str, optional): Path to save the persistence storage file.
                Defaults to 'data/facial_data.json'.
            face_detection_threshold (int, optional): Threshold facial model confidence to consider a detection.
                Defaults to 0.99.
            face_detector (str, optional): Type of face detector to use. Options:
                Dlib-HOG and MMOD, MTCNN, OpenCV CNN. Defaults to 'dlib'.

        Raises:
            ModelFileMissing: Raised when model file is not found
        """
        keypoints_model_path = os.path.join(
            model_loc, FaceRecognition.keypoints_model_path
        )
        face_recog_model_path = os.path.join(
            model_loc, FaceRecognition.face_recog_model_path
        )
        if not (
            path_exists(keypoints_model_path) or path_exists(face_recog_model_path)
        ):
            raise ModelFileMissing
        if face_detector == "opencv":
            self.face_detector = FaceDetectorOpenCV(
                model_loc=model_loc, crop_forehead=True, shrink_ratio=0.2
            )
        elif face_detector == "mtcnn":
            self.face_detector = FaceDetectorMTCNN(crop_forehead=True, shrink_ratio=0.2)
        else:
            self.face_detector = FaceDetectorDlib()
        self.face_detection_threshold = face_detection_threshold

        self.keypoints_detector = dlib.shape_predictor(keypoints_model_path)
        self.face_recognizor = dlib.face_recognition_model_v1(face_recog_model_path)
        self.datastore = FaceDataStore(persistent_data_loc=persistent_data_loc)
Пример #2
0
 def register_face_path(self, img_path: str, name: str) -> None:
     if not path_exists(img_path):
         raise PathNotFound
     try:
         img = cv2.imread(img_path)
         facial_data = self.face_recognizer.register_face(
             image=convert_to_rgb(img), name=name)
         if facial_data:
             logger.info("Face registered...")
             return True
         return False
     except Exception as exc:
         raise exc
    def get_all_data(self) -> List:
        """Returns a list of facial data of all the
        registered users from cache.

        Returns:
            List[Dict]: [description]
        """
        # Data load will fail incase the file doesn't exist
        if not path_exists(self.db_loc):
            raise DatabaseFileNotFound
        try:
            # load the existing data
            with open(self.db_loc, "r") as f:
                data = json.load(f)
                # convert the list to tuple to keep
                # consistency across
                return self.sanitize_data(data)
        except Exception as exc:
            raise exc
    def add_data(self, face_data: Dict):
        """Adds facial data to persistent DB.

        Args:
            face_data (Dict): [description]
        """
        data = []
        # check if the db exists, otherwise create one
        base_path, filename = os.path.split(self.db_loc)

        if not path_exists(base_path):
            logger.info("DB path doesn't exist! Attempting path creation...")
            os.makedirs(base_path)
        if os.path.exists(self.db_loc):
            # load the existing data
            data = self.get_all_data()
        try:
            # Add the new data and save to disk
            data.append(face_data)
            self.save_data(data=data)
            logger.info("Data saved to DB...")
        except Exception as exc:
            raise exc
Пример #5
0
    def recognize_face_video(
        self,
        video_path: str = None,
        detection_interval: int = 15,
        save_output: bool = False,
        preview: bool = False,
        output_path: str = "data/output.mp4",
        resize_scale: float = 0.5,
        verbose: bool = True,
    ) -> None:

        if video_path is None:
            # If no video source is given, try
            # switching to webcam
            video_path = 0
        elif not path_exists(video_path):
            raise FileNotFoundError

        cap, video_writer = None, None

        try:
            cap = cv2.VideoCapture(video_path)
            # To save the video file, get the opencv video writer
            video_writer = get_video_writer(cap, output_path)
            frame_num = 1
            matches, name, match_dist = [], None, None

            t1 = time.time()
            logger.info("Enter q to exit...")

            while True:
                status, frame = cap.read()
                if not status:
                    break
                try:
                    # Flip webcam feed so that it looks mirrored
                    if video_path == 0:
                        frame = cv2.flip(frame, 2)

                    if frame_num % detection_interval == 0:
                        # Scale down the image to increase model
                        # inference time.
                        smaller_frame = convert_to_rgb(
                            cv2.resize(frame, (0, 0), fx=resize_scale, fy=resize_scale)
                        )
                        # Detect faces
                        matches = self.face_recognizer.recognize_faces(
                            image=smaller_frame, threshold=0.6, bboxes=None
                        )
                    if verbose:
                        self.annotate_facial_data(matches, frame, resize_scale)
                    if save_output:
                        video_writer.write(frame)
                    if preview:
                        cv2.imshow("Preview", cv2.resize(frame, (680, 480)))

                    key = cv2.waitKey(1) & 0xFF
                    if key == ord("q"):
                        break
                except Exception:
                    pass
                frame_num += 1

            t2 = time.time()
            logger.info("Time:{}".format((t2 - t1) / 60))
            logger.info("Total frames: {}".format(frame_num))
            logger.info("Time per frame: {}".format((t2 - t1) / frame_num))

        except Exception as exc:
            raise exc
        finally:
            cv2.destroyAllWindows()
            cap.release()
            video_writer.release()
Пример #6
0
 def teardown_method(self):
     if path_exists(self.persistent_db_loc):
         os.remove(self.persistent_db_loc)