Clean push: Removed heavy files & added only latest snapshot

This commit is contained in:
2025-07-26 05:16:12 +05:30
commit acf84e8767
250 changed files with 58564 additions and 0 deletions

View File

@@ -0,0 +1,254 @@
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QSlider, QCheckBox, QFileDialog, QSizePolicy, QGridLayout, QFrame, QSpacerItem
from PySide6.QtCore import Signal, Qt
from PySide6.QtGui import QPixmap, QIcon, QFont
class DiagnosticOverlay(QFrame):
"""Semi-transparent overlay for diagnostics."""
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("""
background: rgba(0,0,0,0.5);
border-radius: 8px;
color: #fff;
font-family: 'Consolas', 'SF Mono', 'monospace';
font-size: 13px;
""")
# self.setFixedWidth(260) # Remove fixed width
self.setFixedHeight(90)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) # Allow horizontal stretch
self.setAttribute(Qt.WA_TransparentForMouseEvents)
layout = QVBoxLayout(self)
layout.setContentsMargins(12, 8, 12, 8)
self.model_label = QLabel("Model: -")
self.device_label = QLabel("Device: -")
self.stats_label = QLabel("Cars: 0 | Trucks: 0 | Ped: 0 | TLights: 0 | Moto: 0")
for w in [self.model_label, self.device_label, self.stats_label]:
w.setStyleSheet("color: #fff;")
layout.addWidget(w)
layout.addStretch(1)
def update_overlay(self, model, device, cars, trucks, peds, tlights, motorcycles):
self.model_label.setText(f"Model: {model}")
self.device_label.setText(f"Device: {device}")
self.stats_label.setText(f"Cars: {cars} | Trucks: {trucks} | Ped: {peds} | TLights: {tlights} | Moto: {motorcycles}")
class VideoDetectionTab(QWidget):
file_selected = Signal(str)
play_clicked = Signal()
pause_clicked = Signal()
stop_clicked = Signal()
detection_toggled = Signal(bool)
screenshot_clicked = Signal()
seek_changed = Signal(int)
auto_select_model_device = Signal() # New signal for auto model/device selection
def __init__(self):
super().__init__()
self.video_loaded = False
grid = QGridLayout(self)
grid.setContentsMargins(32, 24, 32, 24)
grid.setSpacing(0)
# File select bar (top)
file_bar = QHBoxLayout()
self.file_btn = QPushButton()
self.file_btn.setIcon(QIcon.fromTheme("folder-video"))
self.file_btn.setText("Select Video")
self.file_btn.setStyleSheet("padding: 8px 18px; border-radius: 8px; background: #232323; color: #fff;")
self.file_label = QLabel("No file selected")
self.file_label.setStyleSheet("color: #bbb; font-size: 13px;")
self.file_btn.clicked.connect(self._select_file)
file_bar.addWidget(self.file_btn)
file_bar.addWidget(self.file_label)
file_bar.addStretch(1)
# Video display area (centered, scalable)
video_frame = QFrame()
video_frame.setStyleSheet("""
background: #121212;
border: 1px solid #424242;
border-radius: 8px;
""")
video_frame.setMinimumSize(640, 360)
video_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
video_layout = QVBoxLayout(video_frame)
video_layout.setContentsMargins(0, 0, 0, 0)
video_layout.setAlignment(Qt.AlignCenter)
self.video_label = QLabel()
self.video_label.setAlignment(Qt.AlignCenter)
self.video_label.setStyleSheet("background: transparent; color: #888; font-size: 18px;")
self.video_label.setText("No video loaded. Please select a file.")
self.video_label.setMinimumSize(640, 360)
self.video_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
video_layout.addWidget(self.video_label)
# Diagnostic overlay (now below video, not over it)
self.overlay = DiagnosticOverlay()
self.overlay.setStyleSheet(self.overlay.styleSheet() + "border: 1px solid #03DAC5;")
self.overlay.setFixedHeight(90)
# FPS and Inference badges (below video)
self.fps_badge = QLabel("FPS: --")
self.fps_badge.setStyleSheet("background: #27ae60; color: #fff; border-radius: 12px; padding: 4px 24px; font-weight: bold; font-size: 15px;")
self.fps_badge.setAlignment(Qt.AlignCenter)
self.inference_badge = QLabel("Inference: -- ms")
self.inference_badge.setStyleSheet("background: #2980b9; color: #fff; border-radius: 12px; padding: 4px 24px; font-weight: bold; font-size: 15px;")
self.inference_badge.setAlignment(Qt.AlignCenter)
# Horizontal layout for overlay and badges
self.badge_bar = QHBoxLayout()
self.badge_bar.setContentsMargins(0, 8, 0, 8)
self.badge_bar.addWidget(self.fps_badge)
self.badge_bar.addSpacing(12)
self.badge_bar.addWidget(self.inference_badge)
self.badge_bar.addSpacing(18)
self.badge_bar.addWidget(self.overlay) # Overlay will stretch to fill right side
self.badge_bar.addStretch(10)
video_layout.addStretch(1) # Push badge bar to the bottom
video_layout.addLayout(self.badge_bar)
# Control bar (bottom)
control_bar = QHBoxLayout()
control_bar.setContentsMargins(0, 16, 0, 0)
# Playback controls
self.play_btn = QPushButton()
self.play_btn.setIcon(QIcon.fromTheme("media-playback-start"))
self.play_btn.setToolTip("Play")
self.play_btn.setFixedSize(48, 48)
self.play_btn.setEnabled(False)
self.play_btn.setStyleSheet(self._button_style())
self.pause_btn = QPushButton()
self.pause_btn.setIcon(QIcon.fromTheme("media-playback-pause"))
self.pause_btn.setToolTip("Pause")
self.pause_btn.setFixedSize(48, 48)
self.pause_btn.setEnabled(False)
self.pause_btn.setStyleSheet(self._button_style())
self.stop_btn = QPushButton()
self.stop_btn.setIcon(QIcon.fromTheme("media-playback-stop"))
self.stop_btn.setToolTip("Stop")
self.stop_btn.setFixedSize(48, 48)
self.stop_btn.setEnabled(False)
self.stop_btn.setStyleSheet(self._button_style())
for btn, sig in zip([self.play_btn, self.pause_btn, self.stop_btn], [self.play_clicked.emit, self.pause_clicked.emit, self.stop_clicked.emit]):
btn.clicked.connect(sig)
control_bar.addWidget(self.play_btn)
control_bar.addWidget(self.pause_btn)
control_bar.addWidget(self.stop_btn)
control_bar.addSpacing(16)
# Progress bar
self.progress = QSlider(Qt.Horizontal)
self.progress.setStyleSheet("QSlider::groove:horizontal { height: 6px; background: #232323; border-radius: 3px; } QSlider::handle:horizontal { background: #03DAC5; border-radius: 8px; width: 18px; }")
self.progress.setMinimumWidth(240)
self.progress.setEnabled(False)
self.progress.valueChanged.connect(self.seek_changed.emit)
control_bar.addWidget(self.progress, 2)
self.timestamp = QLabel("00:00 / 00:00")
self.timestamp.setStyleSheet("color: #bbb; font-size: 13px;")
control_bar.addWidget(self.timestamp)
control_bar.addSpacing(16)
# Detection toggle & screenshot
self.detection_toggle = QCheckBox("Enable Detection")
self.detection_toggle.setChecked(True)
self.detection_toggle.setStyleSheet("color: #fff; font-size: 14px;")
self.detection_toggle.setEnabled(False)
self.detection_toggle.toggled.connect(self.detection_toggled.emit)
control_bar.addWidget(self.detection_toggle)
self.screenshot_btn = QPushButton()
self.screenshot_btn.setIcon(QIcon.fromTheme("camera-photo"))
self.screenshot_btn.setText("Screenshot")
self.screenshot_btn.setToolTip("Save current frame as image")
self.screenshot_btn.setEnabled(False)
self.screenshot_btn.setStyleSheet(self._button_style())
self.screenshot_btn.clicked.connect(self.screenshot_clicked.emit)
control_bar.addWidget(self.screenshot_btn)
control_bar.addStretch(1)
# Layout grid
grid.addLayout(file_bar, 0, 0, 1, 1)
grid.addWidget(video_frame, 1, 0, 1, 1)
grid.addLayout(self.badge_bar, 2, 0, 1, 1)
grid.addLayout(control_bar, 3, 0, 1, 1)
grid.setRowStretch(1, 1)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
def _button_style(self):
return """
QPushButton {
background: #232323;
border-radius: 24px;
color: #fff;
font-size: 15px;
border: none;
}
QPushButton:hover {
background: #03DAC5;
color: #222;
}
QPushButton:pressed {
background: #018786;
}
"""
def _select_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "Select Video File", "", "Video Files (*.mp4 *.avi *.mov *.mkv *.webm);;All Files (*)")
if file_path:
self.file_label.setText(file_path)
self.file_selected.emit(file_path)
self.video_loaded = True
self._enable_controls(True)
self.video_label.setText("")
self.auto_select_model_device.emit() # Request auto model/device selection
def _enable_controls(self, enabled):
self.play_btn.setEnabled(enabled)
self.pause_btn.setEnabled(enabled)
self.stop_btn.setEnabled(enabled)
self.progress.setEnabled(enabled)
self.detection_toggle.setEnabled(enabled)
self.screenshot_btn.setEnabled(enabled)
if enabled:
self.auto_select_model_device.emit() # Also trigger auto-select when controls are enabled
def update_display(self, pixmap):
# Maintain aspect ratio
if pixmap:
scaled = pixmap.scaled(self.video_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.video_label.setPixmap(scaled)
self._set_controls_enabled(True)
self.video_label.setStyleSheet("background: transparent; color: #888; font-size: 18px;")
else:
self.video_label.clear()
self.video_label.setText("No video loaded. Please select a video file.")
self._set_controls_enabled(False)
self.video_label.setStyleSheet("background: transparent; color: #F44336; font-size: 18px;")
def _set_controls_enabled(self, enabled):
for btn in [self.play_btn, self.pause_btn, self.stop_btn, self.progress, self.detection_toggle, self.screenshot_btn]:
btn.setEnabled(enabled)
def update_stats(self, stats):
# Accepts a stats dict for extensibility
cars = stats.get('cars', 0)
trucks = stats.get('trucks', 0)
peds = stats.get('peds', 0)
tlights = stats.get('tlights', 0)
motorcycles = stats.get('motorcycles', 0)
fps = stats.get('fps', None)
# Try all possible keys for inference time
inference = stats.get('inference', stats.get('detection_time', stats.get('detection_time_ms', None)))
model = stats.get('model', stats.get('model_name', '-'))
device = stats.get('device', stats.get('device_name', '-'))
# Update overlay
self.overlay.update_overlay(model, device, cars, trucks, peds, tlights, motorcycles)
# Update FPS and Inference badges
if fps is not None:
self.fps_badge.setText(f"FPS: {fps:.2f}")
else:
self.fps_badge.setText("FPS: --")
if inference is not None:
self.inference_badge.setText(f"Inference: {inference:.1f} ms")
else:
self.inference_badge.setText("Inference: -- ms")
def update_progress(self, value, max_value, timestamp):
self.progress.setMaximum(max_value)
self.progress.setValue(value)
# Format timestamp as string (e.g., "00:00 / 00:00" or just str)
if isinstance(timestamp, float) or isinstance(timestamp, int):
timestamp_str = f"{timestamp:.2f}"
else:
timestamp_str = str(timestamp)
self.timestamp.setText(timestamp_str)