Spaces:
Sleeping
Sleeping
eeeeelin commited on
Commit ·
021dff5
1
Parent(s): e613b10
create utility file to store reused math logic, add modal path to config file
Browse files- app/__pycache__/config.cpython-311.pyc +0 -0
- app/config.py +1 -0
- app/services/__pycache__/processing_service.cpython-311.pyc +0 -0
- app/services/__pycache__/video_processor.cpython-311.pyc +0 -0
- app/services/processing_service.py +4 -30
- app/services/video_processor.py +2 -26
- app/utils/__init__.py +0 -0
- app/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- app/utils/__pycache__/math_utils.cpython-311.pyc +0 -0
- app/utils/math_utils.py +29 -0
app/__pycache__/config.cpython-311.pyc
CHANGED
|
Binary files a/app/__pycache__/config.cpython-311.pyc and b/app/__pycache__/config.cpython-311.pyc differ
|
|
|
app/config.py
CHANGED
|
@@ -14,6 +14,7 @@ class Config:
|
|
| 14 |
FIREBASE_DATABASE_URL = os.environ.get('FIREBASE_DATABASE_URL')
|
| 15 |
|
| 16 |
# Model
|
|
|
|
| 17 |
CONFIDENCE_THRESHOLD = 0.5
|
| 18 |
FRAME_WIDTH = 672
|
| 19 |
FRAME_HEIGHT = 448
|
|
|
|
| 14 |
FIREBASE_DATABASE_URL = os.environ.get('FIREBASE_DATABASE_URL')
|
| 15 |
|
| 16 |
# Model
|
| 17 |
+
MODEL_PATH = os.environ.get('MODEL_PATH', 'model_data/checkpoint_best_total.pth')
|
| 18 |
CONFIDENCE_THRESHOLD = 0.5
|
| 19 |
FRAME_WIDTH = 672
|
| 20 |
FRAME_HEIGHT = 448
|
app/services/__pycache__/processing_service.cpython-311.pyc
CHANGED
|
Binary files a/app/services/__pycache__/processing_service.cpython-311.pyc and b/app/services/__pycache__/processing_service.cpython-311.pyc differ
|
|
|
app/services/__pycache__/video_processor.cpython-311.pyc
CHANGED
|
Binary files a/app/services/__pycache__/video_processor.cpython-311.pyc and b/app/services/__pycache__/video_processor.cpython-311.pyc differ
|
|
|
app/services/processing_service.py
CHANGED
|
@@ -8,6 +8,8 @@ from app import socketio
|
|
| 8 |
from app.services.video_processor import VideoProcessor
|
| 9 |
from app.services.firebase_service import FirebaseService
|
| 10 |
from app.models import SessionData
|
|
|
|
|
|
|
| 11 |
|
| 12 |
# Global state to track processing jobs
|
| 13 |
processing_jobs = {}
|
|
@@ -76,7 +78,7 @@ def _process_video_background(job: ProcessingJob):
|
|
| 76 |
|
| 77 |
try:
|
| 78 |
# Initialize services
|
| 79 |
-
video_processor = VideoProcessor(model_path=
|
| 80 |
firebase_service = FirebaseService()
|
| 81 |
|
| 82 |
# Create session data
|
|
@@ -270,7 +272,7 @@ def _process_frame_detections(detections, line_points, track_class, track_last_d
|
|
| 270 |
lp1 = (int(line_points[0][0]), int(line_points[0][1]))
|
| 271 |
lp2 = (int(line_points[1][0]), int(line_points[1][1]))
|
| 272 |
|
| 273 |
-
dist, is_within =
|
| 274 |
|
| 275 |
prev_data = track_last_dist.get(tracker_id)
|
| 276 |
track_class[tracker_id] = int(class_id)
|
|
@@ -309,34 +311,6 @@ def _process_frame_detections(detections, line_points, track_class, track_last_d
|
|
| 309 |
|
| 310 |
track_last_dist[tracker_id] = (dist, is_within)
|
| 311 |
|
| 312 |
-
|
| 313 |
-
def _line_signed_distance(p1, p2, centroid):
|
| 314 |
-
"""Calculate signed distance from point to line"""
|
| 315 |
-
import math
|
| 316 |
-
x1, y1 = p1
|
| 317 |
-
x2, y2 = p2
|
| 318 |
-
cx, cy = centroid
|
| 319 |
-
|
| 320 |
-
dx = x2 - x1
|
| 321 |
-
dy = y2 - y1
|
| 322 |
-
line_len_sq = dx * dx + dy * dy
|
| 323 |
-
|
| 324 |
-
if line_len_sq == 0:
|
| 325 |
-
return 0.0, False
|
| 326 |
-
|
| 327 |
-
t = ((cx - x1) * dx + (cy - y1) * dy) / line_len_sq
|
| 328 |
-
margin = 0.1
|
| 329 |
-
is_within_segment = -margin <= t <= 1.0 + margin
|
| 330 |
-
|
| 331 |
-
a = y2 - y1
|
| 332 |
-
b = x1 - x2
|
| 333 |
-
c = x2 * y1 - x1 * y2
|
| 334 |
-
denom = math.hypot(a, b)
|
| 335 |
-
signed_dist = (a * cx + b * cy + c) / denom if denom != 0 else 0.0
|
| 336 |
-
|
| 337 |
-
return signed_dist, is_within_segment
|
| 338 |
-
|
| 339 |
-
|
| 340 |
# SocketIO event emitters
|
| 341 |
def _emit_status_update(job: ProcessingJob):
|
| 342 |
"""Emit job status update"""
|
|
|
|
| 8 |
from app.services.video_processor import VideoProcessor
|
| 9 |
from app.services.firebase_service import FirebaseService
|
| 10 |
from app.models import SessionData
|
| 11 |
+
from app.config import Config
|
| 12 |
+
from app.utils.math_utils import calculate_line_signed_distance
|
| 13 |
|
| 14 |
# Global state to track processing jobs
|
| 15 |
processing_jobs = {}
|
|
|
|
| 78 |
|
| 79 |
try:
|
| 80 |
# Initialize services
|
| 81 |
+
video_processor = VideoProcessor(model_path=Config.MODEL_PATH)
|
| 82 |
firebase_service = FirebaseService()
|
| 83 |
|
| 84 |
# Create session data
|
|
|
|
| 272 |
lp1 = (int(line_points[0][0]), int(line_points[0][1]))
|
| 273 |
lp2 = (int(line_points[1][0]), int(line_points[1][1]))
|
| 274 |
|
| 275 |
+
dist, is_within = calculate_line_signed_distance(lp1, lp2, (cx, cy))
|
| 276 |
|
| 277 |
prev_data = track_last_dist.get(tracker_id)
|
| 278 |
track_class[tracker_id] = int(class_id)
|
|
|
|
| 311 |
|
| 312 |
track_last_dist[tracker_id] = (dist, is_within)
|
| 313 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
# SocketIO event emitters
|
| 315 |
def _emit_status_update(job: ProcessingJob):
|
| 316 |
"""Emit job status update"""
|
app/services/video_processor.py
CHANGED
|
@@ -9,6 +9,7 @@ from rfdetr import RFDETRBase
|
|
| 9 |
from datetime import datetime
|
| 10 |
from app.models import VehicleEvent, SessionData
|
| 11 |
from app.config import Config
|
|
|
|
| 12 |
|
| 13 |
class VideoProcessor:
|
| 14 |
def __init__(self, model_path: str):
|
|
@@ -148,7 +149,7 @@ class VideoProcessor:
|
|
| 148 |
# Convert line points to integers
|
| 149 |
lp1 = (int(line_points[0][0]), int(line_points[0][1]))
|
| 150 |
lp2 = (int(line_points[1][0]), int(line_points[1][1]))
|
| 151 |
-
dist, is_within =
|
| 152 |
|
| 153 |
prev_data = track_last_dist.get(tracker_id)
|
| 154 |
track_class[tracker_id] = int(class_id)
|
|
@@ -179,31 +180,6 @@ class VideoProcessor:
|
|
| 179 |
|
| 180 |
track_last_dist[tracker_id] = (dist, is_within)
|
| 181 |
|
| 182 |
-
def _line_signed_distance(self, p1, p2, centroid):
|
| 183 |
-
"""Calculate signed distance from point to line"""
|
| 184 |
-
x1, y1 = p1
|
| 185 |
-
x2, y2 = p2
|
| 186 |
-
cx, cy = centroid
|
| 187 |
-
|
| 188 |
-
dx = x2 - x1
|
| 189 |
-
dy = y2 - y1
|
| 190 |
-
line_len_sq = dx * dx + dy * dy
|
| 191 |
-
|
| 192 |
-
if line_len_sq == 0:
|
| 193 |
-
return 0.0, False
|
| 194 |
-
|
| 195 |
-
t = ((cx - x1) * dx + (cy - y1) * dy) / line_len_sq
|
| 196 |
-
margin = 0.1
|
| 197 |
-
is_within_segment = -margin <= t <= 1.0 + margin
|
| 198 |
-
|
| 199 |
-
a = y2 - y1
|
| 200 |
-
b = x1 - x2
|
| 201 |
-
c = x2 * y1 - x1 * y2
|
| 202 |
-
denom = math.hypot(a, b)
|
| 203 |
-
signed_dist = (a * cx + b * cy + c) / denom if denom != 0 else 0.0
|
| 204 |
-
|
| 205 |
-
return signed_dist, is_within_segment
|
| 206 |
-
|
| 207 |
def _draw_counts(self, frame, session_data):
|
| 208 |
"""Draw vehicle counts on frame"""
|
| 209 |
stats = session_data.get_statistics()
|
|
|
|
| 9 |
from datetime import datetime
|
| 10 |
from app.models import VehicleEvent, SessionData
|
| 11 |
from app.config import Config
|
| 12 |
+
from app.utils.math_utils import calculate_line_signed_distance
|
| 13 |
|
| 14 |
class VideoProcessor:
|
| 15 |
def __init__(self, model_path: str):
|
|
|
|
| 149 |
# Convert line points to integers
|
| 150 |
lp1 = (int(line_points[0][0]), int(line_points[0][1]))
|
| 151 |
lp2 = (int(line_points[1][0]), int(line_points[1][1]))
|
| 152 |
+
dist, is_within = calculate_line_signed_distance(lp1, lp2, (cx, cy))
|
| 153 |
|
| 154 |
prev_data = track_last_dist.get(tracker_id)
|
| 155 |
track_class[tracker_id] = int(class_id)
|
|
|
|
| 180 |
|
| 181 |
track_last_dist[tracker_id] = (dist, is_within)
|
| 182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
def _draw_counts(self, frame, session_data):
|
| 184 |
"""Draw vehicle counts on frame"""
|
| 185 |
stats = session_data.get_statistics()
|
app/utils/__init__.py
ADDED
|
File without changes
|
app/utils/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (181 Bytes). View file
|
|
|
app/utils/__pycache__/math_utils.cpython-311.pyc
ADDED
|
Binary file (1.2 kB). View file
|
|
|
app/utils/math_utils.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
|
| 3 |
+
def calculate_line_signed_distance(p1, p2, centroid):
|
| 4 |
+
"""
|
| 5 |
+
Calculate signed distance from point to line.
|
| 6 |
+
Returns (signed_dist, is_within_segment)
|
| 7 |
+
"""
|
| 8 |
+
x1, y1 = p1
|
| 9 |
+
x2, y2 = p2
|
| 10 |
+
cx, cy = centroid
|
| 11 |
+
|
| 12 |
+
dx = x2 - x1
|
| 13 |
+
dy = y2 - y1
|
| 14 |
+
line_len_sq = dx * dx + dy * dy
|
| 15 |
+
|
| 16 |
+
if line_len_sq == 0:
|
| 17 |
+
return 0.0, False
|
| 18 |
+
|
| 19 |
+
t = ((cx - x1) * dx + (cy - y1) * dy) / line_len_sq
|
| 20 |
+
margin = 0.1
|
| 21 |
+
is_within_segment = -margin <= t <= 1.0 + margin
|
| 22 |
+
|
| 23 |
+
a = y2 - y1
|
| 24 |
+
b = x1 - x2
|
| 25 |
+
c = x2 * y1 - x1 * y2
|
| 26 |
+
denom = math.hypot(a, b)
|
| 27 |
+
signed_dist = (a * cx + b * cy + c) / denom if denom != 0 else 0.0
|
| 28 |
+
|
| 29 |
+
return signed_dist, is_within_segment
|