Sie sind auf Seite 1von 1

Why GitHub?

Enterprise Explore Marketplace Pricing Search Sign in Sign up

ageitgey / face_recognition Watch 1.5k Star 30.9k Fork 8.5k

Code Issues 415 Pull requests 3 Projects 0 Wiki Security Insights

Dismiss
Join GitHub today
GitHub is home to over 40 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Branch: master face_recognition / face_recognition / api.py Find file Copy path

tejashah88 allowed face_encodings to accept either 'large' or 'small' model 4d7bc04 13 days ago

8 contributors

226 lines (173 sloc) 10.2 KB Raw Blame History

1 # -*- coding: utf-8 -*-


2
3 import PIL.Image
4 import dlib
5 import numpy as np
6 from PIL import ImageFile
7
8 try:
9 import face_recognition_models
10 except Exception:
11 print("Please install `face_recognition_models` with this command before using `face_recognition`:\n")
12 print("pip install git+https://github.com/ageitgey/face_recognition_models")
13 quit()
14
15 ImageFile.LOAD_TRUNCATED_IMAGES = True
16
17 face_detector = dlib.get_frontal_face_detector()
18
19 predictor_68_point_model = face_recognition_models.pose_predictor_model_location()
20 pose_predictor_68_point = dlib.shape_predictor(predictor_68_point_model)
21
22 predictor_5_point_model = face_recognition_models.pose_predictor_five_point_model_location()
23 pose_predictor_5_point = dlib.shape_predictor(predictor_5_point_model)
24
25 cnn_face_detection_model = face_recognition_models.cnn_face_detector_model_location()
26 cnn_face_detector = dlib.cnn_face_detection_model_v1(cnn_face_detection_model)
27
28 face_recognition_model = face_recognition_models.face_recognition_model_location()
29 face_encoder = dlib.face_recognition_model_v1(face_recognition_model)
30
31
32 def _rect_to_css(rect):
33 """
34 Convert a dlib 'rect' object to a plain tuple in (top, right, bottom, left) order
35
36 :param rect: a dlib 'rect' object
37 :return: a plain tuple representation of the rect in (top, right, bottom, left) order
38 """
39 return rect.top(), rect.right(), rect.bottom(), rect.left()
40
41
42 def _css_to_rect(css):
43 """
44 Convert a tuple in (top, right, bottom, left) order to a dlib `rect` object
45
46 :param css: plain tuple representation of the rect in (top, right, bottom, left) order
47 :return: a dlib `rect` object
48 """
49 return dlib.rectangle(css[3], css[0], css[1], css[2])
50
51
52 def _trim_css_to_bounds(css, image_shape):
53 """
54 Make sure a tuple in (top, right, bottom, left) order is within the bounds of the image.
55
56 :param css: plain tuple representation of the rect in (top, right, bottom, left) order
57 :param image_shape: numpy shape of the image array
58 :return: a trimmed plain tuple representation of the rect in (top, right, bottom, left) order
59 """
60 return max(css[0], 0), min(css[1], image_shape[1]), min(css[2], image_shape[0]), max(css[3], 0)
61
62
63 def face_distance(face_encodings, face_to_compare):
64 """
65 Given a list of face encodings, compare them to a known face encoding and get a euclidean distance
66 for each comparison face. The distance tells you how similar the faces are.
67
68 :param faces: List of face encodings to compare
69 :param face_to_compare: A face encoding to compare against
70 :return: A numpy ndarray with the distance for each face in the same order as the 'faces' array
71 """
72 if len(face_encodings) == 0:
73 return np.empty((0))
74
75 return np.linalg.norm(face_encodings - face_to_compare, axis=1)
76
77
78 def load_image_file(file, mode='RGB'):
79 """
80 Loads an image file (.jpg, .png, etc) into a numpy array
81
82 :param file: image file name or file object to load
83 :param mode: format to convert the image to. Only 'RGB' (8-bit RGB, 3 channels) and 'L' (black and white) are supported.
84 :return: image contents as numpy array
85 """
86 im = PIL.Image.open(file)
87 if mode:
88 im = im.convert(mode)
89 return np.array(im)
90
91
92 def _raw_face_locations(img, number_of_times_to_upsample=1, model="hog"):
93 """
94 Returns an array of bounding boxes of human faces in a image
95
96 :param img: An image (as a numpy array)
97 :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
98 :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate
99 deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog".
100 :return: A list of dlib 'rect' objects of found face locations
101 """
102 if model == "cnn":
103 return cnn_face_detector(img, number_of_times_to_upsample)
104 else:
105 return face_detector(img, number_of_times_to_upsample)
106
107
108 def face_locations(img, number_of_times_to_upsample=1, model="hog"):
109 """
110 Returns an array of bounding boxes of human faces in a image
111
112 :param img: An image (as a numpy array)
113 :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
114 :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate
115 deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog".
116 :return: A list of tuples of found face locations in css (top, right, bottom, left) order
117 """
118 if model == "cnn":
119 return [_trim_css_to_bounds(_rect_to_css(face.rect), img.shape) for face in _raw_face_locations(img, number_of_times_to_upsample, "c
120 else:
121 return [_trim_css_to_bounds(_rect_to_css(face), img.shape) for face in _raw_face_locations(img, number_of_times_to_upsample, model)
122
123
124 def _raw_face_locations_batched(images, number_of_times_to_upsample=1, batch_size=128):
125 """
126 Returns an 2d array of dlib rects of human faces in a image using the cnn face detector
127
128 :param img: A list of images (each as a numpy array)
129 :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
130 :return: A list of dlib 'rect' objects of found face locations
131 """
132 return cnn_face_detector(images, number_of_times_to_upsample, batch_size=batch_size)
133
134
135 def batch_face_locations(images, number_of_times_to_upsample=1, batch_size=128):
136 """
137 Returns an 2d array of bounding boxes of human faces in a image using the cnn face detector
138 If you are using a GPU, this can give you much faster results since the GPU
139 can process batches of images at once. If you aren't using a GPU, you don't need this function.
140
141 :param images: A list of images (each as a numpy array)
142 :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces.
143 :param batch_size: How many images to include in each GPU processing batch.
144 :return: A list of tuples of found face locations in css (top, right, bottom, left) order
145 """
146 def convert_cnn_detections_to_css(detections):
147 return [_trim_css_to_bounds(_rect_to_css(face.rect), images[0].shape) for face in detections]
148
149 raw_detections_batched = _raw_face_locations_batched(images, number_of_times_to_upsample, batch_size)
150
151 return list(map(convert_cnn_detections_to_css, raw_detections_batched))
152
153
154 def _raw_face_landmarks(face_image, face_locations=None, model="large"):
155 if face_locations is None:
156 face_locations = _raw_face_locations(face_image)
157 else:
158 face_locations = [_css_to_rect(face_location) for face_location in face_locations]
159
160 pose_predictor = pose_predictor_68_point
161
162 if model == "small":
163 pose_predictor = pose_predictor_5_point
164
165 return [pose_predictor(face_image, face_location) for face_location in face_locations]
166
167
168 def face_landmarks(face_image, face_locations=None, model="large"):
169 """
170 Given an image, returns a dict of face feature locations (eyes, nose, etc) for each face in the image
171
172 :param face_image: image to search
173 :param face_locations: Optionally provide a list of face locations to check.
174 :param model: Optional - which model to use. "large" (default) or "small" which only returns 5 points but is faster.
175 :return: A list of dicts of face feature locations (eyes, nose, etc)
176 """
177 landmarks = _raw_face_landmarks(face_image, face_locations, model)
178 landmarks_as_tuples = [[(p.x, p.y) for p in landmark.parts()] for landmark in landmarks]
179
180 # For a definition of each point index, see https://cdn-images-1.medium.com/max/1600/1*AbEg31EgkbXSQehuNJBlWg.png
181 if model == 'large':
182 return [{
183 "chin": points[0:17],
184 "left_eyebrow": points[17:22],
185 "right_eyebrow": points[22:27],
186 "nose_bridge": points[27:31],
187 "nose_tip": points[31:36],
188 "left_eye": points[36:42],
189 "right_eye": points[42:48],
190 "top_lip": points[48:55] + [points[64]] + [points[63]] + [points[62]] + [points[61]] + [points[60]],
191 "bottom_lip": points[54:60] + [points[48]] + [points[60]] + [points[67]] + [points[66]] + [points[65]] + [points[64]]
192 } for points in landmarks_as_tuples]
193 elif model == 'small':
194 return [{
195 "nose_tip": [points[4]],
196 "left_eye": points[2:4],
197 "right_eye": points[0:2],
198 } for points in landmarks_as_tuples]
199 else:
200 raise ValueError("Invalid landmarks model type. Supported models are ['small', 'large'].")
201
202
203 def face_encodings(face_image, known_face_locations=None, num_jitters=1, model="small"):
204 """
205 Given an image, return the 128-dimension face encoding for each face in the image.
206
207 :param face_image: The image that contains one or more faces
208 :param known_face_locations: Optional - the bounding boxes of each face if you already know them.
209 :param num_jitters: How many times to re-sample the face when calculating encoding. Higher is more accurate, but slower (i.e. 100 is 100
210 :param model: Optional - which model to use. "large" (default) or "small" which only returns 5 points but is faster.
211 :return: A list of 128-dimensional face encodings (one for each face in the image)
212 """
213 raw_landmarks = _raw_face_landmarks(face_image, known_face_locations, model)
214 return [np.array(face_encoder.compute_face_descriptor(face_image, raw_landmark_set, num_jitters)) for raw_landmark_set in raw_landmarks
215
216
217 def compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6):
218 """
219 Compare a list of face encodings against a candidate encoding to see if they match.
220
221 :param known_face_encodings: A list of known face encodings
222 :param face_encoding_to_check: A single face encoding to compare against the list
223 :param tolerance: How much distance between faces to consider it a match. Lower is more strict. 0.6 is typical best performance.
224 :return: A list of True/False values indicating which known_face_encodings match the face encoding to check
225 """
226 return list(face_distance(known_face_encodings, face_encoding_to_check) <= tolerance)

© 2019 GitHub, Inc. Terms Privacy Security Status Help Contact GitHub Pricing API Training Blog About

Das könnte Ihnen auch gefallen