cleanup and files added

This commit is contained in:
2025-08-26 13:24:53 -07:00
parent a379d7a063
commit 51a14cd61c
8968 changed files with 1292619 additions and 0 deletions

View File

@@ -0,0 +1,437 @@
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QTableWidget, QTableWidgetItem,
QTabWidget, QScrollArea, QFrame, QHeaderView, QPushButton
)
from PySide6.QtCore import Qt, QTimer
from PySide6.QtGui import QFont, QColor
import re
from datetime import datetime
class AnalyticsTablesWidget(QWidget):
"""Analytics widget with structured tables for debug data"""
def __init__(self):
super().__init__()
self.debug_data = {
'detections': [],
'traffic_lights': [],
'violations': [],
'performance': [],
'tracking': []
}
self.init_ui()
def init_ui(self):
"""Initialize the UI with tabbed tables"""
layout = QVBoxLayout(self)
layout.setContentsMargins(5, 5, 5, 5)
# Header
header = QLabel("📊 Analytics Tables")
header.setStyleSheet("""
QLabel {
font-size: 16px;
font-weight: bold;
color: #03DAC5;
padding: 8px;
background: #1E1E1E;
border-radius: 6px;
margin-bottom: 5px;
}
""")
layout.addWidget(header)
# Create tab widget
self.tabs = QTabWidget()
self.tabs.setStyleSheet("""
QTabWidget::pane {
border: 1px solid #333;
background: #1E1E1E;
}
QTabWidget::tab-bar {
alignment: left;
}
QTabBar::tab {
background: #2D2D2D;
color: #fff;
padding: 8px 16px;
margin-right: 2px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
QTabBar::tab:selected {
background: #03DAC5;
color: #000;
}
QTabBar::tab:hover {
background: #018786;
}
""")
# Create individual tables
self._create_detection_table()
self._create_traffic_light_table()
self._create_violation_table()
self._create_performance_table()
self._create_tracking_table()
layout.addWidget(self.tabs)
# Control buttons
controls = self._create_controls()
layout.addWidget(controls)
def _create_controls(self):
"""Create control buttons"""
frame = QFrame()
frame.setStyleSheet("""
QFrame {
background: #2D2D2D;
border-radius: 6px;
padding: 5px;
}
""")
layout = QHBoxLayout(frame)
clear_btn = QPushButton("🗑️ Clear All")
clear_btn.setStyleSheet(self._button_style())
clear_btn.clicked.connect(self.clear_all_tables)
export_btn = QPushButton("📤 Export CSV")
export_btn.setStyleSheet(self._button_style())
export_btn.clicked.connect(self.export_to_csv)
layout.addWidget(clear_btn)
layout.addWidget(export_btn)
layout.addStretch()
return frame
def _button_style(self):
return """
QPushButton {
background: #333;
color: #fff;
border: none;
padding: 6px 12px;
border-radius: 4px;
font-size: 12px;
}
QPushButton:hover {
background: #03DAC5;
color: #000;
}
"""
def _create_detection_table(self):
"""Create detection matching table"""
table = QTableWidget()
table.setColumnCount(5)
table.setHorizontalHeaderLabels([
"Detection (x,y)", "Track ID", "IoU", "Distance", "Match Status"
])
# Style the table
self._style_table(table)
# Add to tabs
scroll = QScrollArea()
scroll.setWidget(table)
scroll.setWidgetResizable(True)
self.tabs.addTab(scroll, "🎯 Detection Matching")
# Store reference
self.detection_table = table
def _create_traffic_light_table(self):
"""Create traffic light status table"""
table = QTableWidget()
table.setColumnCount(5)
table.setHorizontalHeaderLabels([
"Detection", "Red Ratio", "Yellow Ratio", "Green Ratio", "Status"
])
self._style_table(table)
scroll = QScrollArea()
scroll.setWidget(table)
scroll.setWidgetResizable(True)
self.tabs.addTab(scroll, "🚦 Traffic Lights")
self.traffic_light_table = table
def _create_violation_table(self):
"""Create violation summary table"""
table = QTableWidget()
table.setColumnCount(4)
table.setHorizontalHeaderLabels([
"Track ID", "Violation Type", "Timestamp", "Details"
])
self._style_table(table)
scroll = QScrollArea()
scroll.setWidget(table)
scroll.setWidgetResizable(True)
self.tabs.addTab(scroll, "🚨 Violations")
self.violation_table = table
def _create_performance_table(self):
"""Create performance metrics table"""
table = QTableWidget()
table.setColumnCount(6)
table.setHorizontalHeaderLabels([
"Frame", "FPS", "Inference (ms)", "Device", "Objects", "Timestamp"
])
self._style_table(table)
scroll = QScrollArea()
scroll.setWidget(table)
scroll.setWidgetResizable(True)
self.tabs.addTab(scroll, "⚡ Performance")
self.performance_table = table
def _create_tracking_table(self):
"""Create vehicle tracking table"""
table = QTableWidget()
table.setColumnCount(6)
table.setHorizontalHeaderLabels([
"Track ID", "Position (x,y)", "Moving", "Violating", "Confidence", "Status"
])
self._style_table(table)
scroll = QScrollArea()
scroll.setWidget(table)
scroll.setWidgetResizable(True)
self.tabs.addTab(scroll, "🚗 Vehicle Tracking")
self.tracking_table = table
def _style_table(self, table):
"""Apply consistent styling to tables"""
table.setStyleSheet("""
QTableWidget {
background-color: #1E1E1E;
color: #fff;
gridline-color: #333;
selection-background-color: #03DAC5;
selection-color: #000;
border: none;
font-size: 12px;
}
QTableWidget::item {
padding: 8px;
border-bottom: 1px solid #333;
}
QHeaderView::section {
background-color: #2D2D2D;
color: #03DAC5;
padding: 8px;
border: none;
font-weight: bold;
font-size: 13px;
}
""")
# Set header resize mode
header = table.horizontalHeader()
header.setStretchLastSection(True)
header.setSectionResizeMode(QHeaderView.Interactive)
# Enable sorting
table.setSortingEnabled(True)
def process_debug_logs(self, debug_text):
"""Process debug logs and update tables"""
if not debug_text:
return
# Parse different types of debug data
self._parse_detection_matches(debug_text)
self._parse_traffic_lights(debug_text)
self._parse_violations(debug_text)
self._parse_performance(debug_text)
self._parse_tracking(debug_text)
def _parse_detection_matches(self, text):
"""Parse detection matching logs"""
# Pattern for successful matches
success_pattern = r'\[MATCH SUCCESS\] Detection at \(([\d.]+),([\d.]+)\) matched with track ID=(\d+).*IoU=([\d.]+), distance=([\d.]+)'
# Pattern for failed matches
fail_pattern = r'\[MATCH FAILED\] No suitable match found for car detection at \(([\d.]+), ([\d.]+)\)'
# Find successful matches
for match in re.finditer(success_pattern, text):
x, y, track_id, iou, distance = match.groups()
self._add_detection_row(f"({x},{y})", track_id, iou, distance, "✅ Matched")
# Find failed matches
for match in re.finditer(fail_pattern, text):
x, y = match.groups()
self._add_detection_row(f"({x},{y})", "", "", "", "❌ Unmatched")
def _parse_traffic_lights(self, text):
"""Parse traffic light status logs"""
# Pattern for traffic light ratios
ratio_pattern = r'\[DEBUG\] ratios: red=([\d.]+), yellow=([\d.]+), green=([\d.]+)'
status_pattern = r'📝 Drawing traffic light status: (\w+) at bbox \[(\d+), (\d+), (\d+), (\d+)\]'
ratios = re.findall(ratio_pattern, text)
statuses = re.findall(status_pattern, text)
# Combine ratios with statuses
for i, ((red, yellow, green), (status, x1, y1, x2, y2)) in enumerate(zip(ratios, statuses)):
detection_id = f"Traffic Light {i+1}"
status_emoji = "🔴" if status == "red" else "🟡" if status == "yellow" else "🟢"
self._add_traffic_light_row(detection_id, red, yellow, green, f"{status_emoji} {status.title()}")
def _parse_violations(self, text):
"""Parse violation logs"""
violation_pattern = r'🚨 Emitting RED LIGHT VIOLATION: Track ID (\d+)'
improper_stop_pattern = r'\[VIOLATION\] Improper stop on crosswalk: Vehicle ID=(\d+) stopped on crosswalk during red light \(overlap=([\d.]+), speed=([\d.]+)\)'
# Red light violations
for match in re.finditer(violation_pattern, text):
track_id = match.group(1)
timestamp = datetime.now().strftime("%H:%M:%S")
self._add_violation_row(track_id, "🚨 Red Light Violation", timestamp, "Vehicle crossed during red light")
# Improper stops
for match in re.finditer(improper_stop_pattern, text):
track_id, overlap, speed = match.groups()
timestamp = datetime.now().strftime("%H:%M:%S")
details = f"Overlap: {overlap}, Speed: {speed}"
self._add_violation_row(track_id, "🚧 Improper Stop", timestamp, details)
def _parse_performance(self, text):
"""Parse performance metrics"""
perf_pattern = r'\[PERF\] Emitting performance_stats_ready: {.*\'frame_idx\': (\d+).*\'fps\': ([\d.]+).*\'inference_time\': ([\d.]+).*\'device\': \'(\w+)\'.*}'
stats_pattern = r'🟢 Stats Updated: FPS=([\d.]+), Inference=([\d.]+)ms, Traffic Light=(\w+)'
# Performance stats
for match in re.finditer(perf_pattern, text):
frame_idx, fps, inference_time, device = match.groups()
timestamp = datetime.now().strftime("%H:%M:%S")
self._add_performance_row(frame_idx, fps, inference_time, device, "", timestamp)
# Basic stats
for match in re.finditer(stats_pattern, text):
fps, inference_time, traffic_light = match.groups()
timestamp = datetime.now().strftime("%H:%M:%S")
self._add_performance_row("", fps, inference_time, "", "", timestamp)
def _parse_tracking(self, text):
"""Parse vehicle tracking data"""
track_pattern = r'Vehicle (\d+): ID=(\d+), center_y=([\d.]+), moving=(\w+), violating=(\w+)'
bbox_pattern = r'ID=(\d+) bbox=\[([\d.]+), ([\d.]+), ([\d.]+), ([\d.]+)\] center_y=([\d.]+)'
# Track vehicles
for match in re.finditer(track_pattern, text):
vehicle_num, track_id, center_y, moving, violating = match.groups()
position = f"(—, {center_y})"
status = "🟢 Active"
confidence = ""
self._add_tracking_row(track_id, position, moving, violating, confidence, status)
# Vehicle bboxes
for match in re.finditer(bbox_pattern, text):
track_id, x1, y1, x2, y2, center_y = match.groups()
center_x = (float(x1) + float(x2)) / 2
position = f"({center_x:.1f}, {center_y})"
# Update existing row or add new one
def _add_detection_row(self, detection, track_id, iou, distance, status):
"""Add row to detection table"""
table = self.detection_table
row = table.rowCount()
table.insertRow(row)
items = [detection, str(track_id), str(iou), str(distance), status]
for col, item in enumerate(items):
table_item = QTableWidgetItem(item)
if status == "✅ Matched":
table_item.setBackground(QColor(3, 218, 197, 50))
elif status == "❌ Unmatched":
table_item.setBackground(QColor(255, 87, 87, 50))
table.setItem(row, col, table_item)
def _add_traffic_light_row(self, detection, red, yellow, green, status):
"""Add row to traffic light table"""
table = self.traffic_light_table
row = table.rowCount()
table.insertRow(row)
items = [detection, red, yellow, green, status]
for col, item in enumerate(items):
table_item = QTableWidgetItem(item)
if "🔴" in status:
table_item.setBackground(QColor(255, 87, 87, 50))
elif "🟡" in status:
table_item.setBackground(QColor(255, 193, 7, 50))
elif "🟢" in status:
table_item.setBackground(QColor(76, 175, 80, 50))
table.setItem(row, col, table_item)
def _add_violation_row(self, track_id, violation_type, timestamp, details):
"""Add row to violation table"""
table = self.violation_table
row = table.rowCount()
table.insertRow(row)
items = [track_id, violation_type, timestamp, details]
for col, item in enumerate(items):
table_item = QTableWidgetItem(item)
table_item.setBackground(QColor(255, 87, 87, 30))
table.setItem(row, col, table_item)
def _add_performance_row(self, frame, fps, inference_time, device, objects, timestamp):
"""Add row to performance table"""
table = self.performance_table
row = table.rowCount()
table.insertRow(row)
items = [str(frame), str(fps), str(inference_time), str(device), str(objects), timestamp]
for col, item in enumerate(items):
table_item = QTableWidgetItem(item)
# Color code by device
if device == "GPU":
table_item.setBackground(QColor(3, 218, 197, 30))
elif device == "CPU":
table_item.setBackground(QColor(255, 193, 7, 30))
table.setItem(row, col, table_item)
def _add_tracking_row(self, track_id, position, moving, violating, confidence, status):
"""Add row to tracking table"""
table = self.tracking_table
row = table.rowCount()
table.insertRow(row)
items = [track_id, position, moving, violating, confidence, status]
for col, item in enumerate(items):
table_item = QTableWidgetItem(item)
if violating == "True":
table_item.setBackground(QColor(255, 87, 87, 50))
elif moving == "True":
table_item.setBackground(QColor(3, 218, 197, 30))
table.setItem(row, col, table_item)
def clear_all_tables(self):
"""Clear all tables"""
for table in [self.detection_table, self.traffic_light_table,
self.violation_table, self.performance_table, self.tracking_table]:
table.setRowCount(0)
def export_to_csv(self):
"""Export tables to CSV files"""
# This would implement CSV export functionality
print("CSV export functionality would be implemented here")
def update_from_debug_text(self, debug_text):
"""Main method to update tables from debug text"""
if debug_text:
self.process_debug_logs(debug_text)