File size: 6,891 Bytes
f837deb
c7b74ee
 
6361d4f
 
 
f837deb
4ebde4b
bbe4d10
6361d4f
f837deb
 
bbe4d10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f837deb
6361d4f
f837deb
989395e
f837deb
 
 
 
6361d4f
f837deb
 
6361d4f
f837deb
 
6361d4f
 
3ab75c1
 
6361d4f
3ab75c1
 
 
 
 
 
6361d4f
3ab75c1
6361d4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ab75c1
 
f837deb
6361d4f
 
 
 
 
 
 
 
 
f837deb
6361d4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f837deb
 
3ab75c1
6361d4f
 
 
f837deb
6361d4f
 
 
 
f837deb
bbe4d10
f837deb
 
bbe4d10
 
 
 
 
 
 
 
f837deb
6361d4f
 
 
 
9e9e8ca
 
 
f837deb
 
 
6361d4f
 
f837deb
 
 
 
 
 
 
 
 
6361d4f
f837deb
 
 
 
 
 
 
 
 
 
 
6361d4f
f837deb
 
 
 
 
 
 
 
6361d4f
f837deb
 
 
 
 
 
11be9ed
897e20a
 
 
 
 
 
6c75ef2
897e20a
 
 
 
 
c2d845c
6c75ef2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import streamlit as st
import cv2
import numpy as np
from datetime import datetime
import torch
from facenet_pytorch import MTCNN, InceptionResnetV1
from keras.models import load_model
from PIL import Image
import sqlite3
import os
import tempfile

# SQLite Database Connection
DB_NAME = "emotion_detection.db"

# Initialize SQLite Database
def initialize_database():
    conn = sqlite3.connect(DB_NAME)
    cursor = conn.cursor()
    cursor.execute("""
    CREATE TABLE IF NOT EXISTS face_data (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        emotion TEXT NOT NULL,
        timestamp TEXT NOT NULL
    )
    """)
    conn.commit()
    conn.close()

initialize_database()

# Page title
st.markdown("<h1 style='text-align: center;'>Emotion Detection with Face Recognition</h1>", unsafe_allow_html=True)
st.markdown("<h3 style='text-align: center;'>angry, fear, happy, neutral, sad, surprise</h3>", unsafe_allow_html=True)

# Load the emotion detection model
@st.cache_resource
def load_emotion_model():
    model = load_model('CNN_Model_acc_75.h5')  # Ensure this file is present
    return model

emotion_model = load_emotion_model()
emotion_labels = ['angry', 'fear', 'happy', 'neutral', 'sad', 'surprise']

# Initialize FaceNet model and MTCNN
facenet = InceptionResnetV1(pretrained='vggface2').eval()
mtcnn = MTCNN()

# Known faces and embeddings
known_faces = []
known_names = []

def load_known_faces():
    folder_path = "known_faces"  # Folder containing known face images
    for image_name in os.listdir(folder_path):
        if image_name.endswith(('.jpg', '.jpeg', '.png')):
            image_path = os.path.join(folder_path, image_name)
            image = Image.open(image_path).convert("RGB")
            face, _ = mtcnn.detect(image)

            if face is not None:
                face_box = face[0].astype(int)
                cropped_face = image.crop((face_box[0], face_box[1], face_box[2], face_box[3]))
                cropped_face = cropped_face.resize((160, 160))
                face_tensor = np.array(cropped_face).transpose(2, 0, 1) / 255.0
                face_tensor = torch.tensor(face_tensor, dtype=torch.float32).unsqueeze(0)
                
                with torch.no_grad():
                    embedding = facenet(face_tensor).numpy()
                
                known_faces.append(embedding)
                known_names.append(image_name.split('.')[0])

load_known_faces()

def recognize_face(embedding):
    min_distance = float('inf')
    name = "Unknown"
    for idx, known_embedding in enumerate(known_faces):
        distance = np.linalg.norm(known_embedding - embedding)
        if distance < min_distance and distance < 0.6:  # Threshold for similarity
            min_distance = distance
            name = known_names[idx]
    return name

def process_frame(frame):
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    faces, _ = mtcnn.detect(frame_rgb)
    result_text = ""

    if faces is not None:
        for face_box in faces:
            x1, y1, x2, y2 = map(int, face_box)
            cropped_face = frame_rgb[y1:y2, x1:x2]
            resized_face = cv2.resize(cropped_face, (48, 48))
            face_normalized = resized_face / 255.0
            face_array = np.expand_dims(face_normalized, axis=0)

            # Emotion prediction
            predictions = emotion_model.predict(face_array)
            emotion = emotion_labels[np.argmax(predictions[0])]

            # Face recognition
            cropped_face_for_recognition = cv2.resize(cropped_face, (160, 160))
            face_tensor = np.array(cropped_face_for_recognition).transpose(2, 0, 1) / 255.0
            face_tensor = torch.tensor(face_tensor, dtype=torch.float32).unsqueeze(0)

            with torch.no_grad():
                face_embedding = facenet(face_tensor).numpy()

            name = recognize_face(face_embedding)

            # Save record in SQLite
            if name != "Unknown":
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                conn = sqlite3.connect(DB_NAME)
                cursor = conn.cursor()
                cursor.execute("""
                INSERT INTO face_data (name, emotion, timestamp)
                VALUES (?, ?, ?)
                """, (name, emotion, timestamp))
                conn.commit()
                conn.close()

            # Display result
            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
            result_text = f"{name} is feeling {emotion}"
            cv2.putText(frame, result_text, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
    else:
        result_text = "No face detected!"

    return frame, result_text

def video_feed(video_source):
    frame_placeholder = st.empty()
    text_placeholder = st.empty()

    while True:
        ret, frame = video_source.read()
        if not ret:
            break
        frame, result_text = process_frame(frame)
        frame_placeholder.image(frame, channels="BGR", use_column_width=True)
        text_placeholder.markdown(f"<h3 style='text-align: center;'>{result_text}</h3>", unsafe_allow_html=True)

# Sidebar for input source
upload_choice = st.sidebar.radio("Choose Input Source", ["Upload Image", "Upload Video", "Camera"])

if upload_choice == "Camera":
    image = st.camera_input("Take a picture")
    if image:
        frame = np.array(Image.open(image))
        frame, result_text = process_frame(frame)
        st.image(frame, caption='Processed Image', use_column_width=True)
        st.markdown(f"<h3 style='text-align: center;'>{result_text}</h3>", unsafe_allow_html=True)

elif upload_choice == "Upload Image":
    uploaded_image = st.file_uploader("Upload Image", type=["png", "jpg", "jpeg"])
    if uploaded_image:
        image = Image.open(uploaded_image)
        frame = np.array(image)
        frame, result_text = process_frame(frame)
        st.image(frame, caption='Processed Image', use_column_width=True)
        st.markdown(f"<h3 style='text-align: center;'>{result_text}</h3>", unsafe_allow_html=True)

elif upload_choice == "Upload Video":
    uploaded_video = st.file_uploader("Upload Video", type=["mp4", "mov", "avi"])
    if uploaded_video:
        with tempfile.NamedTemporaryFile(delete=False) as tfile:
            tfile.write(uploaded_video.read())
            video_source = cv2.VideoCapture(tfile.name)
            video_feed(video_source)

#Display recent SQLite records
st.markdown("### Recent Records")
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT name, emotion, timestamp FROM face_data ORDER BY timestamp DESC LIMIT 5")
records = cursor.fetchall()
conn.close()

for record in records:
    col1, col2, col3 = st.columns(3)
    col1.write(f"**Name**: {record[0]}")
    col2.write(f"**Emotion**: {record[1]}")
    col3.write(f"**Timestamp**: {record[2]}")