forked from realpython/materials
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdetector.py
More file actions
87 lines (70 loc) · 2.53 KB
/
Copy pathdetector.py
File metadata and controls
87 lines (70 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import pickle
from collections import Counter
from pathlib import Path
import face_recognition
DEFAULT_ENCODINGS_PATH = Path("output/encodings.pkl")
# Create directories if they don't already exist
Path("training").mkdir(exist_ok=True)
Path("output").mkdir(exist_ok=True)
Path("validation").mkdir(exist_ok=True)
def encode_known_faces(
model: str = "hog", encodings_location: Path = DEFAULT_ENCODINGS_PATH
) -> None:
"""
Loads images in the training directory and builds a dictionary of their
names and encodings.
"""
names = []
encodings = []
for filepath in Path("training").glob("*/*"):
name = filepath.parent.name
image = face_recognition.load_image_file(filepath)
face_locations = face_recognition.face_locations(image, model=model)
face_encodings = face_recognition.face_encodings(image, face_locations)
for encoding in face_encodings:
names.append(name)
encodings.append(encoding)
name_encodings = {"names": names, "encodings": encodings}
with encodings_location.open(mode="wb") as f:
pickle.dump(name_encodings, f)
def recognize_faces(
image_location: str,
model: str = "hog",
encodings_location: Path = DEFAULT_ENCODINGS_PATH,
) -> None:
"""
Given an unknown image, get the locations and encodings of any faces and
compares them against the known encodings to find potential matches.
"""
with encodings_location.open(mode="rb") as f:
loaded_encodings = pickle.load(f)
input_image = face_recognition.load_image_file(image_location)
input_face_locations = face_recognition.face_locations(
input_image, model=model
)
input_face_encodings = face_recognition.face_encodings(
input_image, input_face_locations
)
for bounding_box, unknown_encoding in zip(
input_face_locations, input_face_encodings
):
name = _recognize_face(unknown_encoding, loaded_encodings)
if not name:
name = "Unknown"
print(name, bounding_box)
def _recognize_face(unknown_encoding, loaded_encodings):
"""
Given an unknown encoding and all known encodings, find the known
encoding with the most matches.
"""
boolean_matches = face_recognition.compare_faces(
loaded_encodings["encodings"], unknown_encoding
)
votes = Counter(
name
for match, name in zip(boolean_matches, loaded_encodings["names"])
if match
)
if votes:
return votes.most_common(1)[0][0]
recognize_faces("unknown.jpg")