Compare commits
No commits in common. "feat/tracker" and "dev" have entirely different histories.
feat/track
...
dev
3 changed files with 4 additions and 94 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -17,10 +17,3 @@ feeder/
|
||||||
dist/
|
dist/
|
||||||
websocket_comm.log
|
websocket_comm.log
|
||||||
temp_debug/
|
temp_debug/
|
||||||
.claude
|
|
||||||
|
|
||||||
# Video Test
|
|
||||||
video_rtsp/
|
|
||||||
multi_stream_viewer.py
|
|
||||||
multi_camera_simulator.py
|
|
||||||
start_4_cameras.bat
|
|
30
app.py
30
app.py
|
@ -1049,34 +1049,10 @@ async def detect(websocket: WebSocket):
|
||||||
from siwatsystem.pympta import run_lightweight_detection
|
from siwatsystem.pympta import run_lightweight_detection
|
||||||
basic_detection = run_lightweight_detection(cropped_frame, model_tree)
|
basic_detection = run_lightweight_detection(cropped_frame, model_tree)
|
||||||
|
|
||||||
# Enhanced car detection: requires both confidence pass AND bbox >= 50% of frame
|
any_car_detected = basic_detection and basic_detection.get("car_detected", False)
|
||||||
car_detected_confidence = basic_detection and basic_detection.get("car_detected", False)
|
logger.debug(f"🔍 Camera {camera_id}: LIGHTWEIGHT - simple car presence check: {any_car_detected}")
|
||||||
car_detected_with_bbox_validation = False
|
|
||||||
|
|
||||||
if car_detected_confidence:
|
if any_car_detected:
|
||||||
# Car passed confidence - now check bbox area
|
|
||||||
best_detection = basic_detection.get("best_detection")
|
|
||||||
if best_detection and best_detection.get("bbox"):
|
|
||||||
bbox = best_detection["bbox"]
|
|
||||||
x1, y1, x2, y2 = bbox
|
|
||||||
bbox_area = (x2 - x1) * (y2 - y1)
|
|
||||||
frame_height, frame_width = cropped_frame.shape[:2]
|
|
||||||
frame_area = frame_height * frame_width
|
|
||||||
bbox_area_ratio = bbox_area / frame_area if frame_area > 0 else 0
|
|
||||||
|
|
||||||
min_area_ratio = 0.2 # 20% of frame
|
|
||||||
car_detected_with_bbox_validation = bbox_area_ratio >= min_area_ratio
|
|
||||||
|
|
||||||
if not car_detected_with_bbox_validation:
|
|
||||||
logger.info(f"🚫 Camera {camera_id}: LIGHTWEIGHT - car detected but bbox {bbox_area_ratio:.1%} < {min_area_ratio:.0%} (too distant) - counting as absent")
|
|
||||||
else:
|
|
||||||
logger.debug(f"✅ Camera {camera_id}: LIGHTWEIGHT - car detected with valid bbox {bbox_area_ratio:.1%} >= {min_area_ratio:.0%}")
|
|
||||||
else:
|
|
||||||
logger.debug(f"⚠️ Camera {camera_id}: LIGHTWEIGHT - car detected but no bbox info available")
|
|
||||||
|
|
||||||
logger.debug(f"🔍 Camera {camera_id}: LIGHTWEIGHT - enhanced car presence check: confidence={car_detected_confidence}, bbox_valid={car_detected_with_bbox_validation}")
|
|
||||||
|
|
||||||
if car_detected_with_bbox_validation:
|
|
||||||
# Car detected - reset absence counter, continue sending cached detection dict
|
# Car detected - reset absence counter, continue sending cached detection dict
|
||||||
pipeline_state["absence_counter"] = 0 # Reset absence since cars are present
|
pipeline_state["absence_counter"] = 0 # Reset absence since cars are present
|
||||||
|
|
||||||
|
|
|
@ -732,17 +732,12 @@ def run_detection_with_tracking(frame, node, context=None):
|
||||||
|
|
||||||
# Tracking zone validation removed - process all detections
|
# Tracking zone validation removed - process all detections
|
||||||
|
|
||||||
# Calculate bbox area
|
|
||||||
x1, y1, x2, y2 = bbox
|
|
||||||
bbox_area = (x2 - x1) * (y2 - y1)
|
|
||||||
|
|
||||||
# Create detection object
|
# Create detection object
|
||||||
detection = {
|
detection = {
|
||||||
"class": class_name,
|
"class": class_name,
|
||||||
"confidence": conf,
|
"confidence": conf,
|
||||||
"id": track_id,
|
"id": track_id,
|
||||||
"bbox": bbox,
|
"bbox": bbox,
|
||||||
"bbox_area": bbox_area,
|
|
||||||
"class_id": cls_id
|
"class_id": cls_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,31 +926,6 @@ def update_single_track_stability(node, detection, camera_id, frame_shape=None,
|
||||||
|
|
||||||
current_track_id = detection.get("id") if detection else None
|
current_track_id = detection.get("id") if detection else None
|
||||||
|
|
||||||
# ─── Bbox Area Validation for Stability ───
|
|
||||||
# Only count detections where bbox area is >=20% of frame (close cars only)
|
|
||||||
if detection and frame_shape is not None:
|
|
||||||
bbox = detection.get("bbox", [0, 0, 0, 0])
|
|
||||||
if bbox and len(bbox) >= 4:
|
|
||||||
x1, y1, x2, y2 = bbox
|
|
||||||
bbox_area = (x2 - x1) * (y2 - y1)
|
|
||||||
frame_height, frame_width = frame_shape[:2]
|
|
||||||
frame_area = frame_height * frame_width
|
|
||||||
bbox_area_ratio = bbox_area / frame_area if frame_area > 0 else 0
|
|
||||||
|
|
||||||
# Require bbox to be at least 20% of frame area
|
|
||||||
min_area_ratio = 0.2
|
|
||||||
|
|
||||||
if bbox_area_ratio < min_area_ratio:
|
|
||||||
logger.info(f"🚫 Camera {camera_id}: Track {current_track_id} REJECTED for stability - bbox area {bbox_area_ratio:.1%} < {min_area_ratio:.0%} (too small/distant)")
|
|
||||||
# Completely reset - remove track entirely (same as trackId change)
|
|
||||||
if current_track_id and current_track_id in track_counters:
|
|
||||||
old_count = track_counters.pop(current_track_id, 0) # Remove completely
|
|
||||||
stable_tracks.discard(current_track_id) # Remove from stable
|
|
||||||
logger.info(f"🔄 Camera {camera_id}: COMPLETELY RESET track {current_track_id} counter from {old_count} to 0 (reason: bbox too small)")
|
|
||||||
return {"validation_complete": False, "stable_tracks": list(stable_tracks), "current_tracks": [], "bbox_too_small": True}
|
|
||||||
else:
|
|
||||||
logger.debug(f"✅ Camera {camera_id}: Track {current_track_id} bbox area {bbox_area_ratio:.1%} >= {min_area_ratio:.0%} - acceptable for stability")
|
|
||||||
|
|
||||||
# ═══ MODE-AWARE TRACK VALIDATION ═══
|
# ═══ MODE-AWARE TRACK VALIDATION ═══
|
||||||
logger.debug(f"📋 Camera {camera_id}: === TRACK VALIDATION ANALYSIS ===")
|
logger.debug(f"📋 Camera {camera_id}: === TRACK VALIDATION ANALYSIS ===")
|
||||||
logger.debug(f"📋 Camera {camera_id}: Current mode: {current_mode} (validation_mode={is_validation_mode})")
|
logger.debug(f"📋 Camera {camera_id}: Current mode: {current_mode} (validation_mode={is_validation_mode})")
|
||||||
|
@ -1473,35 +1443,6 @@ def run_pipeline(frame, node: dict, return_bbox: bool=False, context=None, valid
|
||||||
# Normal detection stage - Using structured detection function
|
# Normal detection stage - Using structured detection function
|
||||||
all_detections, regions_dict, track_validation_result = run_detection_with_tracking(frame, node, context)
|
all_detections, regions_dict, track_validation_result = run_detection_with_tracking(frame, node, context)
|
||||||
|
|
||||||
# ─── Apply largest bbox area selection for full pipeline mode ───
|
|
||||||
# When we have stable tracks and multiple detections, select the largest bbox area one
|
|
||||||
stable_tracks = track_validation_result.get("stable_tracks", [])
|
|
||||||
if stable_tracks and len(all_detections) > 1:
|
|
||||||
logger.info(f"🔍 PIPELINE: Full pipeline mode - selecting largest bbox area from {len(all_detections)} detections")
|
|
||||||
|
|
||||||
# Select detection with largest bbox area
|
|
||||||
largest_detection = max(all_detections, key=lambda x: x.get("bbox_area", 0))
|
|
||||||
logger.info(f"🎯 PIPELINE: Selected largest bbox area detection: conf={largest_detection.get('confidence', 0):.3f}, area={largest_detection.get('bbox_area', 0):.0f}")
|
|
||||||
|
|
||||||
# Update all_detections to only contain the largest bbox area detection
|
|
||||||
all_detections = [largest_detection]
|
|
||||||
|
|
||||||
# Update regions_dict to reflect the selected detection
|
|
||||||
class_name = largest_detection.get("class", "car")
|
|
||||||
regions_dict = {
|
|
||||||
class_name: {
|
|
||||||
"confidence": largest_detection.get("confidence"),
|
|
||||||
"bbox": largest_detection.get("bbox", [0, 0, 0, 0]),
|
|
||||||
"detection": largest_detection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(f"🔄 PIPELINE: Updated regions_dict for largest bbox area selection: {list(regions_dict.keys())}")
|
|
||||||
elif stable_tracks:
|
|
||||||
logger.debug(f"🔄 PIPELINE: Full pipeline mode - single detection, no area selection needed")
|
|
||||||
else:
|
|
||||||
logger.debug(f"🔄 PIPELINE: No stable tracks yet, proceeding with confidence-based detection")
|
|
||||||
|
|
||||||
# Debug: Save crops for debugging (disabled for production)
|
# Debug: Save crops for debugging (disabled for production)
|
||||||
# if regions_dict:
|
# if regions_dict:
|
||||||
# try:
|
# try:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue