|
import os |
|
import streamlit as st |
|
from huggingface_hub import HfApi |
|
from PIL import Image |
|
import sqlite3 |
|
import cv2 |
|
import numpy as np |
|
from tensorflow.keras.models import load_model |
|
from datetime import datetime |
|
|
|
|
|
HOME_DIR = os.getcwd() |
|
DATABASE = "students.db" |
|
REPO_NAME = "face-and-emotion-detection" |
|
REPO_ID = f"LovnishVerma/{REPO_NAME}" |
|
EMOTION_MODEL_FILE = "CNN_Model_acc_75.h5" |
|
EMOTION_LABELS = ["Angry", "Disgust", "Fear", "Happy", "Sad", "Surprise", "Neutral"] |
|
|
|
|
|
hf_token = os.getenv("upload") |
|
if not hf_token: |
|
st.error("Hugging Face token not found. Please set the environment variable.") |
|
st.stop() |
|
|
|
|
|
api = HfApi() |
|
try: |
|
api.create_repo(repo_id=REPO_ID, repo_type="space", space_sdk="streamlit", token=hf_token, exist_ok=True) |
|
st.success(f"Repository '{REPO_NAME}' is ready on Hugging Face!") |
|
except Exception as e: |
|
st.error(f"Error creating Hugging Face repository: {e}") |
|
|
|
|
|
try: |
|
|
|
if not os.path.exists(EMOTION_MODEL_FILE): |
|
st.error(f"Error: Emotion model file '{EMOTION_MODEL_FILE}' not found!") |
|
st.stop() |
|
|
|
|
|
emotion_model = load_model(EMOTION_MODEL_FILE) |
|
st.success("Emotion detection model loaded successfully!") |
|
except Exception as e: |
|
st.error(f"Error loading emotion model: {e}") |
|
st.stop() |
|
|
|
|
|
def initialize_database(): |
|
""" Initializes the SQLite database by creating the students table if it doesn't exist. """ |
|
conn = sqlite3.connect(DATABASE) |
|
cursor = conn.cursor() |
|
cursor.execute(""" |
|
CREATE TABLE IF NOT EXISTS students ( |
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
name TEXT NOT NULL, |
|
roll_no TEXT NOT NULL UNIQUE, |
|
image_url TEXT NOT NULL, |
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP |
|
) |
|
""") |
|
conn.commit() |
|
conn.close() |
|
|
|
def save_to_database(name, roll_no, image_url): |
|
""" Saves the student's data to the database. """ |
|
conn = sqlite3.connect(DATABASE) |
|
cursor = conn.cursor() |
|
try: |
|
cursor.execute(""" |
|
INSERT INTO students (name, roll_no, image_url) |
|
VALUES (?, ?, ?) |
|
""", (name, roll_no, image_url)) |
|
conn.commit() |
|
st.success("Data saved successfully!") |
|
except sqlite3.IntegrityError: |
|
st.error("Roll number already exists!") |
|
finally: |
|
conn.close() |
|
|
|
def save_image_to_hugging_face(image, name, roll_no): |
|
""" Saves the image locally to the HOME_DIR and uploads it to Hugging Face. """ |
|
|
|
filename = f"{name}_{roll_no}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg" |
|
local_path = os.path.join(HOME_DIR, filename) |
|
|
|
try: |
|
|
|
if image.mode != "RGB": |
|
image = image.convert("RGB") |
|
|
|
|
|
image.save(local_path) |
|
|
|
|
|
api.upload_file( |
|
path_or_fileobj=local_path, |
|
path_in_repo=filename, |
|
repo_id=REPO_ID, |
|
repo_type="space", |
|
token=hf_token, |
|
) |
|
|
|
|
|
image_url = f"https://{REPO_NAME}.hf.space/media/{filename}" |
|
st.success(f"Image saved to Hugging Face as {filename}. URL: {image_url}") |
|
|
|
except Exception as e: |
|
st.error(f"Error saving or uploading image: {e}") |
|
|
|
return image_url |
|
|
|
|
|
initialize_database() |
|
|
|
|
|
st.title("Student Registration with Hugging Face Image Upload") |
|
|
|
|
|
name = st.text_input("Enter your name") |
|
roll_no = st.text_input("Enter your roll number") |
|
|
|
|
|
capture_mode = st.radio("Choose an option to upload your image", ["Use Webcam", "Upload File"]) |
|
|
|
|
|
if capture_mode == "Use Webcam": |
|
picture = st.camera_input("Take a picture") |
|
elif capture_mode == "Upload File": |
|
picture = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"]) |
|
|
|
|
|
if st.button("Register"): |
|
if not name or not roll_no: |
|
st.error("Please fill in both name and roll number.") |
|
elif not picture: |
|
st.error("Please upload or capture an image.") |
|
else: |
|
try: |
|
|
|
if capture_mode == "Use Webcam" and picture: |
|
image = Image.open(picture) |
|
elif capture_mode == "Upload File" and picture: |
|
image = Image.open(picture) |
|
|
|
|
|
image_url = save_image_to_hugging_face(image, name, roll_no) |
|
save_to_database(name, roll_no, image_url) |
|
except Exception as e: |
|
st.error(f"An error occurred: {e}") |
|
|
|
|
|
if st.checkbox("Show registered students"): |
|
conn = sqlite3.connect(DATABASE) |
|
cursor = conn.cursor() |
|
cursor.execute("SELECT name, roll_no, image_url, timestamp FROM students") |
|
rows = cursor.fetchall() |
|
conn.close() |
|
|
|
st.write("### Registered Students") |
|
for row in rows: |
|
name, roll_no, image_url, timestamp = row |
|
st.write(f"**Name:** {name}, **Roll No:** {roll_no}, **Timestamp:** {timestamp}") |
|
st.image(image_url, caption=f"{name} ({roll_no})", use_column_width=True) |
|
|
|
|
|
def detect_faces_and_emotions(image): |
|
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) |
|
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') |
|
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.3, minNeighbors=5) |
|
|
|
for (x, y, w, h) in faces: |
|
face = gray_image[y:y+h, x:x+w] |
|
resized_face = cv2.resize(face, (48, 48)) |
|
rgb_face = cv2.cvtColor(resized_face, cv2.COLOR_GRAY2RGB) |
|
normalized_face = rgb_face / 255.0 |
|
reshaped_face = np.reshape(normalized_face, (1, 48, 48, 3)) |
|
|
|
|
|
emotion_prediction = emotion_model.predict(reshaped_face) |
|
emotion_label = np.argmax(emotion_prediction) |
|
return EMOTION_LABELS[emotion_label] |
|
return None |
|
|
|
|
|
if st.sidebar.selectbox("Menu", ["Register Student", "Face Recognition and Emotion Detection", "View Attendance"]) == "Face Recognition and Emotion Detection": |
|
st.subheader("Recognize Faces and Detect Emotions") |
|
action = st.radio("Choose Action", ["Upload Image", "Use Webcam"]) |
|
|
|
if action == "Upload Image": |
|
uploaded_file = st.file_uploader("Upload Image", type=["jpg", "jpeg", "png"]) |
|
if uploaded_file: |
|
img = Image.open(uploaded_file) |
|
img_array = np.array(img) |
|
emotion_label = detect_faces_and_emotions(img_array) |
|
if emotion_label: |
|
st.success(f"Emotion Detected: {emotion_label}") |
|
else: |
|
st.warning("No face detected.") |
|
|
|
elif action == "Use Webcam": |
|
st.info("Use the camera input widget to capture an image.") |
|
camera_image = st.camera_input("Take a picture") |
|
if camera_image: |
|
img = Image.open(camera_image) |
|
img_array = np.array(img) |
|
emotion_label = detect_faces_and_emotions(img_array) |
|
if emotion_label: |
|
st.success(f"Emotion Detected: {emotion_label}") |
|
else: |
|
st.warning("No face detected.") |
|
|