- Interactive mission selector with metadata-driven design - 5 educational missions (basics + advanced) - AI assistant roles (Deepbit, Bugsy, Schnippsi, Tobi) - SnakeCam gesture recognition system - Token tracking utilities - CLAUDE.md documentation - .gitignore for logs and secrets
73 lines
2.2 KiB
Plaintext
Executable File
73 lines
2.2 KiB
Plaintext
Executable File
from flask import Flask, render_template, Response, request, redirect
|
|
import cv2
|
|
import datetime
|
|
import json
|
|
from gestures_debug import detect_hand_gesture
|
|
|
|
app = Flask(__name__)
|
|
|
|
def gen_frames():
|
|
cam = cv2.VideoCapture(0)
|
|
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
|
|
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
|
|
|
|
if not cam.isOpened():
|
|
print("[WARNUNG] Kamera konnte nicht geöffnet werden.")
|
|
return
|
|
|
|
try:
|
|
while True:
|
|
success, frame = cam.read()
|
|
if not success:
|
|
break
|
|
|
|
# Flip horizontal für Spiegelbild
|
|
frame = cv2.flip(frame, 1)
|
|
|
|
# Geste erkennen
|
|
gesture, roi = detect_hand_gesture(frame)
|
|
if isinstance(roi, tuple) and len(roi) == 4:
|
|
x, y, w, h = roi
|
|
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
|
|
cv2.putText(frame, gesture, (x, y - 10),
|
|
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
|
|
|
|
# Frame in JPEG konvertieren
|
|
ret, buffer = cv2.imencode('.jpg', frame)
|
|
frame_bytes = buffer.tobytes()
|
|
|
|
# MJPEG-Stream liefern
|
|
yield (b'--frame\r\n'
|
|
b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
|
|
finally:
|
|
cam.release()
|
|
print("[info] Kamera wurde sauber freigegeben.")
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return render_template('index.html')
|
|
|
|
@app.route('/video_feed')
|
|
def video_feed():
|
|
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
|
|
|
|
@app.route('/log_answer', methods=['POST'])
|
|
def log_answer():
|
|
data = {
|
|
"timestamp": datetime.datetime.now().isoformat(),
|
|
"antwort": request.form.get("antwort", ""),
|
|
"mood": request.form.get("mood", ""),
|
|
"gesture": request.form.get("gesture", "")
|
|
}
|
|
|
|
with open("snake_log.jsonl", "a") as f:
|
|
f.write(json.dumps(data) + "\n")
|
|
|
|
return redirect("/")
|
|
|
|
if __name__ == '__main__':
|
|
print("[SnakeCam] Initialisierung beginnt...")
|
|
print("[SnakeCam] Imports erfolgreich.")
|
|
print("[SnakeCam] Starte Flask Webserver ...")
|
|
app.run(host='0.0.0.0', port=5000)
|