diff --git a/.gitignore b/.gitignore index 8e805c5..cf51c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,11 +16,4 @@ feeder/ .vscode/ dist/ websocket_comm.log -temp_debug/ -.claude - -# Video Test -video_rtsp/ -multi_stream_viewer.py -multi_camera_simulator.py -start_4_cameras.bat \ No newline at end of file +temp_debug/ \ No newline at end of file diff --git a/app.py b/app.py index 0ac238f..3a1c84a 100644 --- a/app.py +++ b/app.py @@ -1049,34 +1049,10 @@ async def detect(websocket: WebSocket): from siwatsystem.pympta import run_lightweight_detection basic_detection = run_lightweight_detection(cropped_frame, model_tree) - # Enhanced car detection: requires both confidence pass AND bbox >= 50% of frame - car_detected_confidence = basic_detection and basic_detection.get("car_detected", False) - car_detected_with_bbox_validation = False + any_car_detected = basic_detection and basic_detection.get("car_detected", False) + logger.debug(f"🔍 Camera {camera_id}: LIGHTWEIGHT - simple car presence check: {any_car_detected}") - if car_detected_confidence: - # 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: + if any_car_detected: # Car detected - reset absence counter, continue sending cached detection dict pipeline_state["absence_counter"] = 0 # Reset absence since cars are present diff --git a/siwatsystem/pympta.py b/siwatsystem/pympta.py index 1d81596..ac34d88 100644 --- a/siwatsystem/pympta.py +++ b/siwatsystem/pympta.py @@ -732,17 +732,12 @@ def run_detection_with_tracking(frame, node, context=None): # Tracking zone validation removed - process all detections - # Calculate bbox area - x1, y1, x2, y2 = bbox - bbox_area = (x2 - x1) * (y2 - y1) - # Create detection object detection = { "class": class_name, "confidence": conf, "id": track_id, "bbox": bbox, - "bbox_area": bbox_area, "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 - # ─── 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 ═══ logger.debug(f"📋 Camera {camera_id}: === TRACK VALIDATION ANALYSIS ===") logger.debug(f"📋 Camera {camera_id}: Current mode: {current_mode} (validation_mode={is_validation_mode})") @@ -1472,35 +1442,6 @@ def run_pipeline(frame, node: dict, return_bbox: bool=False, context=None, valid else: # Normal detection stage - Using structured detection function 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) # if regions_dict: