import math
from sklearn import neighbors
import cv2
import os
import os.path
import pickle
from PIL import Image, ImageDraw
import face_recognition
from face_recognition.face_recognition_cli import image_files_in_folder
from playsound import playsound
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
def capture():
camera_port = 0
videoCaptureObject = cv2.VideoCapture(camera_port, cv2.CAP_DSHOW)
result = True
while (result):
ret, frame = videoCaptureObject.read()
cv2.imwrite("test/test_image.jpg", frame)
result = False
videoCaptureObject.release()
cv2.destroyAllWindows()
def predict(X_img_path, knn_clf=None, model_path=None, distance_threshold=0.5):
if not os.path.isfile(X_img_path) or os.path.splitext(X_img_path)[1][1:] not in ALLOWED_EXTENSIONS:
raise Exception("Invalid image path: {}".format(X_img_path))
if knn_clf is None and model_path is None:
raise Exception("Must supply knn classifier either thourgh knn_clf or model_path")
# Load a trained KNN model (if one was passed in)
if knn_clf is None:
with open(model_path, 'rb') as f:
knn_clf = pickle.load(f)
# Load image file and find face locations
X_img = face_recognition.load_image_file(X_img_path)
X_face_locations = face_recognition.face_locations(X_img)
# If no faces are found in the image, return an empty result.
if len(X_face_locations) == 0:
return []
# Find encodings for faces in the test iamge
faces_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations)
# Use the KNN model to find the best matches for the test face
closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1)
are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))]
# Predict classes and remove classifications that aren't within the threshold
return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in
zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]
def show_prediction_labels_on_image(img_path, predictions):
pil_image = Image.open(img_path).convert("RGB")
draw = ImageDraw.Draw(pil_image)
for name, (top, right, bottom, left) in predictions:
# Draw a box around the face using the Pillow module
draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
# There's a bug in Pillow where it blows up with non-UTF-8 text
# when using the default bitmap font
name = name.encode("UTF-8")
# Draw a label with a name below the face
text_width, text_height = draw.textsize(name)
draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))
# Remove the drawing library from memory as per the Pillow docs
del draw
# Display the resulting image
pil_image.show()
if __name__ == "__main__":
matched_names = []
capture()
for image_file in os.listdir("test"):
full_file_path = os.path.join("test", image_file)
print("Looking for faces in {}".format(image_file))
# Find all people in the image using a trained classifier model
# Note: You can pass in either a classifier file name or a classifier model instance
predictions = predict(full_file_path, model_path="trained_knn_model.clf")
# Print results on the console
for name, (top, right, bottom, left) in predictions:
print("- Found {}".format(name))
matched_names.append(name)
# Display results overlaid on an image
show_prediction_labels_on_image(os.path.join("test", image_file), predictions)
for n in matched_names:
if n != "unknown":
playsound(f"audio_assets/{n}.mp3")
else:
playsound("audio_assets/Stranger.mp3")
os.remove("test/test_image.jpg")
Error:
C:\Users\rohan\AppData\Local\Programs\Python\Python37\python.exe C:/Users/rohan/PycharmProjects/PythpProject/Face_recognition/final.py
Looking for faces in test_image.jpg
- Found unknown
Traceback (most recent call last):
File "C:/Users/rohan/PycharmProjects/PythpProject/Face_recognition/final.py", line 106, in <module>
playsound("audio_assets/Stranger.mp3")
File "C:\Users\rohan\AppData\Roaming\Python\Python37\site-packages\playsound.py", line 34, in _playsoundWin
winCommand('open "' + sound + '" alias', alias)
File "C:\Users\rohan\AppData\Roaming\Python\Python37\site-packages\playsound.py", line 29, in winCommand
'\n ' + errorBuffer.value)
TypeError: can only concatenate str (not "bytes") to str
What I have tried:
The code has to produce a time log file and a audio file based on the recognition.
I downgraded the playsound version and got the above error. If I use the playsound version 1.2.2 I get a different error.
error:
Cannot find the specified file. Make sure the path and filename are correct.