LovnishVerma commited on
Commit
94a1319
·
verified ·
1 Parent(s): ea0580a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -206
app.py CHANGED
@@ -1,219 +1,150 @@
1
- import os
2
- import sqlite3
3
  import streamlit as st
4
- from PIL import Image
5
- import numpy as np
6
  import cv2
7
- import dlib
 
8
  from keras.models import load_model
9
- from datetime import datetime
10
- from huggingface_hub import HfApi
 
 
11
 
12
  # Constants
13
- KNOWN_FACES_DIR = "known_faces" # Directory to save user images
14
- DATABASE = "students.db" # SQLite database file to store student information
 
 
 
15
 
16
- # Ensure the directory exists
17
  os.makedirs(KNOWN_FACES_DIR, exist_ok=True)
18
 
19
- # Initialize Hugging Face API
20
- hf_token = os.getenv("upload") # Ensure this is set correctly as a secret in Hugging Face
21
- if not hf_token:
22
- raise ValueError("Hugging Face token not found. Ensure it's set as a secret in Hugging Face")
23
- api = HfApi()
24
-
25
- # Repository Details on Hugging Face
26
- REPO_NAME = "face_and_emotion_detection" # Replace with your Hugging Face repository name
27
- REPO_ID = "LovnishVerma/" + REPO_NAME # Replace "LovnishVerma" with your Hugging Face username
28
- REPO_TYPE = "space" # 'space' type for Streamlit-based projects
29
-
30
- # Load emotion detection model
31
- model = load_model('CNN_Model_acc_75.h5')
32
- emotion_labels = ['angry', 'fear', 'happy', 'neutral', 'sad', 'surprise']
33
- face_detector = dlib.get_frontal_face_detector() # Use Dlib's face detector
34
- face_predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # Landmarks model for face recognition
35
- face_rec_model = dlib.face_recognition_model_v1('dlib_face_recognition_resnet_model_v1.dat') # Face recognition model
36
-
37
- # Initialize the SQLite database
38
- def initialize_database():
39
- conn = sqlite3.connect(DATABASE)
40
- cursor = conn.cursor()
41
- cursor.execute("""
42
- CREATE TABLE IF NOT EXISTS students (
43
- id INTEGER PRIMARY KEY AUTOINCREMENT,
44
- name TEXT NOT NULL,
45
- roll_no TEXT NOT NULL UNIQUE,
46
- image_path TEXT NOT NULL,
47
- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
48
- )
49
- """)
50
- conn.commit()
51
- conn.close()
52
-
53
- # Save student information in the SQLite database
54
- def save_to_database(name, roll_no, image_path):
55
- conn = sqlite3.connect(DATABASE)
56
- cursor = conn.cursor()
57
- try:
58
  cursor.execute("""
59
- INSERT INTO students (name, roll_no, image_path)
60
- VALUES (?, ?, ?)
61
- """, (name, roll_no, image_path))
 
 
 
 
62
  conn.commit()
63
- st.success("Data saved successfully!")
 
 
 
 
 
 
 
64
  except sqlite3.IntegrityError:
65
- st.error("Roll number already exists!")
66
- finally:
67
- conn.close()
68
-
69
- # Save the captured image locally in known_faces directory and upload to Hugging Face
70
- def save_image_to_hugging_face(image, name, roll_no):
71
- # Create a filename based on the student name and roll number
72
- filename = f"{name}_{roll_no}.jpg"
73
- local_path = os.path.join(KNOWN_FACES_DIR, filename)
74
-
75
- # Save the image locally
76
- image.save(local_path)
77
- st.success(f"Image saved locally to {local_path}")
78
-
79
  try:
80
- # Upload the image to Hugging Face repository
81
- api.upload_file(
82
- path_or_fileobj=local_path,
83
- path_in_repo=filename,
84
- repo_id=REPO_ID,
85
- repo_type=REPO_TYPE,
86
- token=hf_token
87
- )
88
- st.success(f"Image uploaded to Hugging Face: {filename}")
89
  except Exception as e:
90
- st.error(f"Error uploading image to Hugging Face: {e}")
91
-
92
- return local_path
93
-
94
- # Process each frame for emotion detection and face recognition
95
- def process_frame(frame, known_face_encodings, known_face_names):
96
- gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
97
- faces = face_detector(gray_frame)
98
-
99
- face_locations = []
100
- face_encodings = []
101
- face_names = []
102
- for face in faces:
103
- # Get the landmarks of the face
104
- shape = face_predictor(gray_frame, face)
105
- face_encoding = np.array(face_rec_model.compute_face_descriptor(frame, shape))
106
-
107
- # Check if the detected face matches any known face
108
- matches = [np.allclose(face_encoding, known_encoding) for known_encoding in known_face_encodings]
109
- name = "Unknown"
110
-
111
- if True in matches:
112
- first_match_index = matches.index(True)
113
- name = known_face_names[first_match_index]
114
-
115
- # Emotion detection
116
- roi_color = frame[face.top():face.bottom(), face.left():face.right()]
117
- face_roi = cv2.resize(roi_color, (48, 48))
118
- face_roi = np.expand_dims(face_roi, axis=0)
119
- face_roi = face_roi / float(48)
120
- predictions = model.predict(face_roi)
121
- emotion = emotion_labels[np.argmax(predictions[0])]
122
-
123
- # Display name and emotion text on face
124
- cv2.rectangle(frame, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 2)
125
- cv2.putText(frame, f"{name} - {emotion}", (face.left(), face.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
126
-
127
- return frame
128
-
129
- # User Interface for registration
130
- st.title("Student Registration and Attendance")
131
-
132
- # Initialize the database and create the table if it does not exist
133
- initialize_database()
134
-
135
- # Load known faces from the database
136
- known_face_encodings = []
137
- known_face_names = []
138
-
139
- conn = sqlite3.connect(DATABASE)
140
- cursor = conn.cursor()
141
- cursor.execute("SELECT name, image_path FROM students")
142
- rows = cursor.fetchall()
143
-
144
- for row in rows:
145
- name, image_path = row
146
- image = Image.open(image_path)
147
- encoding = dlib.face_recognition_model_v1.compute_face_descriptor(image)[0]
148
- known_face_encodings.append(encoding)
149
- known_face_names.append(name)
150
-
151
- conn.close()
152
-
153
- # Choose input method for the image (webcam or file upload)
154
- capture_mode = st.radio("Choose an option to upload your image", ["Use Webcam", "Upload File"])
155
-
156
- if capture_mode == "Use Webcam":
157
- picture = st.camera_input("Take a picture") # Capture image using webcam
158
- elif capture_mode == "Upload File":
159
- picture = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
160
-
161
- # Input fields for student details
162
- name = st.text_input("Enter your name")
163
- roll_no = st.text_input("Enter your roll number")
164
-
165
- # Handle image upload or webcam capture
166
- if st.button("Register"):
167
- if not name or not roll_no:
168
- st.error("Please fill in both name and roll number.")
169
- elif not picture:
170
- st.error("Please upload or capture an image.")
171
- else:
172
- try:
173
- # Open the image based on capture mode
174
- if capture_mode == "Use Webcam" and picture:
175
- image = Image.open(picture)
176
- elif capture_mode == "Upload File" and picture:
177
- image = Image.open(picture)
178
-
179
- # Save the image locally and upload it to Hugging Face
180
- image_path = save_image_to_hugging_face(image, name, roll_no)
181
-
182
- # Save user data to the database
183
- save_to_database(name, roll_no, image_path)
184
-
185
- # Update the known faces list
186
- known_face_encodings.append(dlib.face_recognition_model_v1.compute_face_descriptor(image)[0])
187
- known_face_names.append(name)
188
-
189
- st.success(f"Student {name} registered successfully!")
190
-
191
- except Exception as e:
192
- st.error(f"An error occurred: {e}")
193
-
194
- # Detect faces and emotions from webcam
195
- cap = cv2.VideoCapture(0)
196
- while True:
197
- ret, frame = cap.read()
198
- if not ret:
199
- break
200
-
201
- frame = process_frame(frame, known_face_encodings, known_face_names)
202
- st.image(frame, channels="BGR", use_column_width=True)
203
- break # Stop after capturing one frame
204
-
205
- cap.release()
206
-
207
- # Display registered students and attendance history
208
- if st.checkbox("Show registered students"):
209
- conn = sqlite3.connect(DATABASE)
210
- cursor = conn.cursor()
211
- cursor.execute("SELECT name, roll_no, image_path, timestamp FROM students")
212
- rows = cursor.fetchall()
213
- conn.close()
214
-
215
- st.write("### Registered Students")
216
- for row in rows:
217
- name, roll_no, image_path, timestamp = row
218
- st.write(f"**Name:** {name}, **Roll No:** {roll_no}, **Timestamp:** {timestamp}")
219
- st.image(image_path, caption=f"{name} ({roll_no})", use_column_width=True)
 
 
 
1
  import streamlit as st
 
 
2
  import cv2
3
+ import os
4
+ import numpy as np
5
  from keras.models import load_model
6
+ from PIL import Image
7
+ import sqlite3
8
+ import requests
9
+ from io import BytesIO
10
 
11
  # Constants
12
+ DB_FILE = "students.db"
13
+ KNOWN_FACES_DIR = "known_faces"
14
+ EMOTION_MODEL_FILE = "CNN_Model_acc_75.h5"
15
+ HUGGING_FACE_TOKEN = os.getenv("HUGGING_FACE_TOKEN")
16
+ HUGGING_FACE_REPO = "username/repo_name"
17
 
18
+ # Create directories
19
  os.makedirs(KNOWN_FACES_DIR, exist_ok=True)
20
 
21
+ # Load models
22
+ try:
23
+ emotion_model = load_model(EMOTION_MODEL_FILE)
24
+ except Exception as e:
25
+ st.error(f"Error loading emotion model: {e}")
26
+
27
+ # Database Functions
28
+ def create_table():
29
+ with sqlite3.connect(DB_FILE) as conn:
30
+ cursor = conn.cursor()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  cursor.execute("""
32
+ CREATE TABLE IF NOT EXISTS students (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+ name TEXT NOT NULL,
35
+ roll_number TEXT NOT NULL UNIQUE,
36
+ image_path TEXT NOT NULL
37
+ )
38
+ """)
39
  conn.commit()
40
+
41
+ def insert_student(name, roll_number, image_path):
42
+ try:
43
+ with sqlite3.connect(DB_FILE) as conn:
44
+ cursor = conn.cursor()
45
+ cursor.execute("INSERT INTO students (name, roll_number, image_path) VALUES (?, ?, ?)",
46
+ (name, roll_number, image_path))
47
+ conn.commit()
48
  except sqlite3.IntegrityError:
49
+ st.warning("Roll number already exists!")
50
+
51
+ # Hugging Face Functions
52
+ def upload_to_hugging_face(file_path, file_name):
53
+ if not HUGGING_FACE_TOKEN:
54
+ st.error("Hugging Face token not found.")
55
+ return
56
+
57
+ url = f"https://huggingface.co/api/repos/{HUGGING_FACE_REPO}/uploads/{file_name}"
58
+ headers = {"Authorization": f"Bearer {HUGGING_FACE_TOKEN}"}
59
+
 
 
 
60
  try:
61
+ with open(file_path, "rb") as file:
62
+ response = requests.post(url, headers=headers, files={"file": file})
63
+ if response.status_code == 200:
64
+ st.success(f"Uploaded {file_name} to Hugging Face!")
65
+ else:
66
+ st.error(f"Failed to upload: {response.content}")
 
 
 
67
  except Exception as e:
68
+ st.error(f"Error uploading file: {e}")
69
+
70
+ # Image Processing Functions
71
+ def detect_faces_and_emotions(image):
72
+ gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
73
+ face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
74
+ faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.3, minNeighbors=5)
75
+
76
+ for (x, y, w, h) in faces:
77
+ face = gray_image[y:y+h, x:x+w]
78
+ resized_face = cv2.resize(face, (48, 48))
79
+ normalized_face = resized_face / 255.0
80
+ reshaped_face = np.reshape(normalized_face, (1, 48, 48, 1))
81
+ emotion_prediction = emotion_model.predict(reshaped_face)
82
+ emotion_label = np.argmax(emotion_prediction)
83
+ return emotion_label
84
+
85
+ return None
86
+
87
+ # UI Design
88
+ st.title("Student Registration and Emotion Detection")
89
+ create_table()
90
+
91
+ menu = ["Register Student", "Face Recognition and Emotion Detection"]
92
+ choice = st.sidebar.selectbox("Menu", menu)
93
+
94
+ if choice == "Register Student":
95
+ st.subheader("Register a New Student")
96
+
97
+ with st.form("register_form"):
98
+ name = st.text_input("Name")
99
+ roll_number = st.text_input("Roll Number")
100
+ image_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"])
101
+ submitted = st.form_submit_button("Register")
102
+
103
+ if submitted:
104
+ if name and roll_number and image_file:
105
+ try:
106
+ img = Image.open(image_file)
107
+ img_path = os.path.join(KNOWN_FACES_DIR, f"{roll_number}.png")
108
+ img.save(img_path)
109
+ insert_student(name, roll_number, img_path)
110
+ upload_to_hugging_face(img_path, f"{roll_number}.png")
111
+ st.success("Student Registered Successfully!")
112
+ except Exception as e:
113
+ st.error(f"Error: {e}")
114
+ else:
115
+ st.warning("Please fill in all fields and upload an image.")
116
+
117
+ elif choice == "Face Recognition and Emotion Detection":
118
+ st.subheader("Recognize Faces and Detect Emotions")
119
+
120
+ action = st.radio("Choose Action", ["Upload Image", "Use Webcam"])
121
+
122
+ if action == "Upload Image":
123
+ uploaded_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"])
124
+ if uploaded_file:
125
+ try:
126
+ img = Image.open(uploaded_file)
127
+ img_array = np.array(img)
128
+ emotion_label = detect_faces_and_emotions(img_array)
129
+ if emotion_label is not None:
130
+ st.success(f"Emotion Detected: {emotion_label}")
131
+ else:
132
+ st.warning("No face detected.")
133
+ except Exception as e:
134
+ st.error(f"Error: {e}")
135
+
136
+ elif action == "Use Webcam":
137
+ cap = cv2.VideoCapture(0)
138
+ if st.button("Start Webcam"):
139
+ while True:
140
+ ret, frame = cap.read()
141
+ if not ret:
142
+ break
143
+ emotion_label = detect_faces_and_emotions(frame)
144
+ if emotion_label is not None:
145
+ st.success(f"Emotion Detected: {emotion_label}")
146
+ cv2.imshow("Webcam", frame)
147
+ if cv2.waitKey(1) & 0xFF == ord('q'):
148
+ break
149
+ cap.release()
150
+ cv2.destroyAllWindows()