0% found this document useful (0 votes)
3 views9 pages

Tkinter Entry with Placeholder for Students

The document describes a Python application using Tkinter for student data entry and face recognition. It includes functionalities for uploading images, capturing images from a webcam, saving student data, training a face recognition model, and taking attendance. The application utilizes MTCNN for face detection, FaceNet for face embedding, and SVM for classification, with data stored in CSV format.

Uploaded by

phungmr311204
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views9 pages

Tkinter Entry with Placeholder for Students

The document describes a Python application using Tkinter for student data entry and face recognition. It includes functionalities for uploading images, capturing images from a webcam, saving student data, training a face recognition model, and taking attendance. The application utilizes MTCNN for face detection, FaceNet for face embedding, and SVM for classification, with data stored in CSV format.

Uploaded by

phungmr311204
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import tkinter as tk

from tkinter import ttk, messagebox, filedialog


import cv2 as cv
import os
import numpy as np
from [Link] import MTCNN
from keras_facenet import FaceNet
from [Link] import LabelEncoder
from [Link] import SVC
from sklearn.model_selection import train_test_split
from [Link] import accuracy_score
import pickle
import uuid
import time
import shutil
import csv

class StudentDataApp([Link]):
def __init__(self):
super().__init__()
[Link]("Student Data Entry & Recognition")
[Link]("800x600")

# Initialize face recognition components


[Link] = MTCNN()
[Link] = FaceNet()
[Link] = LabelEncoder()
[Link] = None # Placeholder for SVM model

# Initialize image paths


self.image_paths = []

# Load existing face embeddings and labels


self.load_existing_data()

# Create Tab Control


self.tab_control = [Link](self)

# Create Tabs
self.data_entry_tab = [Link](self.tab_control)
self.attendance_tab = [Link](self.tab_control)

# Add Tabs to Tab Control


self.tab_control.add(self.data_entry_tab, text='Data Entry')
self.tab_control.add(self.attendance_tab, text='Attendance')

# Pack Tab Control


self.tab_control.pack(expand=1, fill='both')

# Initialize UI for Data Entry Tab


self.init_data_entry_ui()

# Initialize UI for Attendance Tab


self.init_attendance_ui()

def enable_train_if_dataset_exists(self):
DATASET_PATH = "dataset"
if [Link](DATASET_PATH) and any([Link](DATASET_PATH)):
self.train_button.config(state=[Link])

def init_data_entry_ui(self):
# ID Label and Entry
self.label_id = [Link](self.data_entry_tab, text="Student ID:")
self.label_id.pack(pady=5)
self.entry_id = [Link](self.data_entry_tab)
self.entry_id.pack(pady=5)

# Name Label and Entry


self.label_name = [Link](self.data_entry_tab, text="Student Name:")
self.label_name.pack(pady=5)
self.entry_name = [Link](self.data_entry_tab)
self.entry_name.pack(pady=5)

# Image Listbox
self.label_image = [Link](self.data_entry_tab, text="Selected Images:")
self.label_image.pack(pady=5)
self.listbox_images = [Link](self.data_entry_tab, height=8)
self.listbox_images.pack(pady=5)

# Upload Button
self.upload_button = [Link](self.data_entry_tab, text="Upload Images",
command=self.upload_images)
self.upload_button.pack(pady=5)

# Capture Button
self.capture_button = [Link](self.data_entry_tab, text="Capture
Images", command=self.capture_images)
self.capture_button.pack(pady=5)

# Save Button
self.save_button = [Link](self.data_entry_tab, text="Save",
command=self.save_data)
self.save_button.pack(pady=20)

# Train Button
self.train_button = [Link](self.data_entry_tab, text="Train New
Student", command=self.train_new_student,
state=[Link])
self.train_button.pack(pady=10)

self.enable_train_if_dataset_exists()

# Face Recognition Button


self.face_recognition_button = [Link](self.data_entry_tab, text="Face
Recognition",
command=self.face_recognition)
self.face_recognition_button.pack(pady=5)

def init_attendance_ui(self):
# Course Label and Entry
self.label_course = [Link](self.attendance_tab, text="Course:")
self.label_course.pack(pady=5)
self.entry_course = [Link](self.attendance_tab)
self.entry_course.pack(pady=5)

# Date Label and Entry


self.label_date = [Link](self.attendance_tab, text="Date (YYYY-MM-DD):")
self.label_date.pack(pady=5)
self.entry_date = [Link](self.attendance_tab)
self.entry_date.pack(pady=5)

# Attendance Button
self.attendance_button = [Link](self.attendance_tab, text="Take
Attendance", command=self.take_attendance)
self.attendance_button.pack(pady=10)

# Attendance Table
self.attendance_table = [Link](self.attendance_tab, columns=('ID',
'Name', 'Date', 'Time'),
show='headings')
self.attendance_table.heading('ID', text='ID')
self.attendance_table.heading('Name', text='Name')
self.attendance_table.heading('Date', text='Date')
self.attendance_table.heading('Time', text='Time')
self.attendance_table.pack(padx=10, pady=10)

def load_existing_data(self):
# Load existing face embeddings and labels if available
if [Link]('faces_embeddings_done_4classes.npz'):
data = [Link]('faces_embeddings_done_4classes.npz')
self.X = data['arr_0']
self.Y = data['arr_1']
[Link](self.Y) # Fit label encoder
else:
self.X = [Link]((0, 160, 160, 3))
self.Y = [Link]([])

def upload_images(self):
file_paths = [Link](
title="Select Images",
filetypes=[("Image files", "*.jpg *.jpeg *.png")]
)
if file_paths:
self.image_paths.extend(file_paths)
for path in file_paths:
# Copy the uploaded image to dataset/id folder
student_id = self.entry_id.get()
if not student_id:
[Link]("Input Error", "Please enter the Student
ID before uploading images.")
return

IMAGES_PATH = [Link]("dataset", student_id)


[Link](IMAGES_PATH, exist_ok=True)

dest_path = [Link](IMAGES_PATH, [Link](path))


try:
[Link](path, dest_path)
self.listbox_images.insert([Link], [Link](dest_path))
except Exception as e:
[Link]("Error", f"Error copying file: {str(e)}")

def capture_images(self):
student_id = self.entry_id.get()
student_name = self.entry_name.get()
if not student_id or not student_name:
[Link]("Input Error", "Please enter both Student ID and
Name before capturing images.")
return

IMAGES_PATH = [Link]("dataset", student_id)


[Link](IMAGES_PATH, exist_ok=True)

number_images = 10
cap = [Link](0)

if not [Link]():
[Link]("Error", "Cannot open camera.")
return

captured_image_paths = []

for imgnum in range(number_images):


ret, frame = [Link]()
if not ret:
[Link]("Error", "Failed to capture image.")
break

imgname = [Link](IMAGES_PATH, f'{str(uuid.uuid1())}.jpg')


[Link](imgname, frame)
captured_image_paths.append(imgname)

[Link]('frame', frame)
if [Link](1) & 0xFF == ord('q'):
break
[Link](0.5)

[Link]()
[Link]()

self.image_paths.extend(captured_image_paths)
for path in captured_image_paths:
self.listbox_images.insert([Link], [Link](path))

def save_data(self):
student_id = self.entry_id.get()
student_name = self.entry_name.get()

if not student_id or not student_name or not self.image_paths:


[Link]("Input Error", "Please enter ID, Name, and
select images.")
return

try:
# Save student data to CSV
csv_file = 'student_data.csv'
if not [Link](csv_file):
with open(csv_file, mode='w', newline='') as file:
writer = [Link](file)
[Link](['ID', 'Name', 'ImagePath'])

# Write the student information


with open(csv_file, mode='a', newline='') as file:
writer = [Link](file)
[Link]([student_id, student_name, self.image_paths[0]]) #
Save the first image path

# Update UI state
self.train_button.config(state=[Link]) # Enable train button after
saving

# Clear the input fields and image listbox


self.entry_id.delete(0, [Link])
self.entry_name.delete(0, [Link])
self.listbox_images.delete(0, [Link])
self.image_paths = []

[Link]("Success", "Student data saved successfully.")

except Exception as e:
[Link]("Error", f"Error saving data: {str(e)}")

def train_new_student(self):
class FACELOADING:
def __init__(self, directory):
[Link] = directory
[Link] = MTCNN()
self.target_size = (160, 160)
self.X = []
self.Y = []

def extract_face(self, filename):


try:
img = [Link](filename)
img_rgb = [Link](img, cv.COLOR_BGR2RGB)
results = [Link].detect_faces(img_rgb)
if results:
x1, y1, width, height = results[0]['box']
x2, y2 = x1 + width, y1 + height
face = img_rgb[y1:y2, x1:x2]
image = [Link](face, self.target_size)
return image
except Exception as e:
print(f"Error extracting face: {str(e)}")
return None

def load_faces(self, subdir):


faces = []
y = subdir
subdir_full = [Link]([Link], subdir)
for filename in [Link](subdir_full):
path = [Link](subdir_full, filename)
face = self.extract_face(path)
if face is not None:
[Link](face)
return faces, y

def load_dataset(self):
for subdir in [Link]([Link]):
subdir_full = [Link]([Link], subdir)
if not [Link](subdir_full):
continue
faces, y = self.load_faces(subdir)
labels = [y] * len(faces)
print(f'Loaded {len(faces)} examples for class: {y}')
[Link](faces)
[Link](labels)
return [Link](self.X), [Link](self.Y)

directory = "dataset"
faceloading = FACELOADING(directory)
self.X, self.Y = faceloading.load_dataset()

[Link](self.Y)
Y = [Link](self.Y)
[Link] = SVC(kernel='linear', probability=True)

faces = [Link](self.X)
print("Shape of faces:", [Link]) # Phải là (N, 160, 160, 3)
print("Faces dtype:", [Link])
faces = [Link]('float32')

# Kiểm tra shape, nếu không đúng thì báo lỗi và dừng lại
if [Link] != 4 or [Link][-1] != 3:
raise Exception("faces shape không đúng, cần (N, 160, 160, 3)")

# Trích xuất embedding cho cả batch


X = [Link](faces) # shape (N, 512)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2,


random_state=42)

[Link](X_train, Y_train)
Y_pred = [Link](X_test)
accuracy = accuracy_score(Y_test, Y_pred)

[Link]("Training Complete", f"Model trained with accuracy:


{accuracy * 100:.2f}%")

with open('svm_model_160x160.pkl', 'wb') as file:


[Link]([Link], file)

def face_recognition(self):
cap = [Link](0)
if not [Link]():
[Link]("Error", "Cannot open camera.")
return

with open('svm_model_160x160.pkl', 'rb') as file:


[Link] = [Link](file)

while True:
ret, frame = [Link]()
if not ret:
[Link]("Error", "Failed to capture image.")
break

frame_rgb = [Link](frame, cv.COLOR_BGR2RGB)


faces = [Link].detect_faces(frame_rgb)
for result in faces:
x1, y1, width, height = result['box']
x2, y2 = x1 + width, y1 + height
face = frame_rgb[y1:y2, x1:x2]
face = [Link](face, (160, 160))
face_emb = [Link](face[[Link], :])
face_emb = face_emb / [Link](face_emb, axis=1,
keepdims=True)
probs = [Link].predict_proba(face_emb)[0]
best_idx = [Link](probs)
confidence = probs[best_idx]
if confidence < 0.7:
pred_name = "Unknown"
else:
pred_name = [Link].inverse_transform([best_idx])[0]
label = f"{pred_name} ({confidence * 100:.1f}%)"

[Link](frame, (x1, y1), (x2, y2), (0, 255, 0), 2)


[Link](frame, label, (x1, y1 - 10), cv.FONT_HERSHEY_SIMPLEX,
0.9, (0, 255, 0), 2)

[Link]('Face Recognition', frame)


if [Link](1) & 0xFF == ord('q'):
break

[Link]()
[Link]()

def take_attendance(self):
course = self.entry_course.get()
date = self.entry_date.get()

if not course or not date:


[Link]("Input Error", "Please enter both Course and
Date.")
return

# Create the course folder if it doesn't exist


course_folder = [Link]('attendance', course)
[Link](course_folder, exist_ok=True)

# File path for the attendance CSV


file_path = [Link](course_folder, f"{date}.csv")

# Load student data from CSV


student_data = {}
with open('student_data.csv', mode='r') as file:
reader = [Link](file)
for row in reader:
student_data[row['ID']] = row['Name']

cap = [Link](0)
if not [Link]():
[Link]("Error", "Cannot open camera.")
return

with open('svm_model_160x160.pkl', 'rb') as file:


[Link] = [Link](file)

attendance_records = []
recorded_students = set() # To keep track of recorded student IDs
while True:
ret, frame = [Link]()
if not ret:
[Link]("Error", "Failed to capture image.")
break

frame_rgb = [Link](frame, cv.COLOR_BGR2RGB)


faces = [Link].detect_faces(frame_rgb)
for result in faces:
x1, y1, width, height = result['box']
x2, y2 = x1 + width, y1 + height
face = frame_rgb[y1:y2, x1:x2]
face = [Link](face, (160, 160))
face_emb = [Link](face[[Link], :])
face_emb = face_emb / [Link](face_emb, axis=1,
keepdims=True)
probs = [Link].predict_proba(face_emb)[0]
best_idx = [Link](probs)
confidence = probs[best_idx]
if confidence < 0.7:
pred_id = "Unknown"
pred_name = "Unknown"
else :
pred_id = [Link].inverse_transform([best_idx])[0]
# Use student ID to get the student name
pred_name = student_data.get(pred_id, "Unknown")

# Draw bounding box and label on the image


[Link](frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
[Link](frame, pred_name, (x1, y1 - 10),
cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

# Check if the student has already been recorded


if pred_id not in recorded_students:
# Record attendance
current_time = [Link]("%H:%M:%S")
attendance_records.append([pred_id, pred_name, date,
current_time, f"{confidence*100:.1f}%"])

# Add the student ID to the set


recorded_students.add(pred_id)

[Link]('Face Recognition', frame)


if [Link](1) & 0xFF == ord('q'):
break

[Link]()
[Link]()

# Save attendance records to CSV


with open(file_path, mode='w', newline='') as file:
writer = [Link](file)
[Link](['ID', 'Name', 'Date', 'Time', 'Confidence'])
[Link](attendance_records)

# Update attendance table


self.update_attendance_table(file_path)
def update_attendance_table(self, attendance_file):
for row in self.attendance_table.get_children():
self.attendance_table.delete(row)

with open(attendance_file, mode='r') as file:


reader = [Link](file)
next(reader) # Skip header row
for row in reader:
self.attendance_table.insert("", [Link], values=row)

# Run the application


if __name__ == "__main__":
app = StudentDataApp()
[Link]()

You might also like