Spaces:
Running
Running
File size: 10,018 Bytes
4e74bb5 |
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 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# # app.py
# import os
# import base64
# import uuid
# from flask import Flask, request, jsonify, render_template
# from flask_cors import CORS
# from haversine import haversine, Unit
# from deepface import DeepFace
# # --- Flask App Initialization ---
# app = Flask(__name__)
# # CORS is needed to allow communication between the server and the frontend.
# # It's good practice to restrict origins in a production environment.
# CORS(app)
# # --- Configuration & Data ---
# # In a real app, this data would come from a database.
# CLASS_LOCATIONS = {
# "CS101": {
# "name": "Computer Science Building, Room 101",
# "lat": 16.7953091,
# "lon": 80.8228997
# },
# "PHY203": {
# "name": "Physics Hall, Room 203",
# "lat": 40.712776,
# "lon": -74.005974
# }
# }
# # The allowed distance in meters from the class location.
# # Note: 9 meters is a very strict radius.
# LOCATION_RADIUS_METERS = 900000000
# # The path to the reference image for face verification.
# # Ensure 'reference.jpg' is in the same directory as this script.
# REFERENCE_IMG_PATH = "WIN_20250906_10_34_24_Pro.jpg"
# if not os.path.exists(REFERENCE_IMG_PATH):
# raise FileNotFoundError(f"Reference image not found at '{REFERENCE_IMG_PATH}'")
# # --- Route for serving the frontend ---
# @app.route('/')
# def index():
# """Renders the main HTML page."""
# return render_template('index.html')
# # --- API Endpoint for Location Verification ---
# @app.route('/verify-location', methods=['POST'])
# def handle_verify_location():
# """
# Verifies if the user's coordinates are within the allowed radius for a class.
# """
# data = request.json
# class_id = data.get('class_id')
# user_lat = data.get('latitude')
# user_lon = data.get('longitude')
# if not all([class_id, user_lat, user_lon]):
# return jsonify({"status": "error", "message": "Missing class_id, latitude, or longitude."}), 400
# class_info = CLASS_LOCATIONS.get(class_id)
# if not class_info:
# return jsonify({"status": "error", "message": f"Class ID '{class_id}' not found."}), 404
# # Calculate distance
# class_location = (class_info["lat"], class_info["lon"])
# user_location = (float(user_lat), float(user_lon))
# distance = haversine(class_location, user_location, unit=Unit.METERS)
# if distance <= LOCATION_RADIUS_METERS:
# print(f"SUCCESS: Location verified for '{class_id}'. Distance: {distance:.2f}m.")
# return jsonify({
# "status": "success",
# "message": f"Location verified. You are {distance:.2f} meters from the class."
# })
# else:
# print(f"FAILURE: User is too far for '{class_id}'. Distance: {distance:.2f}m.")
# return jsonify({
# "status": "failure",
# "message": f"Attendance denied. You are {distance:.2f} meters away from the class location."
# })
# # --- API Endpoint for Face Verification ---
# @app.route('/verify-face', methods=['POST'])
# def handle_verify_face():
# """
# Verifies the captured face image against the reference image.
# Expects a base64 encoded image string.
# """
# data = request.json
# image_data_url = data.get('image')
# if not image_data_url:
# return jsonify({"status": "error", "message": "No image data received."}), 400
# try:
# # Decode the base64 image
# header, encoded = image_data_url.split(",", 1)
# image_bytes = base64.b64decode(encoded)
# # Save to a temporary file for DeepFace to process
# captured_img_path = f"{uuid.uuid4()}.jpg"
# with open(captured_img_path, "wb") as f:
# f.write(image_bytes)
# # Perform face verification
# result = DeepFace.verify(
# img1_path=REFERENCE_IMG_PATH,
# img2_path=captured_img_path,
# model_name="Facenet",
# enforce_detection=False # Be more lenient if a face isn't perfectly centered
# )
# # Clean up the temporary file
# os.remove(captured_img_path)
# if result["verified"]:
# print("SUCCESS: Face verification successful.")
# return jsonify({"status": "success", "message": "Face verified successfully."})
# else:
# print("FAILURE: Face verification failed.")
# return jsonify({"status": "failure", "message": "Face does not match. Attendance denied."})
# except Exception as e:
# print(f"An error occurred during face verification: {e}")
# # If a temp file was created before the error, try to remove it
# if 'captured_img_path' in locals() and os.path.exists(captured_img_path):
# os.remove(captured_img_path)
# return jsonify({"status": "error", "message": "Could not process the image. Please try again."}), 500
# # --- Main Execution ---
# if __name__ == '__main__':
# # Use host='0.0.0.0' to make it accessible on your local network
# app.run(host='0.0.0.0', port=5000, debug=True)
# app.py
import os
import base64
import uuid
# --- MEMORY OPTIMIZATION FOR TENSORFLOW (THE FIX) ---
# These lines MUST be at the top, before importing deepface
import tensorflow as tf
# Configure TensorFlow to be less memory-intensive by using single-threaded operations.
# This is crucial for free-tier deployment environments.
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)
# ---------------------------------------------------
from flask import Flask, request, jsonify, render_template
from flask_cors import CORS
from haversine import haversine, Unit
from deepface import DeepFace
# --- Flask App Initialization ---
app = Flask(__name__)
CORS(app)
# --- Configuration & Data ---
CLASS_LOCATIONS = {
"CS101": {
"name": "Computer Science Building, Room 101",
"lat": 16.7953091,
"lon": 80.8228997
}
}
# Using a larger radius for testing based on your previous logs. Adjust as needed.hlo
LOCATION_RADIUS_METERS = 38061
REFERENCE_IMG_PATH = "reference.jpg"
if not os.path.exists(REFERENCE_IMG_PATH):
print(f"WARNING: Reference image not found at '{REFERENCE_IMG_PATH}'.")
# --- MODEL WARM-UP FUNCTION ---
def load_initial_model():
"""
Forces DeepFace to download and load the model into memory once when the
server starts, preventing timeouts on the first user request.
"""
print("Pre-loading FaceNet model...")
try:
_ = DeepFace.represent(img_path=REFERENCE_IMG_PATH, model_name="Facenet", enforce_detection=False)
print("FaceNet model pre-loaded successfully.")
except Exception as e:
print(f"Error pre-loading model: Could not find face in reference image or another error occurred. {e}")
# The app will still run, but the first /verify-face call might be slow.
# Call the warm-up function when the application starts
load_initial_model()
# --- Routes ---
@app.route('/')
def index():
"""Renders the main HTML page."""
return render_template('index.html')
# (The rest of your app.py file remains exactly the same...)
# ... @app.route('/verify-location') ...
# ... @app.route('/verify-face') ...
# ... if __name__ == '__main__': ...
@app.route('/verify-location', methods=['POST'])
def handle_verify_location():
"""Verifies user's coordinates are within the allowed radius."""
data = request.json
class_id = data.get('class_id')
user_lat = data.get('latitude')
user_lon = data.get('longitude')
if not all([class_id, user_lat, user_lon]):
return jsonify({"status": "error", "message": "Missing required location data."}), 400
class_info = CLASS_LOCATIONS.get(class_id)
if not class_info:
return jsonify({"status": "error", "message": f"Class ID '{class_id}' not found."}), 404
class_location = (class_info["lat"], class_info["lon"])
user_location = (float(user_lat), float(user_lon))
distance = haversine(class_location, user_location, unit=Unit.METERS)
if distance <= LOCATION_RADIUS_METERS:
return jsonify({
"status": "success",
"message": f"Location verified. You are {distance:.2f} meters from the class."
})
else:
return jsonify({
"status": "failure",
"message": f"Attendance denied. You are {distance:.2f} meters away."
})
@app.route('/verify-face', methods=['POST'])
def handle_verify_face():
"""Verifies a captured face image against the reference image."""
data = request.json
image_data_url = data.get('image')
if not image_data_url:
return jsonify({"status": "error", "message": "No image data received."}), 400
if not os.path.exists(REFERENCE_IMG_PATH):
return jsonify({"status": "error", "message": "Server error: Reference image is missing."}), 500
captured_img_path = ""
try:
header, encoded = image_data_url.split(",", 1)
image_bytes = base64.b64decode(encoded)
captured_img_path = f"{uuid.uuid4()}.jpg"
with open(captured_img_path, "wb") as f:
f.write(image_bytes)
result = DeepFace.verify(
img1_path=REFERENCE_IMG_PATH,
img2_path=captured_img_path,
model_name="Facenet",
enforce_detection=False
)
if result["verified"]:
return jsonify({"status": "success", "message": "Face verified successfully."})
else:
return jsonify({"status": "failure", "message": "Face does not match. Attendance denied."})
except Exception as e:
print(f"An error occurred during face verification: {e}")
return jsonify({"status": "error", "message": "Could not process the image."}), 500
finally:
if os.path.exists(captured_img_path):
os.remove(captured_img_path)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True) |