arnavam commited on
Commit
1c44b5a
·
1 Parent(s): 6ae3d39

fixig some things

Browse files
Files changed (1) hide show
  1. server.py +65 -2
server.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException, status, Depends, UploadFile, File, Form
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import StreamingResponse
4
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
@@ -14,6 +14,7 @@ import threading
14
  import os
15
  import base64
16
  import hashlib
 
17
  from pydantic import BaseModel, Field
18
  from pymongo import AsyncMongoClient
19
  from passlib.context import CryptContext
@@ -51,6 +52,10 @@ current_cx = 0.5
51
  current_cy = 0.5
52
  current_scale = 1.0
53
 
 
 
 
 
54
  # Configurable parameters for smooth panning
55
  SMOOTHING_FACTOR = 0.1 # Lower is smoother but slower (similar to Dart's TweenAnimation)
56
  TARGET_ASPECT_RATIO = 16.0 / 9.0 # Assuming output is meant to be 16:9
@@ -204,7 +209,7 @@ def apply_center_stage_crop(frame, tracking_data):
204
  the frame based on the tracking target bounding box.
205
  Returns the cropped frame.
206
  """
207
- global current_cx, current_cy, current_scale
208
 
209
  h, w = frame.shape[:2]
210
 
@@ -213,6 +218,8 @@ def apply_center_stage_crop(frame, tracking_data):
213
  target_cy = 0.5
214
  target_scale = 1.0
215
 
 
 
216
  # Calculate target state based on tracking data
217
  boxes = tracking_data.get("boxes", [])
218
  if tracking_data.get("mode") == "multi":
@@ -225,6 +232,7 @@ def apply_center_stage_crop(frame, tracking_data):
225
 
226
  target_cx = box_cx / w
227
  target_cy = box_cy / h
 
228
 
229
  # Target scale logic (from Dart): max dimension proportion * 1.5 margin
230
  max_dim = max(box_w / w, box_h / h)
@@ -246,11 +254,27 @@ def apply_center_stage_crop(frame, tracking_data):
246
 
247
  target_cx = box_cx / w
248
  target_cy = box_cy / h
 
249
 
250
  max_dim = max(box_w / w, box_h / h)
251
  target_scale = 1.0 / (max_dim * 2.0) # slightly tighter for single person
252
  target_scale = max(1.0, min(target_scale, 3.0))
253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  # Apply EMA smoothing
255
  current_cx += (target_cx - current_cx) * SMOOTHING_FACTOR
256
  current_cy += (target_cy - current_cy) * SMOOTHING_FACTOR
@@ -897,6 +921,45 @@ async def set_desired_angle(
897
  logger.error(f"Error setting angle in DB: {e}")
898
  raise HTTPException(status_code=500, detail=str(e))
899
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  @app.get("/api/audio/settings")
901
  async def get_audio_settings():
902
  """Retrieve all audio settings from MongoDB."""
 
1
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException, status, Depends, UploadFile, File, Form, Body
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import StreamingResponse
4
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
 
14
  import os
15
  import base64
16
  import hashlib
17
+ import math
18
  from pydantic import BaseModel, Field
19
  from pymongo import AsyncMongoClient
20
  from passlib.context import CryptContext
 
52
  current_cy = 0.5
53
  current_scale = 1.0
54
 
55
+ # --- Real-time Target Tracking State ---
56
+ current_target_angle = None
57
+ current_target_distance = None
58
+
59
  # Configurable parameters for smooth panning
60
  SMOOTHING_FACTOR = 0.1 # Lower is smoother but slower (similar to Dart's TweenAnimation)
61
  TARGET_ASPECT_RATIO = 16.0 / 9.0 # Assuming output is meant to be 16:9
 
209
  the frame based on the tracking target bounding box.
210
  Returns the cropped frame.
211
  """
212
+ global current_cx, current_cy, current_scale, current_target_angle, current_target_distance
213
 
214
  h, w = frame.shape[:2]
215
 
 
218
  target_cy = 0.5
219
  target_scale = 1.0
220
 
221
+ target_found = False
222
+
223
  # Calculate target state based on tracking data
224
  boxes = tracking_data.get("boxes", [])
225
  if tracking_data.get("mode") == "multi":
 
232
 
233
  target_cx = box_cx / w
234
  target_cy = box_cy / h
235
+ target_found = True
236
 
237
  # Target scale logic (from Dart): max dimension proportion * 1.5 margin
238
  max_dim = max(box_w / w, box_h / h)
 
254
 
255
  target_cx = box_cx / w
256
  target_cy = box_cy / h
257
+ target_found = True
258
 
259
  max_dim = max(box_w / w, box_h / h)
260
  target_scale = 1.0 / (max_dim * 2.0) # slightly tighter for single person
261
  target_scale = max(1.0, min(target_scale, 3.0))
262
 
263
+ if target_found:
264
+ # Calculate distance and angle from the frame center (w/2, h/2) to the target bounding box center (box_cx, box_cy)
265
+ center_x, center_y = w / 2.0, h / 2.0
266
+
267
+ dx = box_cx - center_x
268
+ dy = box_cy - center_y
269
+
270
+ current_target_distance = math.hypot(dx, dy)
271
+ # Convert atan2 result to 0-360 degrees
272
+ angle = math.degrees(math.atan2(dy, dx))
273
+ current_target_angle = angle % 360.0
274
+ else:
275
+ current_target_angle = None
276
+ current_target_distance = None
277
+
278
  # Apply EMA smoothing
279
  current_cx += (target_cx - current_cx) * SMOOTHING_FACTOR
280
  current_cy += (target_cy - current_cy) * SMOOTHING_FACTOR
 
921
  logger.error(f"Error setting angle in DB: {e}")
922
  raise HTTPException(status_code=500, detail=str(e))
923
 
924
+ @app.get("/api/audio/get-angle")
925
+ async def get_current_angle():
926
+ """
927
+ Get the currently tracked angle of the target person.
928
+ If no person is tracked, fallback to the angle previously set via set-angle.
929
+ """
930
+ try:
931
+ global current_target_angle, current_target_distance
932
+
933
+ # If a person is actively being tracked, return their real-time angle
934
+ if current_target_angle is not None:
935
+ return {
936
+ "ok": True,
937
+ "source": "tracking",
938
+ "angle": round(current_target_angle, 2),
939
+ "distance": round(current_target_distance, 2)
940
+ }
941
+
942
+ # Fallback to the saved angle if no target is actively tracked
943
+ if audio_angles_collection is not None:
944
+ saved_angle_doc = await audio_angles_collection.find_one({"key": "latest_angle"})
945
+ if saved_angle_doc and "value" in saved_angle_doc:
946
+ return {
947
+ "ok": True,
948
+ "source": "database",
949
+ "angle": float(saved_angle_doc["value"]),
950
+ "distance": None
951
+ }
952
+
953
+ return {
954
+ "ok": False,
955
+ "message": "No active tracking and no saved angle found",
956
+ "angle": None,
957
+ "distance": None
958
+ }
959
+ except Exception as e:
960
+ logger.error(f"Error retrieving angle: {e}")
961
+ raise HTTPException(status_code=500, detail=str(e))
962
+
963
  @app.get("/api/audio/settings")
964
  async def get_audio_settings():
965
  """Retrieve all audio settings from MongoDB."""