190 lines
No EOL
6 KiB
Python
190 lines
No EOL
6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for the refactored detection and tracking functionality.
|
|
"""
|
|
import os
|
|
import sys
|
|
import cv2
|
|
import numpy as np
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
# Add the project root to Python path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from siwatsystem.pympta import run_detection_with_tracking, load_pipeline_from_zip
|
|
|
|
# Set up logging
|
|
logging.basicConfig(
|
|
level=logging.DEBUG,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def create_test_frame():
|
|
"""Create a simple test frame for detection testing."""
|
|
frame = np.zeros((480, 640, 3), dtype=np.uint8)
|
|
# Add some simple shapes to simulate objects
|
|
cv2.rectangle(frame, (50, 50), (200, 150), (255, 0, 0), -1) # Blue rectangle
|
|
cv2.rectangle(frame, (300, 200), (450, 350), (0, 255, 0), -1) # Green rectangle
|
|
cv2.putText(frame, "Test Frame", (250, 400), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
|
|
return frame
|
|
|
|
def test_detection_function():
|
|
"""Test the structured detection function with mock data."""
|
|
logger.info("Testing run_detection_with_tracking function...")
|
|
|
|
# Create test frame
|
|
test_frame = create_test_frame()
|
|
|
|
# Mock node configuration (simulating what would come from an MPTA file)
|
|
mock_node = {
|
|
"modelId": "test_detection_v1",
|
|
"triggerClasses": ["car", "person"],
|
|
"triggerClassIndices": [0, 1],
|
|
"minConfidence": 0.5,
|
|
"multiClass": False,
|
|
"expectedClasses": [],
|
|
"tracking": {
|
|
"enabled": True,
|
|
"reidConfigPath": "botsort.yaml"
|
|
}
|
|
}
|
|
|
|
# Mock context
|
|
test_context = {
|
|
"display_id": "test-display-001",
|
|
"camera_id": "test-cam-001"
|
|
}
|
|
|
|
logger.info("Mock node configuration:")
|
|
for key, value in mock_node.items():
|
|
logger.info(f" {key}: {value}")
|
|
|
|
# Note: This test will fail without a real YOLO model, but demonstrates the structure
|
|
try:
|
|
detections, regions = run_detection_with_tracking(test_frame, mock_node, test_context)
|
|
logger.info(f"Function executed successfully!")
|
|
logger.info(f"Returned detections: {len(detections)}")
|
|
logger.info(f"Returned regions: {list(regions.keys())}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Function failed (expected without real model): {e}")
|
|
return False
|
|
|
|
def test_mpta_loading():
|
|
"""Test loading an MPTA file with tracking configuration."""
|
|
logger.info("Testing MPTA loading with tracking configuration...")
|
|
|
|
# Check if models directory exists
|
|
models_dir = Path("models")
|
|
if not models_dir.exists():
|
|
logger.warning("No models directory found - skipping MPTA test")
|
|
return False
|
|
|
|
# Look for any .mpta files
|
|
mpta_files = list(models_dir.glob("**/*.mpta"))
|
|
if not mpta_files:
|
|
logger.warning("No .mpta files found in models directory - skipping MPTA test")
|
|
return False
|
|
|
|
mpta_file = mpta_files[0]
|
|
logger.info(f"Testing with MPTA file: {mpta_file}")
|
|
|
|
try:
|
|
# Attempt to load pipeline
|
|
target_dir = f"temp_test_{os.getpid()}"
|
|
pipeline = load_pipeline_from_zip(str(mpta_file), target_dir)
|
|
|
|
if pipeline:
|
|
logger.info("MPTA loaded successfully!")
|
|
logger.info(f"Pipeline model ID: {pipeline.get('modelId')}")
|
|
logger.info(f"Tracking config: {pipeline.get('tracking')}")
|
|
|
|
# Clean up
|
|
import shutil
|
|
if os.path.exists(target_dir):
|
|
shutil.rmtree(target_dir)
|
|
|
|
return True
|
|
else:
|
|
logger.error("Failed to load MPTA pipeline")
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"MPTA loading failed: {e}")
|
|
return False
|
|
|
|
def print_usage_example():
|
|
"""Print example usage of the new structured functions."""
|
|
logger.info("\n" + "="*60)
|
|
logger.info("USAGE EXAMPLE - Structured Detection & Tracking")
|
|
logger.info("="*60)
|
|
|
|
example_config = '''
|
|
Example pipeline.json configuration:
|
|
|
|
{
|
|
"pipeline": {
|
|
"modelId": "car_frontal_detection_v1",
|
|
"modelFile": "yolo11n.pt",
|
|
"triggerClasses": ["Car", "Frontal"],
|
|
"minConfidence": 0.7,
|
|
"multiClass": true,
|
|
"expectedClasses": ["Car", "Frontal"],
|
|
"tracking": {
|
|
"enabled": true,
|
|
"reidConfigPath": "botsort_reid.yaml"
|
|
},
|
|
"actions": [...],
|
|
"branches": [...]
|
|
}
|
|
}
|
|
'''
|
|
|
|
logger.info(example_config)
|
|
|
|
code_example = '''
|
|
Usage in code:
|
|
|
|
# Load pipeline from MPTA file
|
|
pipeline = load_pipeline_from_zip("model.mpta", "temp_dir")
|
|
|
|
# Run detection with tracking
|
|
detections, regions = run_detection_with_tracking(frame, pipeline, context)
|
|
|
|
# Process results
|
|
for detection in detections:
|
|
class_name = detection["class"]
|
|
confidence = detection["confidence"]
|
|
track_id = detection["id"] # Available when tracking enabled
|
|
bbox = detection["bbox"]
|
|
print(f"Detected: {class_name} (ID: {track_id}, conf: {confidence:.2f})")
|
|
'''
|
|
|
|
logger.info(code_example)
|
|
|
|
def main():
|
|
"""Main test function."""
|
|
logger.info("Starting detection & tracking refactoring tests...")
|
|
|
|
# Test 1: Function structure
|
|
test1_passed = test_detection_function()
|
|
|
|
# Test 2: MPTA loading
|
|
test2_passed = test_mpta_loading()
|
|
|
|
# Print usage examples
|
|
print_usage_example()
|
|
|
|
# Summary
|
|
logger.info("\n" + "="*60)
|
|
logger.info("TEST SUMMARY")
|
|
logger.info("="*60)
|
|
logger.info(f"Function structure test: {'PASS' if test1_passed else 'EXPECTED FAIL (no model)'}")
|
|
logger.info(f"MPTA loading test: {'PASS' if test2_passed else 'SKIP (no files)'}")
|
|
logger.info("\nRefactoring completed successfully!")
|
|
logger.info("The detection and tracking code is now structured and easy to configure.")
|
|
|
|
if __name__ == "__main__":
|
|
main() |