Spaces:
Sleeping
Sleeping
File size: 4,666 Bytes
742eac0 1fb58c9 742eac0 1fb58c9 742eac0 1fb58c9 742eac0 00485bf 742eac0 1fb58c9 742eac0 1fb58c9 742eac0 00485bf 742eac0 1fb58c9 742eac0 d8bd926 742eac0 1fb58c9 742eac0 1fb58c9 742eac0 1fb58c9 742eac0 1fb58c9 |
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 |
import os
import random
from datetime import datetime
from PIL import Image
import pickle
import torch
import pandas as pd
import requests
from facenet_pytorch import MTCNN, InceptionResnetV1
from scipy.spatial.distance import cosine
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename
import numpy as np
import tempfile
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads/'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
mtcnn = MTCNN(keep_all=True, thresholds=[0.5, 0.6, 0.6], min_face_size=15)
model = InceptionResnetV1(pretrained='vggface2').eval()
def convert_image_format(input_path, output_format='PNG'):
try:
image = Image.open(input_path)
if hasattr(image, '_getexif'):
exif = image._getexif()
orientation = exif.get(0x112) if exif else None
rotations = {3: 180, 6: 270, 8: 90}
if orientation in rotations:
image = image.rotate(rotations[orientation], expand=True)
output_path = os.path.splitext(input_path)[0] + '.' + output_format.lower()
image.convert('RGB').save(output_path, format=output_format)
return output_path
except Exception as e:
logger.error("Error converting image format: %s", e, exc_info=True)
return None
def load_embeddings(model_file):
with open(model_file, 'rb') as f:
return pickle.load(f)
def compare_faces(embedding, dataset, threshold=0.5):
embedding /= np.linalg.norm(embedding)
best, name = float('inf'), None
for person, embeds in dataset.items():
for known in embeds:
known = known / np.linalg.norm(known)
dist = cosine(embedding, known.flatten())
if dist < best:
best, name = dist, person
return name if best < threshold else None
def load_id_mapping(excel_file):
df = pd.read_excel(excel_file)
return {row['Name']: row['ID'] for _, row in df.iterrows()}
def process_image(path):
dataset = load_embeddings('data/face_model.pkl')
mapping = load_id_mapping('data/test.xlsx')
path = convert_image_format(path)
if not path:
return {'error': 'Conversion failed'}
try:
img = Image.open(path).convert('RGB')
except Exception as e:
return {'error': str(e)}
faces, probs = mtcnn(img, return_prob=True)
results, unknown = [], 0
if faces is not None:
for face, p in zip(faces, probs):
if p < 0.9:
continue
face = (face - 0.5) / 0.5
emb = model(face.unsqueeze(0)).detach().cpu().numpy().flatten()
person = compare_faces(emb, dataset)
if person:
sid = mapping.get(person, 'ID not found')
logger.info("Matched student - ID: %s, Name: %s", sid, person)
results.append({'Student Name': person, 'ID': sid})
status, resp = send_attendance_to_external_api(sid)
logger.info("Attendance: %s - %s", status, resp)
else:
unknown += 1
if unknown:
results.append({'unknown_faces': unknown})
else:
results.append({'message': 'No faces detected'})
return results
@app.route('/recognize_faces', methods=['POST'])
def recognize_faces_endpoint():
logger.info("Received request on /recognize_faces endpoint")
if 'file' not in request.files:
return jsonify({'error': 'No file provided'}), 400
f = request.files['file']
filename = f"face{random.randint(1, 1000)}.jpg"
temp_dir = tempfile.gettempdir()
full = os.path.join(temp_dir, filename)
f.save(full)
logger.info("Saved uploaded file to %s", full)
return jsonify(process_image(full))
def send_attendance_to_external_api(student_id):
url = 'http://54.242.19.19:3000/api/attendance'
rid = random.randint(1, 1000)
payload = {
'id': str(rid),
'studentId': str(student_id),
'status': 'present',
'date': datetime.now().strftime('%m/%d/%Y %I:%M:%S %p +00:00'),
'teacherID': "5005"
}
logger.info("Sending payload: %s", payload)
try:
r = requests.post(url, json=payload)
try:
return r.status_code, r.json()
except Exception as json_err:
return r.status_code, {'error': 'Invalid JSON', 'raw': r.text}
except Exception as e:
logger.error("Attendance error: %s", e, exc_info=True)
return 500, {'error': str(e)}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)
|