1import face_recognition
2import os
3import cv2
4
5
6KNOWN_FACES_DIR = 'known_faces'
7UNKNOWN_FACES_DIR = 'unknown_faces'
8TOLERANCE = 0.6
9FRAME_THICKNESS = 3
10FONT_THICKNESS = 2
11MODEL = 'cnn' # default: 'hog', other one can be 'cnn' - CUDA accelerated (if available) deep-learning pretrained model
12
13
14# Returns (R, G, B) from name
15def name_to_color(name):
16 # Take 3 first letters, tolower()
17 # lowercased character ord() value rage is 97 to 122, substract 97, multiply by 8
18 color = [(ord(c.lower())-97)*8 for c in name[:3]]
19 return color
20
21
22print('Loading known faces...')
23known_faces = []
24known_names = []
25
26# We oranize known faces as subfolders of KNOWN_FACES_DIR
27# Each subfolder's name becomes our label (name)
28for name in os.listdir(KNOWN_FACES_DIR):
29
30 # Next we load every file of faces of known person
31 for filename in os.listdir(f'{KNOWN_FACES_DIR}/{name}'):
32
33 # Load an image
34 image = face_recognition.load_image_file(f'{KNOWN_FACES_DIR}/{name}/{filename}')
35
36 # Get 128-dimension face encoding
37 # Always returns a list of found faces, for this purpose we take first face only (assuming one face per image as you can't be twice on one image)
38 encoding = face_recognition.face_encodings(image)[0]
39
40 # Append encodings and name
41 known_faces.append(encoding)
42 known_names.append(name)
43
44
45print('Processing unknown faces...')
46# Now let's loop over a folder of faces we want to label
47for filename in os.listdir(UNKNOWN_FACES_DIR):
48
49 # Load image
50 print(f'Filename {filename}', end='')
51 image = face_recognition.load_image_file(f'{UNKNOWN_FACES_DIR}/{filename}')
52
53 # This time we first grab face locations - we'll need them to draw boxes
54 locations = face_recognition.face_locations(image, model=MODEL)
55
56 # Now since we know loctions, we can pass them to face_encodings as second argument
57 # Without that it will search for faces once again slowing down whole process
58 encodings = face_recognition.face_encodings(image, locations)
59
60 # We passed our image through face_locations and face_encodings, so we can modify it
61 # First we need to convert it from RGB to BGR as we are going to work with cv2
62 image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
63
64 # But this time we assume that there might be more faces in an image - we can find faces of dirrerent people
65 print(f', found {len(encodings)} face(s)')
66 for face_encoding, face_location in zip(encodings, locations):
67
68 # We use compare_faces (but might use face_distance as well)
69 # Returns array of True/False values in order of passed known_faces
70 results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
71
72 # Since order is being preserved, we check if any face was found then grab index
73 # then label (name) of first matching known face withing a tolerance
74 match = None
75 if True in results: # If at least one is true, get a name of first of found labels
76 match = known_names[results.index(True)]
77 print(f' - {match} from {results}')
78
79 # Each location contains positions in order: top, right, bottom, left
80 top_left = (face_location[3], face_location[0])
81 bottom_right = (face_location[1], face_location[2])
82
83 # Get color by name using our fancy function
84 color = name_to_color(match)
85
86 # Paint frame
87 cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)
88
89 # Now we need smaller, filled grame below for a name
90 # This time we use bottom in both corners - to start from bottom and move 50 pixels down
91 top_left = (face_location[3], face_location[2])
92 bottom_right = (face_location[1], face_location[2] + 22)
93
94 # Paint frame
95 cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
96
97 # Wite a name
98 cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)
99
100 # Show image
101 cv2.imshow(filename, image)
102 cv2.waitKey(0)
103 cv2.destroyWindow(filename)
104
1>>> import cv2
2>>> # Get user supplied values
3imagePath = sys.argv[1]
4cascPath = sys.argv[2]
5# Create the haar cascade
6faceCascade = cv2.CascadeClassifier(cascPath)
7# Read the image
8image = cv2.imread(imagePath)
9gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
10# Detect faces in the image
11faces = faceCascade.detectMultiScale(
12 gray,
13 scaleFactor=1.1,
14 minNeighbors=5,
15 minSize=(30, 30),
16 flags = cv2.cv.CV_HAAR_SCALE_IMAGE
17)
18print "Found {0} faces!".format(len(faces))
19
20# Draw a rectangle around the faces
21for (x, y, w, h) in faces:
22 cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
23cv2.imshow("Faces found", image)
24cv2.waitKey(0)