- Remove 257 redundant per-definition comment stubs across the package - Drop dead nonlocal declarations in autoslicer_detection.py - Document the swapped flag and swap_left_right in architecture docs - Remove unsupported 'legacy override' claims from autotune/runtime docs
4.1 KiB
4.1 KiB
Architecture
Overview
ScanSlicer is a Qt desktop app split into UI mixins, controller mixins, canvas subsystems, and image-processing/autotune engines.
Top-level startup path:
scanslicer.entry:main- Backend/environment resolution and validation
scanslicer.main:run_appQtScanSlicerwindow composition
Module Map
scanslicer/entry.py- CLI parsing
- Wayland/X11 backend selection
- Qt platform environment configuration
scanslicer/main.pyQtScanSlicermain window lifecycle- Theme handling and app icon resolution
- App bootstrap (
run_app)
scanslicer/controller*.py- UI action handlers split by responsibility
scanslicer/ui_builders*.py- Widget construction for control panel, preview panel, and shared UI helpers
scanslicer/canvas*.py- Interactive image canvas for box display/editing
scanslicer/autoslicer.py- Detection/export engine wrapper
scanslicer/autoslicer_detection.py- Detection pipelines and contour-to-box extraction
scanslicer/autoslicer_feedback.py- Auto-tune profiles, candidate scoring, and feedback persistence
scanslicer/params.py- Parameter model, defaults, and user presets
scanslicer/slices.py- Box geometry model and polygon IoU helper
UI Composition
QtScanSlicer inherits:
ScanSlicerUiBuilderMixin(UI construction)ScanSlicerControllerMixin(behavior)
Controller mixin composition:
ScanSlicerStatusMixin(status/logging/busy state)ScanSlicerCanvasActionsMixin(box operations and preview toggles)ScanSlicerDetectionMixin(worker orchestration)ScanSlicerImageIOMixin(directory/image loading and save/export)ScanSlicerParamsMixin(parameter/default/preset/autotune interactions)
Detection Execution Flow
- User action triggers
update_preview(). - Detection starts in
DetectionTask(QRunnable) onQThreadPool(single worker). - Worker runs
Autoslicer.autodetect_slices(...). - On completion:
- Cache normal preview image
- Cache filter preview image
- Update canvas image
- Merge/update boxes
- Toolbar status and box state are refreshed.
Key properties:
- One detection worker at a time.
- Busy state disables controls during processing.
- Task IDs prevent stale callbacks from old tasks mutating UI.
Auto-Tune Execution Flow
- User clicks
Auto-tune. AutotuneTaskruns in the same single-thread pool.autotune_for_current_image():
- Builds candidate parameter sets
- Ranks by current-image + prior feedback similarity
- Coarse pass on downscaled image (
fast_mode=True) - Fine pass on top finalists
- Applies best candidate to parameter model
- UI controls sync from model and detection re-runs.
Canvas System
QtSlicingCanvas= interaction + rendering + state mixins- Stores:
- image and zoom/pan state
- list of
PhotoSliceobjects - active slice index
- drag modes (corner, side, rotation, box drag, panning)
- Emits
active_slice_changedsignal to keep toolbar state synchronized.
Geometry Model
PhotoSlice stores a 4-point quadrilateral and flags:
lockedside_handles_enabledswapped(persistent left/right mirror state, honored by normalization)
It supports:
- top-left normalization and winding correction
- rectangle detection (
is_perfect_rectangle) - squarize while preserving tilt
- reset to axis-aligned orientation
- explicit left/right swap (
swap_left_right)
Persistence Model
Paths are runtime-dependent (host vs container), with environment overrides:
- Defaults JSON
- Presets JSON
- Auto-tune feedback JSON
- Session status log
Persistence writes are performed through explicit actions (save defaults/preset, save slices with feedback, status updates).
Export Pipeline
For each locked box:
- Compute output width/height from opposing edge lengths.
- Build perspective transform from box quad to rectangle.
- Warp source image with
cv2.warpPerspective. - Save with format-specific encoding params.
Packaging Surfaces
- Python package/CLI (
pyproject.toml, scriptscanslicer) - Docker runtime (
Dockerfile,docker-compose.yml) - AppImage (
packaging/appimage/)