├── .github └── FUNDING.yml ├── .gitignore ├── FaceDetect ├── __init__.py └── facedetect.py ├── LICENSE.md ├── README.md ├── main.py ├── main_detection_image.py ├── main_detection_webcam.py ├── main_detection_webcam_extended.py ├── main_faceextract_image.py ├── main_facefeatures_image.py ├── main_recognize_image.py ├── main_recognize_video.py ├── outputs ├── banner.png ├── main_detection_image_output.png ├── main_detection_webcam_output.png ├── main_faceextract_image_output.png ├── main_facefeatures_image_output.png ├── main_recognize_image_output.png └── main_recognize_video_output.png └── resources ├── freevideo.mp4 ├── people.jpg ├── person1.png ├── person2.png └── person3.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ['DoryAzar'] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/__pycache__ 3 | **/__pycache__/** 4 | __pycache__ 5 | .DS_Store? 6 | .DS_Store 7 | .idea 8 | venv 9 | staging 10 | -------------------------------------------------------------------------------- /FaceDetect/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["facedetect"] -------------------------------------------------------------------------------- /FaceDetect/facedetect.py: -------------------------------------------------------------------------------- 1 | # facedetect.py 2 | # 3 | # FaceDetect framework that provides tools and features to detect and recognize faces in different media 4 | # 5 | # Usage: 6 | # - Import FaceDetect into your python script 7 | # - Instantiate a FaceDetect object 8 | 9 | # Default Face Detection: 10 | # - Call the start() method (default settings will be run) 11 | # - This will automatically start face detection 12 | # 13 | # Customize Face Detection: 14 | # - Pass a settings dictionary to the FaceDetect constructor 15 | # - Setting capabilities: 16 | # * mode: image or video (default) 17 | # * custom: False (default). Set to True when the FaceDetect class is extended 18 | # * method: call native callback methods during detection or bypass with a custom method 19 | # * draw: draws the detection on the canvas if set to True (default) 20 | # * print: prints the face locations and labels on the console 21 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 22 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 23 | # 24 | # Dory Azar 25 | # December 2020 26 | 27 | import os 28 | import cv2 29 | from PIL import Image 30 | import numpy 31 | import face_recognition 32 | 33 | 34 | class FaceDetect: 35 | """ FaceDetect framework that provides tools and features to detect and recognize faces in different media """ 36 | 37 | # Defining constant settings 38 | FACE_FEATURES = ['chin', 'left_eye', 'right_eye', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', 'nose_tip', 39 | 'top_lip', 'bottom_lip'] 40 | DEFAULT_SETTINGS = { 41 | 'mode': 'video', 42 | 'draw': True, 43 | 'custom': False, 44 | 'method': 'detect', 45 | 'face-extraction': False, 46 | 'print': True, 47 | 'face-features': [], 48 | 'known-faces': {} 49 | } 50 | ACCEPTED_VIDEO_FORMAT = ['avi', 'mp4', 'mov'] 51 | ACCEPTED_IMAGE_FORMAT = ['jpeg', 'jpg', 'gif', 'png'] 52 | 53 | def __init__(self, settings=None): 54 | """ Initializes the Face Detect framework""" 55 | 56 | # Initialize default properties 57 | self.canvas = cv2 58 | self.stream = None 59 | self.settings = self.DEFAULT_SETTINGS 60 | 61 | # Initialize face detection and recognition properties 62 | self.frame = None # The detection frame 63 | self.known_faces_encodings = [] # Face Encodings of known faces 64 | self.known_faces_labels = [] # Face Labels of known faces 65 | self.face_labels = [] # Face labels 66 | self.detections = None # Face detection results 67 | self.face_landmarks = None # Face landmarks 68 | self.face_extracts = [] # Collection of face extracted face images 69 | 70 | # Populating setting from input (overrides are possible) 71 | if settings: 72 | for setting in settings: 73 | 74 | # Sanitize the key 75 | sanitized_setting = setting.lower() 76 | 77 | # Get the value and sanitize if string, otherwise take as is 78 | val = settings.get(setting) 79 | val = val.lower().strip() if type(val) is str else val 80 | 81 | # Set the settings to the sanitized keys and values 82 | self.settings[sanitized_setting] = val if type(val) is bool or val else self.settings[sanitized_setting] 83 | 84 | #################################################### 85 | # Public methods for face detection and recognition 86 | #################################################### 87 | 88 | def start(self, media_path=''): 89 | """ Interface starter that starts either an image app or a video/webcam app""" 90 | 91 | try: 92 | 93 | # Execute before calling engine 94 | self.__preload() 95 | 96 | # If mode is image than run static detection mode 97 | if self.__get_setting('mode') == 'image': 98 | self.__detect_static(media_path) 99 | 100 | # if mode is video than run streaming mode 101 | else: 102 | self.__detect_stream(media_path) 103 | 104 | # Raise TypeError exceptions 105 | except TypeError as error: 106 | raise Exception(error) 107 | 108 | # Raise exceptions caused by canvas (cv2) and raise as FaceDetect Exception 109 | except self.canvas.error: 110 | raise Exception("There was a problem starting the FaceDetect canvas") 111 | 112 | # Any other exception classify as data runtime issue and raise as FaceDetect Exception 113 | except Exception as error: 114 | raise Exception(error) 115 | 116 | #################################################### 117 | # Detection mechanisms 118 | # - Static: For images 119 | # - Stream: For video and webcam 120 | #################################################### 121 | 122 | def __detect_static(self, media_path): 123 | """ Loads an image for face detection and recognition""" 124 | 125 | # Check if valid image type 126 | if not media_path or not self.__is_valid_media('image', media_path): 127 | raise Exception('Provide a valid image file') 128 | 129 | # Load the image in cv2 for display 130 | self.frame = self.canvas.imread(media_path) 131 | 132 | # Load the image in face_recognition for calculations 133 | self.stream = face_recognition.load_image_file(media_path) 134 | 135 | # Start the detection 136 | self.__detect() 137 | 138 | # Call a native or custom callback method 139 | self.__callback() 140 | 141 | # Execute Settings if there are detections 142 | if self.detections: 143 | self.__execute_setting() 144 | 145 | # Open the cv2 media player 146 | while True: 147 | 148 | # Display the final result 149 | self.canvas.imshow('FaceDetect', self.frame) 150 | 151 | # Close when 'q' is pressed 152 | if self.canvas.waitKey(1) & 0xFF == ord('q'): 153 | return 154 | 155 | def __detect_stream(self, media_path=''): 156 | """ Starts the video or the webcam for face detection and recognition""" 157 | 158 | # Get the media stream 159 | self.__capture(media_path) 160 | 161 | # Keep displaying as long as stream is open 162 | while self.stream and self.stream.isOpened(): 163 | 164 | ret, self.frame = self.stream.read() 165 | if ret: 166 | # Start the detection 167 | self.__detect() 168 | 169 | # Call a native or custom callback method 170 | self.__callback() 171 | 172 | # Execute Settings if there are detections 173 | if self.detections: 174 | self.__execute_setting() 175 | 176 | self.canvas.imshow('FaceDetect', self.frame) 177 | 178 | # Close when 'q' is pressed 179 | if self.canvas.waitKey(1) & 0xFF == ord('q'): 180 | return 181 | 182 | #################################################### 183 | # FaceDetect Flow Methods 184 | #################################################### 185 | 186 | def __preload(self): 187 | """ Assesses the provided (or default) settings and preloads features """ 188 | 189 | # With recognition activated 190 | if self.__get_setting('method') == 'recognize': 191 | 192 | # Get the known face files provided 193 | known_faces = self.__get_setting('known-faces') 194 | known_faces = known_faces if type(known_faces) is dict else {} 195 | 196 | # Get the list of tuples from the setting input 197 | known_faces = [(known_face_label, image_path) for known_face_label, image_path in known_faces.items()] 198 | 199 | # Iterate through each setting input and load the images 200 | for (known_face_label, image_path) in known_faces: 201 | try: 202 | loaded_image = face_recognition.load_image_file(image_path) 203 | self.known_faces_encodings.append(face_recognition.face_encodings(loaded_image)[0]) 204 | self.known_faces_labels.append(known_face_label) 205 | 206 | # Raise FileNotFoundError onto a FaceDetect Exception 207 | except FileNotFoundError: 208 | raise Exception("Some of the image paths provided are invalid") 209 | 210 | # Raise any other Exception on a FaceDetect Exception 211 | except Exception: 212 | raise Exception("We were not able to start face recognition") 213 | 214 | def __detect(self): 215 | """ Detects faces in the media provided and calls on drawing or printing locations out """ 216 | 217 | # Initialize variables 218 | mode = self.__get_setting('mode') 219 | self.face_labels = [] 220 | 221 | # Resize frame of video to 1/4 size for faster face detections 222 | small_frame = self.canvas.resize(self.frame, (0, 0), fx=0.25, fy=0.25) 223 | 224 | # If it's video, convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) 225 | # If it is an image take the stream 226 | rgb_small_frame = small_frame[:, :, ::-1] if mode != 'image' else self.stream 227 | 228 | # Find all the faces in the frame and their encodings 229 | self.face_locations = face_recognition.face_locations(rgb_small_frame) 230 | self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations) 231 | 232 | # Find all the faces landmarks 233 | self.face_landmarks = face_recognition.face_landmarks(rgb_small_frame) 234 | # Resize the data to match original size 235 | if mode != 'image': 236 | 237 | # Resize data to bring to original size 238 | self.face_locations = [(top*4, bottom*4, left*4, right*4) for (top, bottom, left, right) 239 | in self.face_locations] 240 | 241 | # Resize the data to bring to original size 242 | for landmark in self.face_landmarks: 243 | for feature in landmark: 244 | landmark[feature] = [(x * 4, y * 4) for (x, y) in landmark[feature]] 245 | 246 | # Iterate through the detected face locations and append an unknown label 247 | for count, location in enumerate(self.face_locations): 248 | label = "Face " + str(count + 1) 249 | self.face_labels.append(label) 250 | 251 | # Upon face detection 252 | self.__generate_detections() 253 | 254 | def __callback(self): 255 | """ Callback method that will run at every fetching interval and that will execute 256 | a method determined in the settings """ 257 | 258 | method = self.settings['method'] if self.__get_setting('method') else None 259 | custom = self.settings['custom'] if self.__get_setting('custom') else None 260 | 261 | try: 262 | if method and method != 'detect': 263 | self.__getattribute__('_FaceDetect__' + method)() 264 | 265 | if type(custom) is str: 266 | self.__getattribute__(custom)() 267 | 268 | # Execute method if it exists 269 | # try: 270 | # if method and self.__get_setting('custom'): 271 | # self.__getattribute__(method)() 272 | # elif method and method != 'detect': 273 | # self.__getattribute__('_FaceDetect__' + method)() 274 | 275 | # Generate exception if the method does not exist 276 | except AttributeError: 277 | raise Exception("The provided method does not exist") 278 | 279 | def __execute_setting(self): 280 | """ Assesses the provided (or default) settings and executes the detection features """ 281 | 282 | # If there are detections print and drawing is off, print them off 283 | if self.__get_setting('print'): 284 | print(self) 285 | 286 | # Draw detections if they are available and the setting is on 287 | if self.__get_setting('draw'): 288 | self.__draw_detections() 289 | 290 | # Extract face images 291 | if self.__get_setting('mode') == 'image' and self.__get_setting('face-extraction'): 292 | self.__extract_face_images() 293 | 294 | # Draw Face Landmarks 295 | 296 | # Get the face-features setting 297 | features = self.__get_setting('face-features') 298 | 299 | # Force to an empty list if 300 | features = [] if type(features) is not list else list(map(str.lower, features)) 301 | 302 | # Default features to be drawn unless specified 303 | features = self.FACE_FEATURES if 'face' in features else features 304 | 305 | if self.face_landmarks and features: 306 | self.__draw_landmarks(features) 307 | 308 | def __recognize(self): 309 | """ Compares faces to a known set of images and identifies them in the canvas """ 310 | 311 | if self.face_encodings: 312 | 313 | # Clear the face labels to prepare for recognition 314 | self.face_labels = [] 315 | 316 | # Iterate through the different face_encodings identified 317 | for face_encoding in self.face_encodings: 318 | 319 | # Default label is unknown 320 | label = 'Unknown' 321 | 322 | # Compare the face encodings and get all the potential matches 323 | face_matches = face_recognition.compare_faces(self.known_faces_encodings, face_encoding) 324 | 325 | # Find the best match based on the face distances 326 | face_distances = face_recognition.face_distance(self.known_faces_encodings, face_encoding) 327 | best_match = int(numpy.argmin(face_distances)) 328 | 329 | # When a best match use the label provided as the label 330 | if face_matches[best_match]: 331 | label = self.known_faces_labels[best_match] 332 | 333 | # Append the face label to the collection 334 | self.face_labels.append(label) 335 | 336 | # Update the detections account for the new names 337 | self.__generate_detections() 338 | 339 | #################################################### 340 | # OpenCV & PIL Utility methods 341 | #################################################### 342 | 343 | def __capture(self, media_input=''): 344 | """ Captures video or webcam using OpenCV """ 345 | 346 | # If invalid media video, it will open the video cam by default 347 | media_input = media_input if media_input and self.__is_valid_media('video', media_input) else 0 348 | self.stream = self.canvas.VideoCapture(media_input) 349 | 350 | def __draw_detections(self): 351 | """ Draws the rectangles over the detections """ 352 | 353 | # Check if there is recognition 354 | is_recognize = self.__get_setting('method') == 'recognize' 355 | 356 | # Iterate through the zipped tuples of locations and labels 357 | for (top, right, bottom, left), label in self.detections: 358 | 359 | # Define the colors based on whether or not recognition is activated 360 | b = 255 if not is_recognize else 0 361 | g = 255 if is_recognize and label != 'Unknown' else 0 362 | r = 255 if is_recognize and label == 'Unknown' else 0 363 | 364 | # Draw a box around the face 365 | self.canvas.rectangle(self.frame, (left, top), (right, bottom), (b, g, r), 2) 366 | 367 | # Draw a label with a label below the face 368 | self.canvas.rectangle(self.frame, (left, bottom - 35), (right, bottom), (b, g, r), self.canvas.FILLED) 369 | font = self.canvas.FONT_HERSHEY_DUPLEX 370 | self.canvas.putText(self.frame, label, (left + 6, bottom - 6), font, 0.9, (255, 255, 255), 1) 371 | 372 | def __extract_face_images(self): 373 | """ Extracts individual face images from image. Works in mode image only """ 374 | 375 | # Iterate through the zipped tuples of locations and labels 376 | for (top, right, bottom, left), label in self.detections: 377 | # frame the detected face 378 | face_image = self.stream[top:bottom, left:right] 379 | 380 | # Change the image to PIL image for manipulation 381 | pil_image = Image.fromarray(face_image) 382 | 383 | # Save the extracted PIL images 384 | self.face_extracts.append(pil_image) 385 | 386 | # Display the pil image 387 | pil_image.show() 388 | 389 | def __draw_landmarks(self, features=None): 390 | """ Draws the facial features of a detected face """ 391 | 392 | # Iterate through the detected face landmarks 393 | for landmark in self.face_landmarks: 394 | 395 | # Iterate through the features of each face 396 | for feature in landmark: 397 | 398 | # Draw them as closed lines on the canvas except the chin will be an open line 399 | if features and feature in features: 400 | 401 | # Draw closed lines around the feature unless it's the chin 402 | points = numpy.array(landmark[feature]) 403 | self.canvas.polylines(self.frame, [points], feature != 'chin', (255, 0, 0), 2) 404 | 405 | #################################################### 406 | # Utility methods 407 | #################################################### 408 | 409 | def __str__(self): 410 | """ Stringify the object by exposing the detections and recognitions""" 411 | results = '' 412 | for detection in self.detections: 413 | results = results + '(%s, %s)' % (detection[0], detection[1]) 414 | return results 415 | 416 | def __is_valid_media(self, media_type, media_path): 417 | """ Validates if a media path is of an acceptable format """ 418 | 419 | # Get the file name and extension 420 | file_name, file_extension = os.path.splitext(media_path) 421 | 422 | # Sanitize the file extension to get rid of the . 423 | file_extension = file_extension.strip('.') 424 | 425 | # Check if it is an accepted video format 426 | if media_type.lower() == 'video' and file_extension.lower() in self.ACCEPTED_VIDEO_FORMAT: 427 | return True 428 | 429 | # Check if it is an accepted image format 430 | elif media_type.lower() == 'image' and file_extension.lower() in self.ACCEPTED_IMAGE_FORMAT: 431 | return True 432 | return False 433 | 434 | def __get_setting(self, key): 435 | """ Getter to get a value from the settings """ 436 | if key.lower() in self.settings and self.settings[key]: 437 | return self.settings[key] 438 | return None 439 | 440 | def __generate_detections(self): 441 | """ Generates and updates the detections """ 442 | 443 | # Condense the face locations and labels into tuples 444 | self.detections = zip(self.face_locations, self.face_labels) if self.face_locations else None 445 | 446 | # Format onto tuples if there are self detections 447 | if self.detections: 448 | self.detections = [(detection[0], detection[1]) for detection in self.detections] 449 | 450 | def __end(self): 451 | """ Ends the show """ 452 | if self.stream: 453 | self.stream.release() 454 | 455 | if self.canvas: 456 | self.canvas.destroyAllWindows() 457 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Released under MIT License 2 | 3 | Copyright (c) 2020 Dory Azar. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FaceDetect: Face detection & recognition 2 | + By: Dory Azar 3 | 4 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/banner.png) 5 | 6 |
7 | 8 | 9 | ## Content 10 | 11 | + [Project Status](https://github.com/DoryAzar/FaceDetectPython#project-status) 12 | + [Project Synopsis](https://github.com/DoryAzar/FaceDetectPython#project-synopsis) 13 | + [Resources](https://github.com/DoryAzar/FaceDetectPython#resources) 14 | + [Let's get started](https://github.com/DoryAzar/FaceDetectPython#lets-get-started) 15 | + [Let's get through the basics](https://github.com/DoryAzar/FaceDetectPython#lets-get-through-the-basics) 16 | + [Let's have some fun](https://github.com/DoryAzar/FaceDetectPython#lets-have-some-fun) 17 | + [Known Issues](https://github.com/DoryAzar/FaceDetectPython#known-issues) 18 | 19 |
20 | 21 | ## Project Status 22 | 23 | **All the features described below have been implemented for this project. 24 | The core logic that we created can be found in [FaceDetect > facedetect.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/FaceDetect/facedetect.py)** 25 | 26 | + The foundation for the framework has been completed. FaceDetect has been implemented and packaged as a class that just needs to be imported for usage. 27 | + The framework allows reading images, videos and webcam streams 28 | + The framework allows for customization in 2 ways: 29 | 1. By providing a settings dictionary to the constructor to adjust the native features 30 | 2. By extending the FaceDetect class to create more elaborate features 31 | + Face Detection has been implemented for all 3 media. The faces can now be detected in images, videos and live webcams 32 | + Ability to either draw rectangles around the detections or print them to the console has been implemented 33 | + Ability to extract detected faces into separate individual images has been implemented 34 | + Ability to detect facial features and draw them on top of either medium has been implemented 35 | + Ability to recognize faces in a video, webcam or image based on known faces provided as image inputs 36 | + Ability to identify recognized faces visually in a video, webcam or image 37 | + Ability to access detection and recognition data through extensibility for use in other programs 38 | + All the features are documented in the README 39 | 40 | 41 |
42 | 43 | ## Project Synopsis 44 | 45 | Detecting human faces and recognizing faces and facial expressions have always been an area of interest for different applications such as games, utilities and even security. With the advancement of machine learning, the techniques of detection and recognition have become more accurate and precise than ever before. 46 | 47 | However, machine learning remains a relatively complex field that could feel intimidating or inaccessible to many of us. Luckily, in the last couple of years, several organizations and open source communities have been developing tools and libraries that help abstract the complex mathematical algorithms in order to encourage developers to easily create learning models and train them using any programming languages. 48 | 49 | As part of this project, we will create a Face Detection framework in Python built on top of the work of several open source projects and models with the hope to reduce the entry barrier for developers and to encourage them to focus more on developing innovative applications that make use of face detection and recognition. 50 | 51 | Artificial Intelligence (AI) and Machine Learning in particular don't have to be difficult and we hope that the FaceDetect framework gives developers the means to include face detection and recognition in a seamless way in their applications. 52 | 53 | 54 | The framework aims to provide an easy way for developers to detect faces, facial features and recognize faces from an image, a video or a live cam stream. 55 | 56 | Here are some of the features that we are considering. We will try to do as many as time allows: 57 | + Detect faces in an image, video or live webcam 58 | + Extract detected faces in separate images from the main image 59 | + Detect and draw facial features (eyes, noses, ears etc.) 60 | + Recognize previously saved faces in an image, video or live webcam 61 | + Generate live data from detections that can be shared and used in other programs (extensibility) 62 | 63 |
64 | 65 | ## Resources 66 | 67 | + **Face Recognition by Adam Geitgey** 68 | 69 | The face-recognition python library was created by Adam Geitgey. It uses deep learning for face detection and recognition using the Python **dlib** library. 70 | 71 | [Face Recognition Documentation](https://face-recognition.readthedocs.io/en/latest/index.html) 72 | 73 | + **Open CV**: 74 | 75 | While Open CV is a great library to implement face detection and recognition, it will mainly be used in this project for capturing a stream from the webcam. 76 | 77 | [Open CV Documentation](https://docs.opencv.org/master/) 78 | 79 |
80 | 81 | ## Let's get started 82 | 83 | ### Environment 84 | 85 | #### Python 3.8+ - Anaconda installation 86 | 87 | One of the easiest ways to install Python is to use packaged distributions. Anaconda is one such distribution. 88 | If you are new to Python, we recommend that you install the Anaconda distribution. 89 | 90 | [Download Anaconda](https://www.anaconda.com/download/) 91 | 92 | If you already have Anaconda installed, all you need to do is to update it and make sure that you are using the latest version 93 | of Python. You can do this from the command line or the terminal: 94 | ``` 95 | conda update conda 96 | conda update anaconda 97 | conda update python 98 | ``` 99 | 100 | #### Recommended Editor (IDE) 101 | 102 | You can use any development environment or editor that you are comfortable with. In this course, we will be using PyCharm. 103 | You can download the free Community Edition version. 104 | 105 | [Download PyCharm](https://www.jetbrains.com/pycharm/download/) 106 | 107 | ### Requirements 108 | 109 | There are several libraries and packages needed to run this program successfully. We will provide the instructions on how to download on Mac/Linux machines: 110 | 111 | #### cmake 112 | 113 | In order to successfully install and build all the dependencies locally, CMake needs to be installed for python 114 | ```bash 115 | // Use Homebrew to install Cmake 116 | brew install cmake 117 | ``` 118 | #### dlib 119 | 120 | C++ library that provides machine learning tools to be used in several other languages such as python. 121 | ``` 122 | // use pip to install dlib 123 | python -m pip install dlib 124 | ``` 125 | #### face-recognition 126 | 127 | library built on top of dlib that facilitates the usage of face detection and face recognition 128 | ``` 129 | // use pip to install face-recognition 130 | pip install face-recognition 131 | ``` 132 | #### Open CV 133 | 134 | Open source computer vision library that provides machine AI vision 135 | ``` 136 | //use pip to install opencv 137 | pip install opencv-python 138 | ``` 139 | 140 | #### PIL: Python Imaging Library 141 | 142 | PIL is a native Python library. It is used in this project for image manipulations. 143 | 144 |
145 | 146 | #### Numpy 147 | 148 | Numpy is a native Python library. It is used for multi-dimensional array manipulations. It is used in this project for image array manipulations and matrices conversions 149 | 150 |
151 | 152 | ### Installation 153 | 154 | You can install the FaceDetect application from github 155 | ``` 156 | git clone https://github.com/DoryAzar/FaceDetectPython 157 | ``` 158 | 159 | 160 | ### FaceDetect Structure 161 | 162 | The distribution comes with several scripts that are explained herewith: 163 | 164 | + **FaceDetect > facedetect.py**: `facedetect.py` is the core logic that we created that makes all the magic happen. 165 | The FaceDetect class and all its features and functionalities are implemented in this script. The script is open source 166 | and can be modified and adjusted as needed within the boundaries of an MIT license. 167 | 168 | + **main scripts**: In the root folder of the distribution, there are several scripts that start with `main...`. 169 | This series of scripts are examples of how FaceDetect is used in different situations. 170 | 171 | + **resources**: The `resources` folder contains example images to test out face detection and recognition. 172 | They are used by the main scripts. 173 | 174 | + **outputs**: The `outputs` folder contains screenshots of the example programs in action used for documentation purposes 175 | 176 |
177 | 178 | 179 | ### Testing the installation 180 | 181 | The `main.py` script provided with the distribution provides an initial boiler plate main to test out the installation. 182 | It can be run either in the terminal or using Anaconda PyCharm 183 | 184 | + Using the terminal 185 | 186 | ``` 187 | python main.py 188 | ``` 189 | + Using Anaconda PyCharm 190 | 191 | - After installing the dependencies, set up a new Anaconda project with a Python 3.8 Virtual Environment. 192 | - Make sure to create a fresh new virtual environment in the folder containing the FaceDetect distribution 193 | - Run `main.py` 194 | 195 | 196 |
197 | 198 | 199 | 200 | 201 | ## Let's get through the basics 202 | 203 | ### Understanding Face detection and recognition 204 | 205 | Detection and Recognition are two different concepts. While both use machine learning and neural networks in particular, they achieve different things. Understanding the distinction is key to better understanding how the FaceDetect framework operates. 206 | 207 | + **Face detection**: Face detection is about identifying a human face among all other "things" perceived through either an image or a video. So for example, a picture or a video can have people, objects, scenery etc... Face detection is when the system is capable of pointing out the presence of a human face among all those other things. 208 | 209 | + **Face recognition**: Recognition is about identifying who the human face is among all other faces and things perceived. So for example, Face recognition is when the system is capable of pointing out "Flash" among all other superheroes in a picture or a video. 210 | 211 |
212 | 213 | ### Understanding the framework 214 | 215 | FaceDetect relies on an important principle: "First you detect then you do something with the detections". 216 | What we do with the detections is really what this framework is all about. 217 | On one hand, it provides cool native features such as drawing rectangles around them, labeling them, recognizing the faces etc. 218 | On the other, it provides a way to extend its capabilities by writing custom features 219 | 220 | 221 | #### Getting Started with FaceDetect 222 | 223 | 1. Start by creating a new python script file in the root of the distribution folder FaceDetectPython (similarly to main.py that is provided with the distribution) 224 | 2. The first thing that you need to do is to import the FaceDetect package: 225 | 226 | ```python 227 | 228 | from FaceDetect.facedetect import FaceDetect 229 | 230 | ``` 231 | 232 | 3. Instantiate a FaceDetect object. A `settings` dictionary can be passed to the constructor to use different features of FaceDetect. Initially, we will not pass any to run FaceDetect in its default settings. 233 | 234 | ```python 235 | 236 | # Instantiate a FaceDetect with the default settings 237 | facedetector = FaceDetect() 238 | 239 | 4. Start the detections 240 | 241 | ```python 242 | try: 243 | # When the start method is not given an image or video path, it starts the webcam 244 | # For Image file: facedetector.start('') 245 | # For Video: facedetector.start('') 246 | # Press 'q' to exit 247 | facedetector.start() 248 | 249 | 250 | # FaceDetect always generates a FaceDetect Exception 251 | except Exception as error: 252 | print(error) 253 | 254 | ``` 255 | 5. This will start a live stream from a webcam and human faces will be highlighted in the live stream with a blue rectangle surrounding them. 256 | This code can be found in the `main.py` script that is in the distribution 257 | 258 | We will explore more capabilities in the `Let's have some fun` section 259 | 260 | 261 |
262 | 263 | #### Personalized Settings 264 | 265 | FaceDetect gives you the flexibility to control its features through the use of a `settings` dictionary that can be passed to the constructor. 266 | 267 | ```python 268 | 269 | facedetector = FaceDetect({'setting1':'value1', 'settings2': 'value2' # etc...}) 270 | 271 | ``` 272 | Here is a list of all the settings and their potential values: 273 | 274 | ```python 275 | 'mode': 'video' # Specifies if the input for detections is video (default) or image. Webcam is mode video 276 | 277 | 'draw': True # Specifies whether or not the face detections should be drawn on the image or video. If set to False, nothing is displayed but detections are printed out in the console 278 | 279 | 'custom': '' # If you wish to extend the FaceDetect class, specify the method that it needs to execute 280 | 281 | 'method': 'detect' # detect (default) to run detections. 'recognize' to run face recognition 282 | 283 | 'print': True # Prints the face locations and labels on the console. Set to False to disable 284 | 285 | 'face-extraction': False # Extracts captures of the faces into their own images. Applicable only to mode image 286 | 287 | 'face-features': [] # Default no face features will be drawn. Specify what face features to draw in a list/array 288 | # Possible values: 'face' (for the whole face), 'chin', 'left_eye', 'right_eye', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', 'nose_tip', 'top_lip', 'bottom_lip' 289 | 290 | 'known-faces': {} # Setting need for facial recognition when 'method' is set to 'recognize' 291 | # It is a dictionary of face labels and image paths associated. 292 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 293 | ``` 294 | 295 | 296 |
297 | 298 | 299 | #### Extending the capabilities of FaceDetect 300 | 301 | FaceDetect provides you with a way to extend its capabilities by implementing your own code on top of the package. 302 | In order to do that you will need to extend the FaceDetect class. 303 | 304 | 1. Create a new script file in the FaceDetectPython root folder 305 | 2. Import the FaceDetect package: 306 | 307 | ```python 308 | 309 | from FaceDetect.facedetect import FaceDetect 310 | 311 | ``` 312 | 3. Create a class that extends FaceDetect. That class extends FaceDetect and inherits all of its properties and methods. You can add additional methods and properties. 313 | ```python 314 | class MyDetector(FaceDetect): 315 | 316 | # example of a method that print the detections property from FaceDetect 317 | def main(self): 318 | print(self.detections) 319 | 320 | ``` 321 | 4. Instantiate an object of this created class 322 | ```python 323 | 324 | # Pass the name of the custom method to execute at every detection cycle 325 | my_detector = MyDetector({'custom': , 'method': 'detect' }) 326 | 327 | ``` 328 | 5. Start the detections 329 | 330 | ```python 331 | try: 332 | facedetector.start() 333 | 334 | # FaceDetect always generates a FaceDetect Exception 335 | except Exception as error: 336 | print(error) 337 | 338 | ``` 339 | 340 | 6. This will start a live stream from a webcam and human faces will be highlighted in the live stream with a blue rectangle surrounding them. 341 | On top of this, the code in the `main` function will be executed iteratively with every detection cycle. 342 | This code can be found in the `main_detect_webcam_extended.py` script that is in the distribution. 343 | 344 |
345 | 346 | #### FaceDetect Properties for extensibility 347 | 348 | Extending FaceDetect gives access to the methods and properties of the FaceDetect object. 349 | The following properties give access to real-time computations generated by the detection and recognition algorithm that could be used by the extended program. 350 | 351 | ```python 352 | 353 | canvas # Access to the canvas that can be drawn on 354 | stream # If it is a video or a webcam, it provides access to the video stream. If it is an image it gives access to the image array 355 | settings # Access to the applied settings 356 | frame # Access to the capture frame from the stream if it is a video or a webcam 357 | known_faces_encodings # Face Encodings of known faces 358 | known_faces_labels # Face Labels of known faces 359 | face_locations # Access to the locations of the faces detected 360 | face_encodings # Access to face encodings / face signature 361 | face_labels # Access to face labels 362 | detections # Access to zipped version of (face_locations, label) 363 | face_landmarks # Access to face feature landmarks 364 | face_extracts # Access to face extracted face image arrays 365 | 366 | ``` 367 | 368 |
369 | 370 | 371 | ## Let's have some fun 372 | 373 | In this section, we will explore all the features that we developed as part of this project and illustrate them through examples. 374 | The complete codes for all the examples are provided as part of the distributions. They all start with `main...` 375 | and they are located in the root folder. 376 | 377 | Let's remember that the goal of the FaceDetect framework is to make it easy for novice developers to detect and recognize faces. 378 | You will notice that many of the features are executed in a few lines of code. 379 | 380 | **When you run the examples, an image or video canva opens up. You need to press 'q' on your keyboard to quit or you could just interrupt the program.** 381 | 382 | ### 1. Detect faces in an image 383 | 384 | In this first example, we will provide an image to FaceDetect and it will draw rectangles around the faces it finds in 385 | the image. 386 | 387 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_detection_image_output.png) 388 | 389 | ```python 390 | 391 | # Tell FaceDetect to use mode image 392 | facedetector = FaceDetect({'mode': 'image'}) 393 | 394 | # Tell FaceDetect to start detections on a desired image 395 | try: 396 | facedetector.start('resources/people.jpg') 397 | except Exception as error: 398 | print(error) 399 | 400 | ``` 401 | 402 | > The complete code can be found in [main_detect_image.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_detection_image.py) 403 | 404 |
405 | 406 | ### 2. Detect faces in a video or a webcam 407 | 408 | FaceDetect also allows you to detect faces in videos or live webcams. Both these modalities are video streams 409 | and are initialized in the same way. The only difference is that a video file needs to be provided if the desire is to detect faces 410 | in a pre-recorded video. 411 | 412 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_detection_webcam_output.png) 413 | 414 | ```python 415 | 416 | # FaceDetect can be initialized in its default settings. It will run in mode video by default 417 | facedetector = FaceDetect() # {'mode': 'video'} is the default setting 418 | try: 419 | facedetector.start() # webcam 420 | # facedetector.start('') for video 421 | 422 | except Exception as error: 423 | print(error) 424 | 425 | ``` 426 | 427 | > The complete code can be found in [main_detect_webcam.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_detection_webcam.py) 428 | 429 | 430 |
431 | 432 | ### 3. Detection settings 433 | 434 | Upon detection, FaceDetect draws rectangles around the detected faces in the canvas and prints the faces locations in the console (terminal or IDE console). 435 | You can turn these settings: 436 | 437 | ```python 438 | 439 | # Set draw and print to False 440 | facedetect = FaceDetect({'draw': False, 'print': False}) 441 | 442 | ``` 443 | 444 |
445 | 446 | ### 4. Draw facial features on top of detected faces 447 | 448 | FaceDetect allows you to draw facial features on top of detected faces in an image, video or webcam in simple lines of code. 449 | 450 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_facefeatures_image_output.png) 451 | 452 | ```python 453 | 454 | facedetector = FaceDetect({'mode': 'image', 'face-features': ['face']}) # switch image to video for video or webcam 455 | # you can also choose to draw particular features such as: 456 | # 'chin', 'left_eye', 'right_eye', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', 'nose_tip', 'top_lip', 'bottom_lip' 457 | 458 | try: 459 | facedetector.start('resources/people.jpg') # leave empty for webcam or provide a video file 460 | 461 | except Exception as error: 462 | print(error) 463 | 464 | ``` 465 | 466 | > The complete code can be found in [main_facefeatures_image.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_facefeatures_image.py) 467 | 468 |
469 | 470 | ### 5. Extract faces into images (image mode only) 471 | 472 | FaceDetect provides you with a way to extract the faces from an image and load them as individual images that can be saved locally. 473 | 474 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_faceextract_image_output.png) 475 | 476 | ```python 477 | 478 | # Set face extraction to true 479 | facedetector = FaceDetect({'mode': 'image', 'face-extraction': True}) 480 | 481 | try: 482 | facedetector.start('resources/people.jpg') 483 | 484 | except Exception as error: 485 | print(error) 486 | 487 | ``` 488 | 489 | > The complete code can be found in [main_faceextract_image.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_faceextract_image.py) 490 | 491 |
492 | 493 | ### 6. Recognize faces in an image 494 | 495 | FaceDetect allows you to recognize faces in an image based on a dictionary of known people faces. 496 | It compares the detected faces to the faces signatures that it computes from the images provided. If it finds matches, it 497 | will identify them on the image with a green rectangle along with the respective names (provided). The unknown faces will be 498 | identified with a red rectangle labelled 'Unknown'. 499 | 500 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_recognize_image_output.png) 501 | 502 | ```python 503 | 504 | # Set the method to recognize and provide a dictionary of known faces names and image path 505 | facedetector = FaceDetect({'mode': 'image', 'method': 'recognize', 'known-faces': {'John': 'resources/person1.png', 506 | 'Jane': 'resources/person2.png'}}) 507 | 508 | try: 509 | facedetector.start('resources/people.jpg') 510 | 511 | except Exception as error: 512 | print(error) 513 | 514 | ``` 515 | 516 | > The complete code can be found in [main_recognize_image.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_recognize_image.py) 517 | 518 |
519 | 520 | ### 7. Recognize faces in a video or a webcam 521 | 522 | FaceDetect allows you to recognize faces in a video or a webcam based on a dictionary of known people faces. 523 | If it finds matches, it will identify them on the video or webcam canvas with a green rectangle along with the respective names (provided). 524 | The unknown faces will be identified with a red rectangle labelled 'Unknown'. 525 | 526 | ![](https://github.com/DoryAzar/FaceDetectPython/blob/master/outputs/main_recognize_video_output.png) 527 | 528 | ```python 529 | 530 | # Set the method to recognize and provide a dictionary of known faces names and image path 531 | facedetector = FaceDetect({'method': 'recognize', 'known-faces': {'John': 'resources/person1.png', 532 | 'Jane': 'resources/person2.png'}}) 533 | 534 | try: 535 | facedetector.start() 536 | 537 | except Exception as error: 538 | print(error) 539 | 540 | 541 | ``` 542 | 543 | > The complete code can be found in [main_recognize_video.py](https://github.com/DoryAzar/FaceDetectPython/blob/master/main_recognize_video.py) 544 | 545 | 546 |
547 | 548 | ## Known Issues 549 | 550 | + OpenCV is generating a warning upon loading a video, webcam or an image indicating that some plugins are not compiled against the right Qt binaries. This is due to the GUI that needs to be compiled and that depends heavily on X11 libraries. This issue did not cause any issue for the needs of FaceDetect. It could be resolved by making sure all libraries are compatible with the latest MacOs. 551 | 552 | + OpenCV is not the best for drawing on top of rich media. It is however the most robust in terms of computer graphics and is a fast video and image processor. 553 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # main.py 2 | # Usage: %python main.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | 8 | # Initialize FaceDetect 9 | # Params: 10 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 11 | # * mode: image or video (default) 12 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 13 | # * method: call native callback methods during detection or bypass with a custom method 14 | # * draw: draws the detection on the canvas if set to True (default) 15 | # * print: prints the face locations and labels on the console 16 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 17 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 18 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 19 | # It is a dictionary of face labels and image paths associated. 20 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 21 | # 22 | 23 | 24 | facedetector = FaceDetect() 25 | 26 | try: 27 | # When the start method is not given an image or video path, it starts the webcam 28 | # For Image file: facedetector.start('') 29 | # For Video: facedetector.start('') 30 | # Press 'q' to exit 31 | facedetector.start() 32 | 33 | 34 | # FaceDetect always generates a FaceDetect Exception 35 | except Exception as error: 36 | print(error) 37 | -------------------------------------------------------------------------------- /main_detection_image.py: -------------------------------------------------------------------------------- 1 | # main_detection_image.py 2 | # Usage: %python main_detection_image.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | facedetector = FaceDetect({'mode': 'image'}) 24 | 25 | try: 26 | # When the start method is not given an image or video path, it starts the webcam 27 | # For Image file: facedetector.start('') 28 | # For Video: facedetector.start('') 29 | # Press 'q' to exit 30 | facedetector.start('resources/people.jpg') 31 | 32 | 33 | # FaceDetect always generates a FaceDetect Exception 34 | except Exception as error: 35 | print(error) 36 | -------------------------------------------------------------------------------- /main_detection_webcam.py: -------------------------------------------------------------------------------- 1 | # main_detection_webcam.py 2 | # Usage: %python main_detection_webcam.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | # Passing settings (the default ones are being passed for comparison purposes with main.py) 24 | facedetector = FaceDetect({'mode': 'video', 'custom': False, 'method': 'detect', 'draw': True}) 25 | 26 | try: 27 | # When the start method is not given an image or video path, it starts the webcam 28 | # For Image file: facedetector.start('') 29 | # For Video: facedetector.start('') 30 | # Press 'q' to exit 31 | facedetector.start() 32 | 33 | 34 | # FaceDetect always generates a FaceDetect Exception 35 | except Exception as error: 36 | print(error) 37 | -------------------------------------------------------------------------------- /main_detection_webcam_extended.py: -------------------------------------------------------------------------------- 1 | # main_detection_webcam.py 2 | # Usage: %python main_detection_webcam_extended.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | 8 | # Initialize FaceDetect 9 | # Params: 10 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 11 | # * mode: image or video (default) 12 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 13 | # * method: call native callback methods during detection or bypass with a custom method 14 | # * draw: draws the detection on the canvas if set to True (default) 15 | # * print: prints the face locations and labels on the console 16 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 17 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 18 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 19 | # It is a dictionary of face labels and image paths associated. 20 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 21 | # 22 | 23 | 24 | class MyDetector(FaceDetect): 25 | # example of a method that print the detections property from FaceDetect 26 | def main(self): 27 | print(self.detections) 28 | 29 | 30 | # Passing settings (the default ones are being passed for comparison purposes with main.py) 31 | facedetector = MyDetector({'custom': True, 'method': 'main'}) 32 | 33 | try: 34 | # When the start method is not given an image or video path, it starts the webcam 35 | # For Image file: facedetector.start('') 36 | # For Video: facedetector.start('') 37 | # Press 'q' to exit 38 | facedetector.start() 39 | 40 | 41 | # FaceDetect always generates a FaceDetect Exception 42 | except Exception as error: 43 | print(error) 44 | -------------------------------------------------------------------------------- /main_faceextract_image.py: -------------------------------------------------------------------------------- 1 | # main_faceextract_image.py 2 | # Usage: %python main_faceextract_image.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | facedetector = FaceDetect({'mode': 'image', 'face-extraction': True}) 24 | 25 | try: 26 | # When the start method is not given an image or video path, it starts the webcam 27 | # For Image file: facedetector.start('') 28 | # For Video: facedetector.start('') 29 | # Press 'q' to exit 30 | facedetector.start('resources/people.jpg') 31 | 32 | 33 | # FaceDetect always generates a FaceDetect Exception 34 | except Exception as error: 35 | print(error) 36 | -------------------------------------------------------------------------------- /main_facefeatures_image.py: -------------------------------------------------------------------------------- 1 | # main_facefeatures_image.py 2 | # Usage: %python main_facefeatures_image.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | facedetector = FaceDetect({'mode': 'image', 'face-features': ['face']}) 24 | # you can also choose to draw particular features such as: 25 | # 'chin', 'left_eye', 'right_eye', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', 'nose_tip', 'top_lip', 'bottom_lip' 26 | 27 | try: 28 | # When the start method is not given an image or video path, it starts the webcam 29 | # For Image file: facedetector.start('') 30 | # For Video: facedetector.start('') 31 | # Press 'q' to exit 32 | facedetector.start('resources/people.jpg') 33 | 34 | 35 | # FaceDetect always generates a FaceDetect Exception 36 | except Exception as error: 37 | print(error) 38 | -------------------------------------------------------------------------------- /main_recognize_image.py: -------------------------------------------------------------------------------- 1 | # main_recognize_image.py 2 | # Usage: %python main_recognize_image.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | # Set the method to recognize and provide a dictionary of known faces names and image path 24 | facedetector = FaceDetect({'mode': 'image', 'method': 'recognize', 'known-faces': {'John': 'resources/person1.png', 25 | 'Jane': 'resources/person2.png'}}) 26 | 27 | try: 28 | # When the start method is not given an image or video path, it starts the webcam 29 | # For Image file: facedetector.start('') 30 | # For Video: facedetector.start('') 31 | # Press 'q' to exit 32 | facedetector.start('resources/people.jpg') 33 | 34 | 35 | # FaceDetect always generates a FaceDetect Exception 36 | except Exception as error: 37 | print(error) 38 | -------------------------------------------------------------------------------- /main_recognize_video.py: -------------------------------------------------------------------------------- 1 | # main_recognize_video.py 2 | # Usage: %python main_recognize_video.py 3 | 4 | # Import the FaceDetect class 5 | from FaceDetect.facedetect import FaceDetect 6 | 7 | # Initialize FaceDetect 8 | # Params: 9 | # - settings (optional): Dictionary with settings to be passed to the FaceDetector 10 | # * mode: image or video (default) 11 | # * custom: False (default). If you wish to extend the FaceDetect class, specify the method that it needs to execute 12 | # * method: call native callback methods during detection or bypass with a custom method 13 | # * draw: draws the detection on the canvas if set to True (default) 14 | # * print: prints the face locations and labels on the console 15 | # * face-extraction: extracts captures of the faces into their own images. Applicable only to mode image 16 | # * face-features: Draws the specified face features. Off by default. Pass the list ['face'] to draw the whole face 17 | # * known-faces: Setting need for facial recognition when 'method' is set to 'recognize' 18 | # It is a dictionary of face labels and image paths associated. 19 | # For example: {'John': 'person1.png', 'Jane': 'person2.png'} 20 | # 21 | 22 | 23 | # Set the method to recognize and provide a dictionary of known faces names and image path 24 | facedetector = FaceDetect({'method': 'recognize', 'known-faces': {'John': 'resources/person1.png', 25 | 'Jane': 'resources/person2.png'}}) 26 | 27 | try: 28 | # When the start method is not given an image or video path, it starts the webcam 29 | # For Image file: facedetector.start('') 30 | # For Video: facedetector.start('') 31 | # Press 'q' to exit 32 | facedetector.start() 33 | 34 | 35 | # FaceDetect always generates a FaceDetect Exception 36 | except Exception as error: 37 | print(error) 38 | -------------------------------------------------------------------------------- /outputs/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/banner.png -------------------------------------------------------------------------------- /outputs/main_detection_image_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_detection_image_output.png -------------------------------------------------------------------------------- /outputs/main_detection_webcam_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_detection_webcam_output.png -------------------------------------------------------------------------------- /outputs/main_faceextract_image_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_faceextract_image_output.png -------------------------------------------------------------------------------- /outputs/main_facefeatures_image_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_facefeatures_image_output.png -------------------------------------------------------------------------------- /outputs/main_recognize_image_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_recognize_image_output.png -------------------------------------------------------------------------------- /outputs/main_recognize_video_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/outputs/main_recognize_video_output.png -------------------------------------------------------------------------------- /resources/freevideo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/resources/freevideo.mp4 -------------------------------------------------------------------------------- /resources/people.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/resources/people.jpg -------------------------------------------------------------------------------- /resources/person1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/resources/person1.png -------------------------------------------------------------------------------- /resources/person2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/resources/person2.png -------------------------------------------------------------------------------- /resources/person3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DoryAzar/FaceDetectPython/1606e55aab3526327062d8d2327353b943cb3abd/resources/person3.png --------------------------------------------------------------------------------