├── README.md ├── client ├── client.py └── test-image.jpg ├── requirements.txt ├── server ├── __pycache__ │ └── face_rec.cpython-311.pyc ├── face_rec.py ├── faces │ ├── bill gates.jpg │ ├── elon musk.jpg │ ├── jeff bezos.jpg │ └── obama.jpg └── main.py └── tutorial ├── face_rec.py ├── faces ├── bill gates.jpg ├── elon musk.jpg ├── jeff bezos.jpg └── obama.jpg └── test-image.jpg /README.md: -------------------------------------------------------------------------------- 1 | # Facial Recognition 2 | 3 | This repository contains code that allows you to run this facial recognition script locally, or from a client-server model. 4 | 5 | ## Installation 6 | 7 | ### dlib Requirements (Windows) 8 | 9 | If you are on Mac or Linux you can skip this step... 10 | 11 | - Install [Microsoft C++ Build Tools](https://aka.ms/vs/17/release/vs_buildtools.exe) 12 | 13 | ![Build Tools Install GUI](https://i.stack.imgur.com/jKl2N.png) 14 | 15 | dlib can be challenging to install on Windows. If you are having trouble try looking through this [Stack Overflow Issue](https://stackoverflow.com/questions/74476152/error-in-installing-dlib-library-in-python3-11) 16 | 17 | ### dlib Requirements (Ubuntu/Mac) 18 | 19 | Refer to [this guide](https://pyimagesearch.com/2018/01/22/install-dlib-easy-complete-guide/) for help installing dlib on Mac/Linux: 20 | 21 | ### Install Python Packages 22 | 23 | Start by cloning this repository: `git clone ` then `cd ` 24 | 25 | To install the required packages ensure you are using Python 3.7+ and run the command: 26 | 27 | - `pip install -r requirements.txt` (Windows) or 28 | - `pip3 install -r requirements.txt` (Mac/Linux) 29 | 30 | ## Running The Code 31 | 32 | ### Running The Code Locally 33 | 34 | Assuming all of the packages are installed correctly you should be able to run the code locally. 35 | 36 | - Change directories into the `/tutorial` folder: `cd tutorial` 37 | - Execute the python script `face_rec.py`: `python face_rec.py` or `python3 face_rec.py` 38 | - Wait, and press `q` to quit the window! 39 | 40 | If you'd like to change the image the faces are being predicted for simply download a new image and set the path on line 55 from `face_rec.py`: 41 | 42 | ```python 43 | print(classify_face("test-image.jpg")) 44 | ``` 45 | 46 | ### Running With Client/Server 47 | 48 | Running the code from the client/server model is slightly more complicated. 49 | 50 | - Start by running the flask backend server. 51 | - Change directories to `/server`: `cd server` 52 | - Start the API server: `python main.py` or `python3 main.py` (take note of the port it is running on, default is `5000`) 53 | 54 | - Now that the server is running you can change to the `/client` directory: `cd ../client` 55 | - If necessary adjust the URL on line 13 of `client.py` to specify the correct port. 56 | - From the client directory run `client.py`: `python client.py` or `python3 client.py` 57 | 58 | If you'd like to change the image the faces are being predicted for simply download a new image and set the path on line 14 from `client.py`: 59 | 60 | ```python 61 | my_img = {'image': open('test-image.jpg', 'rb')} # feel free to change the image path here 62 | ``` 63 | 64 | ## Customization 65 | 66 | ### Adding Faces 67 | 68 | To add more faces to be detected simply add a labelled `.jpg` or `.png` file to the `/faces` directory. If you were to add an image of Tim (me!) you would simply save the image as `tim.png` (or `tim.jpg`). 69 | 70 | ## Deployment 71 | 72 | If you're intersted in deploying the flask server have a look at this [Repository](https://github.com/techwithtim/Flask-App-Hosted-On-VPS) and this [YouTube Video](https://www.youtube.com/watch?v=KgAtZ1LlNiQ) 73 | 74 | 75 | # 💻 Launch Your Software Development Career Today! 76 | 77 | 🎓 **No degree? No problem!** My program equips you with everything you need to break into tech and land an entry-level software development role. 78 | 79 | 🚀 **Why Join?** 80 | - 💼 **$70k+ starting salary potential** 81 | - 🕐 **Self-paced:** Complete on your own time 82 | - 🤑 **Affordable:** Low risk compared to expensive bootcamps or degrees 83 | - 🎯 **45,000+ job openings** in the market 84 | 85 | 👉 **[Start your journey today!](https://techwithtim.net/dev)** 86 | No experience needed—just your determination. Future-proof your career and unlock six-figure potential like many of our students have! 87 | -------------------------------------------------------------------------------- /client/client.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import io 3 | import cv2 4 | import base64 5 | import numpy as np 6 | from PIL import Image 7 | 8 | def string_to_image(base64_string): 9 | imgdata = base64.b64decode(base64_string) 10 | return np.array(Image.open(io.BytesIO(imgdata))) 11 | 12 | 13 | url = 'http://localhost:5000/classify-faces' 14 | my_img = {'image': open('test-image.jpg', 'rb')} # feel free to change the image path here 15 | r = requests.post(url, files=my_img) 16 | 17 | img_str = r.json().get("image").split('\'')[1] 18 | img = string_to_image(img_str) 19 | 20 | while True: 21 | cv2.imshow('Image', img) 22 | if cv2.waitKey(1) & 0xFF == ord('q'): 23 | break 24 | -------------------------------------------------------------------------------- /client/test-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/client/test-image.jpg -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cmake 2 | dlib 3 | face_recognition 4 | numpy 5 | opencv-python 6 | requests 7 | flask -------------------------------------------------------------------------------- /server/__pycache__/face_rec.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/server/__pycache__/face_rec.cpython-311.pyc -------------------------------------------------------------------------------- /server/face_rec.py: -------------------------------------------------------------------------------- 1 | import face_recognition as fr 2 | import os 3 | import cv2 4 | import numpy as np 5 | 6 | 7 | def get_encoded_faces(): 8 | encoded = {} 9 | 10 | for dirpath, dnames, fnames in os.walk("./faces"): 11 | for f in fnames: 12 | if f.endswith(".jpg") or f.endswith(".png"): 13 | face = fr.load_image_file("faces/" + f) 14 | encoding = fr.face_encodings(face)[0] 15 | encoded[f.split(".")[0]] = encoding 16 | 17 | return encoded 18 | 19 | 20 | def classify_faces(img): 21 | faces = get_encoded_faces() 22 | faces_encoded = list(faces.values()) 23 | known_face_names = list(faces.keys()) 24 | 25 | face_locations = fr.face_locations(img) 26 | unknown_face_encodings = fr.face_encodings(img, face_locations) 27 | 28 | face_names = [] 29 | for face_encoding in unknown_face_encodings: 30 | # See if the face is a match for the known face(s) 31 | matches = fr.compare_faces(faces_encoded, face_encoding) 32 | name = "Unknown" 33 | 34 | 35 | face_distances = fr.face_distance(faces_encoded, face_encoding) 36 | best_match_index = np.argmin(face_distances) 37 | if matches[best_match_index]: 38 | name = known_face_names[best_match_index] 39 | 40 | face_names.append(name) 41 | 42 | for (top, right, bottom, left), name in zip(face_locations, face_names): 43 | # Draw a box around the face 44 | cv2.rectangle(img, (left-20, top-20), (right+20, bottom+20), (255, 0, 0), 2) 45 | 46 | # Draw a label with a name below the face 47 | cv2.rectangle(img, (left-20, bottom -15), (right+20, bottom+20), (255, 0, 0), cv2.FILLED) 48 | font = cv2.FONT_HERSHEY_DUPLEX 49 | cv2.putText(img, name, (left -20, bottom + 15), font, 1.0, (255, 255, 255), 2) 50 | 51 | 52 | return img 53 | 54 | -------------------------------------------------------------------------------- /server/faces/bill gates.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/server/faces/bill gates.jpg -------------------------------------------------------------------------------- /server/faces/elon musk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/server/faces/elon musk.jpg -------------------------------------------------------------------------------- /server/faces/jeff bezos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/server/faces/jeff bezos.jpg -------------------------------------------------------------------------------- /server/faces/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/server/faces/obama.jpg -------------------------------------------------------------------------------- /server/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify, send_file 2 | from face_rec import classify_faces 3 | import cv2 4 | import base64 5 | from PIL import Image 6 | import numpy as np 7 | import os, io, sys 8 | 9 | app = Flask(__name__) 10 | 11 | 12 | @app.route('/classify-faces', methods=["POST"]) 13 | def classify(): 14 | if not request.files.get("image"): 15 | return jsonify({error: "please pass a valid image"}), 400 16 | 17 | file = request.files['image'].read() ## byte file 18 | npimg = np.fromstring(file, np.uint8) 19 | img = cv2.imdecode(npimg, cv2.IMREAD_COLOR) 20 | 21 | new_img = classify_faces(img) 22 | img = Image.fromarray(new_img.astype("uint8")) 23 | rawBytes = io.BytesIO() 24 | img.save(rawBytes, "JPEG") 25 | rawBytes.seek(0) 26 | img_base64 = base64.b64encode(rawBytes.read()) 27 | 28 | return jsonify({"image": str(img_base64)}) 29 | 30 | 31 | if __name__ == "__main__": 32 | app.run(debug=True) -------------------------------------------------------------------------------- /tutorial/face_rec.py: -------------------------------------------------------------------------------- 1 | import face_recognition as fr 2 | import os 3 | import cv2 4 | import numpy as np 5 | 6 | 7 | def get_encoded_faces(): 8 | encoded = {} 9 | 10 | for dirpath, dnames, fnames in os.walk("./faces"): 11 | for f in fnames: 12 | if f.endswith(".jpg") or f.endswith(".png"): 13 | face = fr.load_image_file(os.path.join("faces", f)) 14 | encoding = fr.face_encodings(face)[0] 15 | face_name = f.split(".")[0] 16 | encoded[face_name] = encoding 17 | 18 | return encoded 19 | 20 | 21 | def classify_face(im): 22 | faces = get_encoded_faces() 23 | faces_encoded = list(faces.values()) 24 | known_face_names = list(faces.keys()) 25 | 26 | img = cv2.imread(im, 1) 27 | 28 | face_locations = fr.face_locations(img) 29 | unknown_face_encodings = fr.face_encodings(img, face_locations) 30 | 31 | face_names = [] 32 | for face_encoding in unknown_face_encodings: 33 | matches = fr.compare_faces(faces_encoded, face_encoding) 34 | name = "Unknown" 35 | 36 | face_distances = fr.face_distance(faces_encoded, face_encoding) 37 | best_match_index = np.argmin(face_distances) 38 | if matches[best_match_index]: 39 | name = known_face_names[best_match_index] 40 | 41 | face_names.append(name) 42 | 43 | for (top, right, bottom, left), name in zip(face_locations, face_names): 44 | cv2.rectangle(img, (left-20, top-20), (right + 20, bottom+20), (255, 0, 0), 2) 45 | cv2.rectangle(img, (left-20, bottom-15), (right + 20, bottom+20), (255, 0, 0), cv2.FILLED) 46 | font = cv2.FONT_HERSHEY_DUPLEX 47 | cv2.putText(img, name, (left-20, bottom + 15), font, 1.0, (255, 255, 255), 2) 48 | 49 | while True: 50 | cv2.imshow("Image", img) 51 | if cv2.waitKey(1) & 0xFF == ord("q"): 52 | return face_names 53 | 54 | if __name__ == "__main__": 55 | print(classify_face("test-image.jpg")) -------------------------------------------------------------------------------- /tutorial/faces/bill gates.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/tutorial/faces/bill gates.jpg -------------------------------------------------------------------------------- /tutorial/faces/elon musk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/tutorial/faces/elon musk.jpg -------------------------------------------------------------------------------- /tutorial/faces/jeff bezos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/tutorial/faces/jeff bezos.jpg -------------------------------------------------------------------------------- /tutorial/faces/obama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/tutorial/faces/obama.jpg -------------------------------------------------------------------------------- /tutorial/test-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Facial-Recognition-Client-Server/d04717c0bd812bfcdad9eaa0f25586212f47be0a/tutorial/test-image.jpg --------------------------------------------------------------------------------