Spaces:
Sleeping
Sleeping
File size: 6,341 Bytes
8f825da 17e462b 8f825da db13789 17e462b db13789 17e462b 8f825da 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b db13789 17e462b 8f825da db13789 8f825da |
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 |
from flask import Flask, render_template, request, Response, jsonify
import cv2
import os
import numpy as np
import pickle
from datetime import datetime
# --- Flask App ---
app = Flask(__name__)
FACE_DATA_DIR = 'face_data'
FACE_CASCADE_PATH = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
if not os.path.exists(FACE_DATA_DIR):
os.makedirs(FACE_DATA_DIR)
face_cascade = cv2.CascadeClassifier(FACE_CASCADE_PATH)
camera = None
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
is_trained = False
has_webcam = os.path.exists("/dev/video0") # deteksi webcam di server
def load_face_data():
global is_trained
faces, labels, names = [], [], []
if os.path.exists(os.path.join(FACE_DATA_DIR, 'names.pkl')):
with open(os.path.join(FACE_DATA_DIR, 'names.pkl'), 'rb') as f:
names = pickle.load(f)
for idx, name in enumerate(names):
face_dir = os.path.join(FACE_DATA_DIR, name)
if os.path.exists(face_dir):
for filename in os.listdir(face_dir):
if filename.endswith('.jpg'):
img_path = os.path.join(face_dir, filename)
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
faces.append(img)
labels.append(idx)
if faces:
face_recognizer.train(faces, np.array(labels))
is_trained = True
return names
return []
def get_camera():
global camera
if has_webcam:
if camera is None:
camera = cv2.VideoCapture(0)
return camera
return None
@app.route('/')
def index():
names = load_face_data()
return render_template('index.html', registered_faces=names, has_webcam=has_webcam)
@app.route('/register')
def register():
return render_template('register.html', has_webcam=has_webcam)
@app.route('/recognize')
def recognize():
return render_template('recognize.html', has_webcam=has_webcam)
@app.route('/video_feed')
def video_feed():
if not has_webcam:
return "Webcam tidak tersedia di server ini", 404
def generate():
cam = get_camera()
while True:
success, frame = cam.read()
if not success:
break
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
return Response(generate(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/recognition_feed')
def recognition_feed():
if not has_webcam:
return "Webcam tidak tersedia di server ini", 404
def generate():
cam = get_camera()
names = load_face_data()
while True:
success, frame = cam.read()
if not success:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
if is_trained and names:
roi_gray = gray[y:y+h, x:x+w]
roi_gray = cv2.resize(roi_gray, (100, 100))
id_, confidence = face_recognizer.predict(roi_gray)
if confidence < 100:
name = names[id_]
confidence_text = f"{name} ({round(100-confidence)}%)"
else:
confidence_text = "Unknown"
cv2.putText(frame, confidence_text, (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
return Response(generate(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/capture_face', methods=['POST'])
def capture_face():
if has_webcam:
name = request.json.get('name', '').strip()
if not name:
return jsonify({'error': 'Nama tidak boleh kosong'})
cam = get_camera()
success, frame = cam.read()
if not success:
return jsonify({'error': 'Gagal mengambil gambar dari kamera'})
return save_face(name, frame)
else:
return jsonify({'error': 'Webcam tidak tersedia, gunakan /upload_face'})
@app.route('/upload_face', methods=['POST'])
def upload_face():
name = request.form.get('name', '').strip()
file = request.files.get('file')
if not name:
return jsonify({'error': 'Nama tidak boleh kosong'})
if not file:
return jsonify({'error': 'File tidak ditemukan'})
np_img = np.frombuffer(file.read(), np.uint8)
frame = cv2.imdecode(np_img, cv2.IMREAD_COLOR)
return save_face(name, frame)
def save_face(name, frame):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) == 0:
return jsonify({'error': 'Tidak ada wajah yang terdeteksi'})
if len(faces) > 1:
return jsonify({'error': 'Terdeteksi lebih dari satu wajah'})
(x, y, w, h) = faces[0]
face_roi = gray[y:y+h, x:x+w]
face_roi = cv2.resize(face_roi, (100, 100))
person_dir = os.path.join(FACE_DATA_DIR, name)
if not os.path.exists(person_dir):
os.makedirs(person_dir)
filename = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
cv2.imwrite(os.path.join(person_dir, filename), face_roi)
names_file = os.path.join(FACE_DATA_DIR, 'names.pkl')
if os.path.exists(names_file):
with open(names_file, 'rb') as f:
names = pickle.load(f)
else:
names = []
if name not in names:
names.append(name)
with open(names_file, 'wb') as f:
pickle.dump(names, f)
load_face_data()
return jsonify({'success': f'Wajah {name} berhasil didaftarkan'})
# --- Wrapper untuk Hugging Face ---
from fastapi import FastAPI
from starlette.middleware.wsgi import WSGIMiddleware
flask_app = app
asgi_app = FastAPI()
asgi_app.mount("/", WSGIMiddleware(flask_app))
if __name__ == '__main__':
flask_app.run(debug=True, host='0.0.0.0', port=5000)
|