SAS2 / app.py
harshdhane's picture
Update app.py
a996970 verified
Raw
History Blame Contribute Delete
6.71 kB
from flask import Flask, render_template, request, jsonify
import os
import cv2
import numpy as np
import pandas as pd
from datetime import datetime
import base64
app = Flask(__name__)
# Setup
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
dataset_path = "./face_dataset/"
attendance_path = "./attendance_data/"
os.makedirs(dataset_path, exist_ok=True)
os.makedirs(attendance_path, exist_ok=True)
# KNN distance utility
def distance(v1, v2):
return np.sqrt(((v1 - v2) ** 2).sum())
def knn(train, test, k=5):
dist = []
for i in range(train.shape[0]):
ix = train[i, :-1]
iy = train[i, -1]
d = distance(test, ix)
dist.append([d, iy])
dk = sorted(dist, key=lambda x: x[0])[:k]
labels = np.array(dk)[:, -1]
return np.unique(labels, return_counts=True)[0][0]
# Attendance management per class
class AttendanceSystem:
def __init__(self, class_name):
self.class_name = class_name
self.file = os.path.join(attendance_path, f"{class_name}.xlsx")
self.columns = ["Enrollment", "Name", "Date", "CheckIn", "CheckOut"]
if not os.path.exists(self.file):
df = pd.DataFrame(columns=self.columns)
df.to_excel(self.file, index=False)
def checkin(self, enrollment, name):
today = datetime.now().strftime("%Y-%m-%d")
now = datetime.now().strftime("%H:%M:%S")
df = pd.read_excel(self.file)
existing = df[(df["Enrollment"] == enrollment) & (df["Date"] == today)]
if existing.empty:
new_entry = pd.DataFrame([[enrollment, name, today, now, ""]], columns=self.columns)
df = pd.concat([df, new_entry], ignore_index=True)
df.to_excel(self.file, index=False)
return True, "Check-in successful"
return False, "Already checked in"
def checkout(self, enrollment):
today = datetime.now().strftime("%Y-%m-%d")
now = datetime.now().strftime("%H:%M:%S")
df = pd.read_excel(self.file)
idx = df[(df["Enrollment"] == enrollment) & (df["Date"] == today)].index
if idx.empty:
return False, "Please check-in first"
row = df.loc[idx[0]]
if pd.isna(row["CheckOut"]) or row["CheckOut"] == "":
df.at[idx[0], "CheckOut"] = now
df.to_excel(self.file, index=False)
return True, "Check-out successful"
return False, "Already checked out"
# Routes
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register')
def register():
return render_template('register.html')
@app.route('/mark')
def mark():
return render_template('mark.html')
# API to save face during registration
@app.route('/api/register_face', methods=['POST'])
def register_face():
data = request.json
class_name = data['class_name']
name = data['name']
enrollment = data['enrollment']
images = data['images'] # List of base64 images
class_folder = os.path.join(dataset_path, class_name)
os.makedirs(class_folder, exist_ok=True)
face_data = []
for img_data in images:
img_bytes = base64.b64decode(img_data.split(",")[1])
np_arr = np.frombuffer(img_bytes, np.uint8)
img = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.equalizeHist(gray)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces[:1]:
face = img[y:y+h, x:x+w]
face = cv2.resize(face, (100, 100))
face_data.append(face.flatten())
flipped = cv2.flip(face, 1)
face_data.append(flipped.flatten())
if face_data:
face_data = np.array(face_data)
filename = f"{enrollment}_{name}.npy"
np.save(os.path.join(class_folder, filename), face_data)
return jsonify({"status": "success", "message": f"{len(face_data)} faces saved"})
return jsonify({"status": "fail", "message": "No faces detected"})
# API to identify face without marking
@app.route('/api/identify_face', methods=['POST'])
def identify_face():
data = request.json
class_name = data['class_name']
img_data = data['image']
img_bytes = base64.b64decode(img_data.split(",")[1])
np_arr = np.frombuffer(img_bytes, np.uint8)
img = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
class_folder = os.path.join(dataset_path, class_name)
if not os.path.exists(class_folder):
return jsonify({"status": "fail", "message": "No data for this class"})
# Load training data for this class
face_data = []
labels = []
names = {}
class_id = 0
for file in os.listdir(class_folder):
if file.endswith('.npy'):
data_arr = np.load(os.path.join(class_folder, file))
face_data.append(data_arr)
parts = file[:-4].split('_', 1)
labels.extend([class_id] * data_arr.shape[0])
names[class_id] = {'enrollment': parts[0], 'name': parts[1]}
class_id += 1
if not face_data:
return jsonify({"status": "fail", "message": "No trained data found"})
X_train = np.concatenate(face_data, axis=0)
y_train = np.array(labels).reshape(-1, 1)
trainset = np.hstack((X_train, y_train))
for (x, y, w, h) in faces[:1]:
face = img[y:y+h, x:x+w]
face = cv2.resize(face, (100, 100)).flatten()
pred_id = knn(trainset, face)
info = names.get(pred_id)
if info:
return jsonify({
"status": "success",
"name": info['name'],
"enrollment": info['enrollment']
})
return jsonify({"status": "fail", "message": "Face not recognized"})
# API to check-in
@app.route('/api/checkin', methods=['POST'])
def api_checkin():
data = request.json
class_name = data['class_name']
enrollment = data['enrollment']
name = data['name']
attendance = AttendanceSystem(class_name)
ok, msg = attendance.checkin(enrollment, name)
status = "success" if ok else "fail"
return jsonify({"status": status, "message": msg})
# API to check-out
@app.route('/api/checkout', methods=['POST'])
def api_checkout():
data = request.json
class_name = data['class_name']
enrollment = data['enrollment']
attendance = AttendanceSystem(class_name)
ok, msg = attendance.checkout(enrollment)
status = "success" if ok else "fail"
return jsonify({"status": status, "message": msg})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)