Add Advanced Edge Detection + active-mask layer#12
Merged
Conversation
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>
This was referenced Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 existingROISet.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
processing/edge_detection.py(EdgeDetectionResult,canny_edges(),gradient_filter(),CANNY_PRESETS; NaN-safe, ROI-aware, provenance-recording).edge_detectextended withsobel/scharr(history-replayable).scikit-imagepromoted to a core dependency.core/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.jsonsidecars mirroring the ROI sidecar.EdgeDetectionDialogwith live overlay preview + Process-tab button; canvasset_mask_overlay/clear_mask_overlay; viewer mask mixin with sidecar autosave;MaskManagerPanel+ "Masks" sidebar tab (set-active, cleanup, invert, convert-to-ROI, statistics, export).roi_statistics(mask=…)) and excludes regions from a plane fit via the mask→ROI bridge.Verification
ruff checkclean across the package.🤖 Generated with Claude Code