diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..27ca1e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +dlib +venv +Faces/* +windows \ No newline at end of file diff --git a/AntiSpoofing.py b/AntiSpoofing.py new file mode 100644 index 0000000..3917d95 --- /dev/null +++ b/AntiSpoofing.py @@ -0,0 +1,42 @@ +from ultralytics import YOLO +import cv2 +import cvzone +import math +import time + +confidence = 0.9 + +cap = cv2.VideoCapture(0) # for webcam +cap.set(3, 640) +cap.set(4, 480) +# cap = cv2.VideoCapture("test.mp4") # for video file + +model = YOLO("models/best.pt") +model.overrides['verbose'] = False + +classNames = ["fake", "real"] + +while True: + success, img = cap.read() + results = model(img, stream=True) + for r in results: + boxes = r.boxes + for box in boxes: + # Confidence + conf = math.ceil((box.conf[0] * 100))/100 + # class name + if conf > confidence: + cls = int(box.cls[0]) + if classNames[cls] == "real": + print("Real") + else: + print("Spoof") + + cv2.imshow("Image", img) + key = cv2.waitKey(1) & 0xFF + + # Exit if 'q' key is pressed + if key == ord("q"): + break + +cv2.destroyAllWindows() \ No newline at end of file diff --git a/FaceRecognition.py b/FaceRecognition.py new file mode 100644 index 0000000..980f34a --- /dev/null +++ b/FaceRecognition.py @@ -0,0 +1,45 @@ +import cv2 +import os +import pickle +import face_recognition +import numpy as np +import cvzone + +cap = cv2.VideoCapture(0) +cap.set(3, 640) # Set width +cap.set(4, 480) # Set height + +# Load the Encoding File +print("Loading encodings...") +encodings = open("GeneratedEncodings.p", "rb") +encodingListKnownWithIDs = pickle.load(encodings) +encodings.close() +encodeListKnown, studentIDs = encodingListKnownWithIDs +print("Encodings loaded.") + +while True: + success, img = cap.read() + + imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25) + imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB) + + faceCurrentFrame = face_recognition.face_locations(imgS) + encodeCurrentFrame = face_recognition.face_encodings(imgS,faceCurrentFrame) + + for encodeFace, faceLocation in zip(encodeCurrentFrame, faceCurrentFrame): + matches = face_recognition.compare_faces(encodeListKnown, encodeFace) + faceDistance = face_recognition.face_distance(encodeListKnown, encodeFace) + matchIndex = np.argmin(faceDistance) + if matches[matchIndex]: + print("Known Face Detected") + print(studentIDs[matchIndex]) + + + cv2.imshow("Face Attendance", img) + + # Wait for a key press to break the loop + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() \ No newline at end of file diff --git a/GeneratedEncodings.p b/GeneratedEncodings.p new file mode 100644 index 0000000..ce5eeaf Binary files /dev/null and b/GeneratedEncodings.p differ diff --git a/README.md b/README.md index 752af81..d7083c7 100644 --- a/README.md +++ b/README.md @@ -1 +1,21 @@ -# DoorAutoCompiled \ No newline at end of file +# Should be the Correct One + +## How to Run: + +Note: if you windows, you will first need to build `dlib` using wheel. + +1. create a virtual environment + ```bash + python -m venv venv + ``` + +2. install requirements + ```bash + pip install -r reqs.txt + ``` + This 100% works on windows, but might need calibration in linux. + +3. run the app + ```bash + python main.py + ``` \ No newline at end of file diff --git a/encodeGenerator.py b/encodeGenerator.py new file mode 100644 index 0000000..3f7605b --- /dev/null +++ b/encodeGenerator.py @@ -0,0 +1,34 @@ +import cv2 +import face_recognition +import pickle +import os + +### Importing the Faces +folderPath = "Faces" +pathList = os.listdir(folderPath) +imgList = [] +studentIDs = [] +for path in pathList: + imgList.append(cv2.imread(os.path.join(folderPath, path))) + studentIDs.append(os.path.splitext(path)[0]) + +### Encodings Generator ### +def findEncodings(imagesList): + encodeList = [] + for img in imagesList: + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + encode = face_recognition.face_encodings(img)[0] + encodeList.append(encode) + + return encodeList + +print("Encoding Started...") +encodeListKnown = findEncodings(imgList) +encodingListKnownWithIDs = (encodeListKnown, studentIDs) +print("Encoding Complete.") + +file = open("GeneratedEncodings.p", "wb") +pickle.dump(encodingListKnownWithIDs, file) +file.close() + +print("Encodings Saved.") \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..a5f91fc --- /dev/null +++ b/main.py @@ -0,0 +1,70 @@ +import cv2 +import pickle +import face_recognition +import numpy as np +import math +from ultralytics import YOLO + +# Initialize video capture +cap = cv2.VideoCapture(0) +cap.set(3, 640) # Set width +cap.set(4, 480) # Set height + +# Load the Encoding File +print("Loading encodings...") +encodings = open("GeneratedEncodings.p", "rb") +encodingListKnownWithIDs = pickle.load(encodings) +encodings.close() +encodeListKnown, studentIDs = encodingListKnownWithIDs +print("Encodings loaded.") + +# Load the anti-spoofing model +model = YOLO("models/best.pt") +model.overrides['verbose'] = False +classNames = ["fake", "real"] +confidence = 0.9 + +while True: + success, img = cap.read() + + # Anti-spoofing check + results = model(img, stream=True) + is_real = False + for r in results: + boxes = r.boxes + for box in boxes: + conf = math.ceil((box.conf[0] * 100))/100 + if conf > confidence: + cls = int(box.cls[0]) + if classNames[cls] == "real": + is_real = True + break + if is_real: + break + + if is_real: + # Face recognition + imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25) + imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB) + + faceCurrentFrame = face_recognition.face_locations(imgS) + encodeCurrentFrame = face_recognition.face_encodings(imgS, faceCurrentFrame) + + for encodeFace, faceLocation in zip(encodeCurrentFrame, faceCurrentFrame): + matches = face_recognition.compare_faces(encodeListKnown, encodeFace) + faceDistance = face_recognition.face_distance(encodeListKnown, encodeFace) + matchIndex = np.argmin(faceDistance) + if matches[matchIndex]: + print("Known Face Detected") + print(studentIDs[matchIndex]) + else: + print("Spoofing Attempt Detected") + + cv2.imshow("Face Attendance", img) + + # Wait for a key press to break the loop + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() diff --git a/models/best.pt b/models/best.pt new file mode 100644 index 0000000..f28cdc8 Binary files /dev/null and b/models/best.pt differ diff --git a/reqs.txt b/reqs.txt new file mode 100644 index 0000000..422d4a1 Binary files /dev/null and b/reqs.txt differ diff --git a/requirements-win.txt b/requirements-win.txt new file mode 100644 index 0000000..820d02f Binary files /dev/null and b/requirements-win.txt differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..78245ad Binary files /dev/null and b/requirements.txt differ