Spaces:
Sleeping
Sleeping
File size: 4,743 Bytes
46db57a 6073a09 46db57a 6073a09 46db57a 6073a09 46db57a 6073a09 46db57a | 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 | 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/"
os.makedirs(dataset_path, exist_ok=True)
# KNN distance
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 system
class AttendanceSystem:
def __init__(self):
self.file = "attendance.csv"
self.columns = ["Name", "Date", "Time"]
if not os.path.exists(self.file):
pd.DataFrame(columns=self.columns).to_csv(self.file, index=False)
def mark(self, name):
today = datetime.now().strftime("%Y-%m-%d")
now = datetime.now().strftime("%H:%M:%S")
df = pd.read_csv(self.file)
existing = df[(df["Name"] == name) & (df["Date"] == today)]
if existing.empty:
new_entry = pd.DataFrame([[name, today, now]], columns=self.columns)
df = pd.concat([df, new_entry], ignore_index=True)
df.to_csv(self.file, index=False)
return True
return False
attendance = AttendanceSystem()
# Home page
@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
# Modified register_face endpoint with preprocessing
@app.route('/api/register_face', methods=['POST'])
def register_face():
data = request.json
name = data['name']
images = data['images'] # List of base64 images
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) # Histogram equalization
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))
# Original face
face_data.append(face.flatten())
# Data augmentation: horizontal flip
flipped_face = cv2.flip(face, 1)
face_data.append(flipped_face.flatten())
if face_data:
face_data = np.array(face_data)
np.save(os.path.join(dataset_path, f"{name}.npy"), face_data)
return jsonify({"status": "success", "message": f"{len(face_data)} faces saved"})
else:
return jsonify({"status": "fail", "message": "No faces detected"})
# API to mark attendance
@app.route('/api/mark_attendance', methods=['POST'])
def mark_attendance():
img_data = request.json['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)
# Load training data
face_data = []
labels = []
names = {}
class_id = 0
for file in os.listdir(dataset_path):
if file.endswith('.npy'):
data = np.load(os.path.join(dataset_path, file))
face_data.append(data)
names[class_id] = file[:-4]
labels.extend([class_id] * data.shape[0])
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)
name = names.get(pred_id, "Unknown")
if name != "Unknown":
marked = attendance.mark(name)
msg = "Attendance marked" if marked else "Already marked today"
return jsonify({"status": "success", "name": name, "message": msg})
return jsonify({"status": "fail", "message": "No known face detected"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)
|