Skip to content

Architecture

Blurzy is a Qt desktop application organized into five broad layers under src/app: - UI, - Application, - Domain, - Infrastructure, and - Shared.

The layers separate user interaction and workflow coordination from video/model integrations and core data types. They describe the current code organization; they are not yet enforced as strict package boundaries.

Layer relationships

Blurzy layers: UI delegates to Application; Application and Infrastructure use Domain; Infrastructure conforms to Application contracts; Shared supports every layer Blurzy layers: UI delegates to Application; Application and Infrastructure use Domain; Infrastructure conforms to Application contracts; Shared supports every layer

Principal dependency Boundary
UI → Application Delegates user actions through the UI adapter
Application → Domain Uses core types, state, and rules
Infrastructure → Application Conforms to Application-owned contracts
Infrastructure → Domain Uses core types, state, and rules

The stack shows code organization; vertical order does not imply a dependency chain. Arrows in the key point toward the types or contracts a layer depends on, not the direction of runtime data or Qt signals. Shared supports multiple layers and is not another step in the dependency chain.

Important

This is a map of the principal boundaries, not an exhaustive import graph or strict Clean Architecture. Application still imports concrete Infrastructure implementations for factories, session initialization, and persistence. src/main.py bootstraps Qt and wires Application, Window, and UIController. Domain owns core types and rules, not Qt workflows or model-specific code.

Layer responsibilities

Layer Responsibility Guide
UI Qt widgets and dialogs, user-action handlers, controller, and view state UI components
Application Workflow facade, services, session lifecycle, manager coordination, and worker interfaces Application workflows
Domain Video/session/detection/tracking/export types and rules Domain concepts
Infrastructure Video I/O, inference and tracking algorithms, background workers, persistence Infrastructure components
Shared Cross-cutting logging, exceptions, image and annotation utilities Shared utilities

The generated API reference documents individual modules and their contracts. This guide focuses on how the layers collaborate.

Important components

  • Application (src/app/application/application.py) is the facade used by the UI. It owns the session manager and constructs application services.
  • UIController (src/app/ui/uicontroller.py) owns the UI handlers and connects the Qt window to the facade.
  • SessionManager and SessionInitializer coordinate per-video runtime objects. A Session holds the video runtime references and the four annotation/tracking data layers.
  • Services such as DetectionService, TrackingService, and ProjectService coordinate use cases; managers own selected worker/session lifecycles.
  • Infrastructure contains VideoReader, detection engines and provider models, tracking strategies, background workers, SessionDataStore, and ProjectStore.
  • Application interfaces define worker/factory contracts consumed by application adapters and infrastructure implementations.

Begin with detection to follow a video from decoded frames into the detection layers, or tracking to see how detections become tracks, how tracklets are stitched, and how privacy coverage controls affect boxes. The session guide explains where runtime state, frame access, and Layers A-D meet.

Runtime workflows

Startup and opening a video

src/main.py loads runtime configuration, initializes Qt, creates the Application, Window, and UIController, then enters the Qt event loop. When a video is opened, the UI handler calls the Application facade; session management creates a session and SessionInitializer attaches the VideoReader, domain SessionState, and VideoDecodeWorker. The decode worker fills a bounded frame buffer, while playback controls request frames through the Application and render them in the preview.

Detection

Detection sequence: the UI handler requests detection, the Application starts a background worker that runs the engine per frame and signals progress, results are stored in Layer A, and the UI redraws Detection sequence: the UI handler requests detection, the Application starts a background worker that runs the engine per frame and signals progress, results are stored in Layer A, and the UI redraws

Arrows are calls or Qt signals, read top to bottom. Single-frame detection is also available. Background detection reads frames and runs inference away from the GUI event loop; Qt signals carry result batches, progress, completion, and errors back to application/UI code. Detection engine factories and provider-specific model packages keep model loading separate from UI widgets.

Tracking, editing, and export

The four data layers separate original machine output from editable results:

Layer Contents Role
A Raw detector output Preserves the original detections.
B Reviewed/editable detections User-selected input for tracking and detection export.
C Raw tracker output Stores the strategy and post-processor result before manual edits.
D Reviewed/editable tracks User-facing tracked annotations and the preferred tracking export source.

The tracking service validates the request, seeds its input from the selected detection layer (normally B), creates a background TrackingWorker, and synchronizes completed output to C and the editable track layer D. Trackers suppress nested same-class detector boxes before association and distinguish coasted estimates from detection-backed observations.

Available strategies are Hungarian IoU association, ByteTrack's high/low confidence association, DeepSORT with motion and appearance matching, and BoT-SORT with Kalman motion and optional appearance matching. Frame-aware appearance embeddings have configurable dimensions of 128, 256, or 512; the worker derives them from the source video and falls back to appearance-disabled behavior when it cannot open a local video path.

When enabled, offline post-processing matches compatible tracklets in forward and backward temporal directions, fills accepted gaps with Gaussian Smoothed Interpolation (GSI), and applies confidence-decayed coast tails. For a missing frame \(t\), GSI combines the left and right endpoint box predictions, with each weighted by its temporal distance from the corresponding observation:

\[ w_L = \exp\left(-\frac{d_L^2}{2\sigma^2}\right), \qquad w_R = \exp\left(-\frac{d_R^2}{2\sigma^2}\right) \]
\[ B_t = \frac{w_L \widehat{B}_{L,t} + w_R \widehat{B}_{R,t}}{w_L + w_R} \]

Here, \(\widehat{B}_{L,t}\) and \(\widehat{B}_{R,t}\) are endpoint box coordinates projected to frame \(t\), and \(\sigma\) is the configured smoothness length. Nearby observations therefore exert more influence on the interpolation.

Privacy Shield (Paranoid Mode) can resist sudden box shrinkage, backfill a configurable interval before the first detection, hold coverage after the last detection, and inflate boxes by a safety margin. These conservative controls operate on tracking output and do not guarantee that every subject is detected.

Preview-only box outlines, border width, mask display, and live blur are separate from Render settings, which govern blur in exported video. Annotation handlers update the selected editable layer and request the preview/table to render again.

For blurred-video export, the export service reads the selected session and uses Layer D when it contains boxes, otherwise Layer C. The export worker runs the operation off the UI thread, reports progress, and supports cancellation. The current video-rendering implementation is in the Application export service and uses OpenCV; it is not a separate infrastructure renderer. Annotation import/export services handle annotation data separately from video rendering.

Projects and persistence

The project service captures session paths, frame positions, settings, layer data, and project directories in domain project documents. The infrastructure ProjectStore serializes and validates the JSON project file. Loading reopens the referenced videos and restores session settings and annotation layers; unavailable or invalid sessions are reported as skipped.

Layer interchange is separate from project persistence: detection and tracking import/export services read or write the selected layer as JSON or CSV, while a project file records the broader session state and file references.

Data and background-work boundaries

  • Domain data includes SessionId, SessionState, ProcessingSettings, DetectionResult, bounding boxes, project documents, and video metadata.
  • Session annotation data is organized as Layer A (label/confidence-selected detections), Layer B (filtered/editable detections), Layer C (raw tracking output), and Layer D (editable tracking results).
  • Infrastructure workers do not update Qt widgets directly. They emit Qt signals; application services/adapters and UI handlers consume those signals and update data or presentation.
  • Session data store, project store, and video reader are distinct: project files persist project/session data, the session store holds live annotation layers, and the reader decodes source media.
  • Exact threading and storage responsibilities vary by workflow. Consult the component page and implementation before changing a worker lifecycle.

Finding your way around

  • Application entry point and Qt bootstrap: src/main.py
  • Workflow facade and composition: src/app/application/application.py
  • Session lifecycle: src/app/application/managers
  • User-action handlers and controller: src/app/ui/handlers, src/app/ui/uicontroller.py
  • Qt window and widgets: src/app/ui/qt
  • Core types and rules: src/app/domain
  • Video, model, tracking, persistence, and worker implementations: src/app/infrastructure
  • Shared utilities: src/app/shared
  • Tests organized by source layer: tests

Info

Blurzy is evolving. These pages describe the current implementation and provide a structure for future detail; they do not imply that every boundary is complete or every proposal is implemented.