Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- .gitattributes +1 -0
- db.py +76 -0
- helper_fns.py +54 -0
- main.py +65 -0
- students_database.db +3 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
students_database.db filter=lfs diff=lfs merge=lfs -text
|
db.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sqlite3
|
2 |
+
import pandas as pd
|
3 |
+
from PIL import Image
|
4 |
+
from helper_fns import pil_to_binary
|
5 |
+
|
6 |
+
# Function to add a new student to the database
|
7 |
+
def add_student(db, firstname, lastname, matric_no, image_path):
|
8 |
+
# Open the image from the given path
|
9 |
+
image = Image.open(image_path)
|
10 |
+
|
11 |
+
# Convert the PIL image to binary
|
12 |
+
image_binary = pil_to_binary(image)
|
13 |
+
|
14 |
+
# Connect to the existing database
|
15 |
+
conn = sqlite3.connect(db)
|
16 |
+
c = conn.cursor()
|
17 |
+
|
18 |
+
# Insert the new data into the table
|
19 |
+
c.execute("INSERT INTO students (first_name, last_name, matric_no, image) VALUES (?, ?, ?, ?)",
|
20 |
+
(firstname, lastname, matric_no, image_binary))
|
21 |
+
|
22 |
+
# Save (commit) the changes and close the connection
|
23 |
+
conn.commit()
|
24 |
+
conn.close()
|
25 |
+
|
26 |
+
|
27 |
+
def create_db(db_name, df):
|
28 |
+
conn = sqlite3.connect(db_name)
|
29 |
+
c = conn.cursor()
|
30 |
+
|
31 |
+
# Create the table if it doesn't exist
|
32 |
+
c.execute('''CREATE TABLE IF NOT EXISTS students
|
33 |
+
(first_name TEXT, last_name TEXT, matric_no TEXT, image BLOB)''')
|
34 |
+
|
35 |
+
for _, row in df.iterrows():
|
36 |
+
add_student(
|
37 |
+
db_name,
|
38 |
+
row['first_name'],
|
39 |
+
row['last_name'],
|
40 |
+
row['matric_no'],
|
41 |
+
row['image_path']
|
42 |
+
)
|
43 |
+
|
44 |
+
|
45 |
+
def get_student_row(db_path, last_name, matric_no):
|
46 |
+
"""
|
47 |
+
Retrieve a row from the database based on the last name and matric number.
|
48 |
+
|
49 |
+
Parameters:
|
50 |
+
db_path (str): Path to the SQLite database file.
|
51 |
+
last_name (str): The last name of the student.
|
52 |
+
matric_no (str): The matriculation number of the student.
|
53 |
+
|
54 |
+
Returns:
|
55 |
+
tuple: The row matching the last name and matric number, or None if not found.
|
56 |
+
"""
|
57 |
+
conn = sqlite3.connect(db_path)
|
58 |
+
cursor = conn.cursor()
|
59 |
+
|
60 |
+
query = """
|
61 |
+
SELECT * FROM students
|
62 |
+
WHERE last_name = ? AND matric_no = ?
|
63 |
+
"""
|
64 |
+
cursor.execute(query, (last_name, matric_no))
|
65 |
+
row = cursor.fetchone()
|
66 |
+
|
67 |
+
conn.close()
|
68 |
+
if row:
|
69 |
+
columns = [col[0] for col in cursor.description]
|
70 |
+
return dict(zip(columns, row))
|
71 |
+
else:
|
72 |
+
return None
|
73 |
+
|
74 |
+
|
75 |
+
if __name__ == '__main__':
|
76 |
+
create_db('students_database.db', pd.read_csv('students_df.csv'))
|
helper_fns.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import io
|
2 |
+
import cv2
|
3 |
+
import time
|
4 |
+
from PIL import Image
|
5 |
+
|
6 |
+
|
7 |
+
# Function to convert PIL image to binary
|
8 |
+
def pil_to_binary(img):
|
9 |
+
with io.BytesIO() as output:
|
10 |
+
img.save(output, format="PNG")
|
11 |
+
return output.getvalue()
|
12 |
+
|
13 |
+
|
14 |
+
def binary_to_pil(binary):
|
15 |
+
return Image.open(io.BytesIO(binary))
|
16 |
+
|
17 |
+
|
18 |
+
def crop_image(image_array, x, y, w, h):
|
19 |
+
return image_array[y: y + h, x: x + w]
|
20 |
+
|
21 |
+
|
22 |
+
def extract_faces(image_one, image_two, results):
|
23 |
+
image_one_results = results['facial_areas']['img1']
|
24 |
+
cropped_image_one = crop_image(image_one,
|
25 |
+
image_one_results['x'],
|
26 |
+
image_one_results['y'],
|
27 |
+
image_one_results['w'],
|
28 |
+
image_one_results['h'],)
|
29 |
+
|
30 |
+
image_two_results = results['facial_areas']['img2']
|
31 |
+
cropped_image_two = crop_image(image_two,
|
32 |
+
image_two_results['x'],
|
33 |
+
image_two_results['y'],
|
34 |
+
image_two_results['w'],
|
35 |
+
image_two_results['h'],)
|
36 |
+
|
37 |
+
return Image.fromarray(cropped_image_one).resize((480, 480)), Image.fromarray(cropped_image_two).resize((480, 480))
|
38 |
+
|
39 |
+
def read_image_from_webcam():
|
40 |
+
#initialize webcam
|
41 |
+
cap = cv2.VideoCapture(0)
|
42 |
+
|
43 |
+
if not cap.isOpened():
|
44 |
+
print(f'Error could not open webcam')
|
45 |
+
return None
|
46 |
+
else:
|
47 |
+
print(f'Webcam opened successfully!')
|
48 |
+
#wait for 5 seconds
|
49 |
+
time.sleep(5)
|
50 |
+
_, frame = cap.read()
|
51 |
+
#Image.fromarray
|
52 |
+
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
53 |
+
cap.release()
|
54 |
+
return rgb_frame
|
main.py
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import warnings
|
3 |
+
|
4 |
+
os.environ['TF_ENABLE_ONEDNN_OPTS']=str(0)
|
5 |
+
warnings.filterwarnings('ignore')
|
6 |
+
|
7 |
+
#import pandas as pd
|
8 |
+
import numpy as np
|
9 |
+
|
10 |
+
from deepface import DeepFace
|
11 |
+
from db import create_db, get_student_row
|
12 |
+
from helper_fns import binary_to_pil, extract_faces
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
def verify_student(db_path, last_name, matric_no, input_image):
|
18 |
+
data = get_student_row(db_path, last_name, matric_no)
|
19 |
+
|
20 |
+
if data is not None:
|
21 |
+
binary_image = data['image']
|
22 |
+
else:
|
23 |
+
raise ValueError('No student having last name {last_name} and matric no: {matric_no} exists in this database.')
|
24 |
+
actual_image =np.array(binary_to_pil(binary_image))
|
25 |
+
|
26 |
+
webcam_image = input_image
|
27 |
+
if webcam_image is None:
|
28 |
+
raise ValueError(f'No image')
|
29 |
+
else:
|
30 |
+
print('Received image')
|
31 |
+
results = DeepFace.verify(webcam_image,
|
32 |
+
actual_image,
|
33 |
+
model_name='Facenet',
|
34 |
+
detector_backend="retinaface",
|
35 |
+
distance_metric="cosine",
|
36 |
+
enforce_detection=True,
|
37 |
+
anti_spoofing=True,
|
38 |
+
align=True,
|
39 |
+
normalization="Facenet")
|
40 |
+
result = results['verified']
|
41 |
+
if results['verified'] == True:
|
42 |
+
result = f"Verification check complete! Successfully verified student: {data['last_name']} {data['first_name']} with matriculation number {data['matric_no']}"
|
43 |
+
else:
|
44 |
+
result = f"Verification check complete! You are not student {data['last_name']} {data['first_name']} with matriculation number {data['matric_no']}"
|
45 |
+
|
46 |
+
cropped_input_image, cropped_returned_image = extract_faces(webcam_image, actual_image, results)
|
47 |
+
return result, cropped_input_image, cropped_returned_image, actual_image
|
48 |
+
|
49 |
+
|
50 |
+
def main(last_name, matric_no, input_image):
|
51 |
+
|
52 |
+
#df = pd.read_csv('students_df.csv')
|
53 |
+
db_path = 'students_database.db'
|
54 |
+
#create_db(db_path, df)
|
55 |
+
|
56 |
+
result, cropped_input_image, cropped_returned_image, actual_image = verify_student(db_path,
|
57 |
+
last_name,
|
58 |
+
matric_no,
|
59 |
+
input_image)
|
60 |
+
|
61 |
+
#os.remove('students_database.db')
|
62 |
+
return result, cropped_input_image, cropped_returned_image, actual_image
|
63 |
+
|
64 |
+
if __name__ == '__main__':
|
65 |
+
main()
|
students_database.db
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:7a7bcbb8dd37f20a6e74dd5d4263487170db4e4af64707510d1cf32093257159
|
3 |
+
size 18714624
|