Skip to content

Add Advanced Edge Detection + active-mask layer#12

Merged
jacobson30-bot merged 1 commit into
mainfrom
advanced-edge-detection-masks
Jun 5, 2026
Merged

Add Advanced Edge Detection + active-mask layer#12
jacobson30-bot merged 1 commit into
mainfrom
advanced-edge-detection-masks

Conversation

@jacobson30-bot
Copy link
Copy Markdown
Contributor

Summary

Adds Canny and Sobel/Scharr edge detection as a non-destructive tool whose outputs become reusable analysis objects, plus a formal active-mask layer (ImageMask + MaskSet) that parallels the existing ROISet.

Workflow: select method → tune → live overlay preview (never mutates the image) → emit overlay / new image / active mask / ROI(s) → mask restricts statistics, excludes regions from a plane fit, converts to ROI.

What's included

  • Edge backendprocessing/edge_detection.py (EdgeDetectionResult, canny_edges(), gradient_filter(), CANNY_PRESETS; NaN-safe, ROI-aware, provenance-recording). edge_detect extended with sobel/scharr (history-replayable). scikit-image promoted to a core dependency.
  • Active mask layercore/mask.py (ImageMask + MaskSet, packbits-compact JSON), processing/mask_ops.py (9 morphology ops), core.roi.roi_from_mask() on the existing Shapely bridge, {stem}.masks.json sidecars mirroring the ROI sidecar.
  • GUI — modeless EdgeDetectionDialog with live overlay preview + Process-tab button; canvas set_mask_overlay/clear_mask_overlay; viewer mask mixin with sidecar autosave; MaskManagerPanel + "Masks" sidebar tab (set-active, cleanup, invert, convert-to-ROI, statistics, export).
  • Downstream — active mask restricts statistics (roi_statistics(mask=…)) and excludes regions from a plane fit via the mask→ROI bridge.

Verification

  • 1961 passed, 207 skipped, ruff check clean across the package.
  • New backend tests (62 passing): edge detection, mask model/ops/sidecar/integration.
  • Offscreen-Qt dialog + manager tests written and gated; they skip where Qt has no platform plugin and run in CI.

Note: the live Qt GUI path was verified statically (imports, wiring, construction order) but not executed in the dev sandbox (no Qt platform plugin). Deferred clean seams left for Gabor/ridge detectors and edge-orientation histograms.

🤖 Generated with Claude Code

Adds Canny and Sobel/Scharr edge detection as a non-destructive tool whose
outputs become reusable analysis objects, plus a formal active-mask layer
(ImageMask + MaskSet) that parallels the existing ROISet.

Backend:
- processing/edge_detection.py: EdgeDetectionResult, canny_edges(),
  gradient_filter(), CANNY_PRESETS (NaN-safe, ROI-aware, provenance-recording)
- extend filters.edge_detect with sobel/scharr (history-replayable)
- scikit-image promoted to a core dependency

Mask layer:
- core/mask.py: ImageMask + MaskSet (packbits-compact JSON, active mask)
- processing/mask_ops.py: invert/dilate/erode/open/close/fill-holes/
  remove-small/skeletonize/remove-border
- core/roi.roi_from_mask() riding the existing Shapely bridge
- {stem}.masks.json sidecars (io + gui wrappers) mirroring the ROI sidecar

GUI:
- gui/dialogs/edge_detection.py: modeless dialog, live overlay preview,
  outputs (overlay / new image / active mask / ROIs); Process-tab button
- image_canvas set_mask_overlay/clear_mask_overlay (bad-segment precedent)
- image_viewer_mask_mixin: per-image MaskSet, sidecar autosave, output wiring
- gui/mask_manager.py + "Masks" sidebar tab: set-active, cleanup, invert,
  convert-to-ROI, statistics, export

Downstream:
- active mask restricts statistics (roi_statistics mask=) and excludes
  regions from a plane fit via the mask->ROI bridge

Tests: edge backend, mask model/ops/sidecar/integration (62 passing) plus
gated offscreen-Qt dialog and manager tests. Full suite green, ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant