KRISH09bha commited on
Commit
dea3c82
·
verified ·
1 Parent(s): 77f612d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -0
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import torch
4
+ import base64
5
+ import asyncio
6
+ from collections import deque
7
+ from ultralytics import YOLO
8
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect
9
+ import uvicorn
10
+
11
+ # Load YOLO model with optimized settings
12
+ device = "cuda" if torch.cuda.is_available() else "cpu"
13
+ model = YOLO("yolov11s-face.pt").to(device)
14
+
15
+ # Constants for distance estimation
16
+ KNOWN_DISTANCE = 50 # cm
17
+ KNOWN_FACE_WIDTH = 14 # cm
18
+ REF_IMAGE_FACE_WIDTH = 120 # Reference face width in pixels at the known distance
19
+ FOCAL_LENGTH = (REF_IMAGE_FACE_WIDTH * KNOWN_DISTANCE) / KNOWN_FACE_WIDTH
20
+ SCALING_FACTOR = 2.0 # Adjust based on testing
21
+
22
+ # FastAPI initialization
23
+ app = FastAPI()
24
+
25
+ # Optimized tracking of previous detections using a deque
26
+ MAX_HISTORY = 10
27
+ detected_people_history = deque(maxlen=MAX_HISTORY)
28
+
29
+ DISTANCE_THRESHOLD = 30 # cm
30
+
31
+ @app.on_event("startup")
32
+ async def startup_event():
33
+ print("\n🚀 WebSocket API is running on ws://0.0.0.0:7860/ws\n")
34
+
35
+ @app.websocket("/ws")
36
+ async def websocket_endpoint(websocket: WebSocket):
37
+ """WebSocket for real-time face detection"""
38
+ await websocket.accept()
39
+ print("✅ Client connected")
40
+
41
+ try:
42
+ while True:
43
+ frame_data = await websocket.receive_text()
44
+ frame_bytes = base64.b64decode(frame_data)
45
+ image_np = np.frombuffer(frame_bytes, np.uint8)
46
+ frame = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
47
+
48
+ # Resize frame for faster inference
49
+ h, w, _ = frame.shape
50
+ resized_frame = cv2.resize(frame, (w // 2, h // 2))
51
+
52
+ # Run YOLO model
53
+ results = model(resized_frame, imgsz=320, half=True, verbose=False)
54
+
55
+ new_people_data = {}
56
+ change_detected = False
57
+ person_id = 1
58
+ frame_width = resized_frame.shape[1]
59
+
60
+ for result in results:
61
+ for box in result.boxes.data.tolist():
62
+ x1, y1, x2, y2, conf, _ = box[:6]
63
+ x1, y1, x2, y2 = map(int, [x1 * 2, y1 * 2, x2 * 2, y2 * 2])
64
+
65
+ if conf > 0.5:
66
+ center_x = (x1 + x2) // 2
67
+ face_width_pixels = x2 - x1
68
+
69
+ if center_x < frame_width // 3:
70
+ position = "Left"
71
+ elif center_x > 2 * frame_width // 3:
72
+ position = "Right"
73
+ else:
74
+ position = "Center"
75
+
76
+ estimated_distance = (
77
+ (FOCAL_LENGTH * KNOWN_FACE_WIDTH) / face_width_pixels
78
+ ) * SCALING_FACTOR if face_width_pixels > 0 else -1
79
+
80
+ new_people_data[f"person{person_id}"] = {
81
+ "distance_cm": round(estimated_distance, 2),
82
+ "position": position,
83
+ }
84
+
85
+ if detected_people_history:
86
+ prev_data = detected_people_history[-1].get(f"person{person_id}")
87
+ if (
88
+ not prev_data
89
+ or prev_data["position"] != position
90
+ or abs(prev_data["distance_cm"] - estimated_distance) > DISTANCE_THRESHOLD
91
+ ):
92
+ change_detected = True
93
+
94
+ person_id += 1
95
+
96
+ if not detected_people_history or len(new_people_data) != len(detected_people_history[-1]):
97
+ change_detected = True
98
+
99
+ if change_detected:
100
+ detected_people_history.append(new_people_data)
101
+ await websocket.send_json({"people": new_people_data})
102
+ else:
103
+ await websocket.send_json({"people": []})
104
+
105
+ await asyncio.sleep(0.05)
106
+
107
+ except WebSocketDisconnect:
108
+ print("❌ Client disconnected")
109
+ except Exception as e:
110
+ print(f"⚠️ Error: {e}")
111
+
112
+ if __name__ == "__main__":
113
+ print("\n🔥 Starting WebSocket server...")
114
+ uvicorn.run(app, host="0.0.0.0", port=7860)