BUG: Fix uninitialized output in LabelSet erode and dilate at zero scale#6631
Conversation
|
| Filename | Overview |
|---|---|
| Modules/Filtering/LabelErodeDilate/include/itkLabelSetErodeImageFilter.hxx | Uses the last active dimension when deciding where erosion writes final output. |
| Modules/Filtering/LabelErodeDilate/include/itkLabelSetMorphBaseImageFilter.h | Adds state for the last dimension with active scale. |
| Modules/Filtering/LabelErodeDilate/include/itkLabelSetMorphBaseImageFilter.hxx | Computes active dimensions and seeds identity output for fully inactive morphology. |
| Modules/Filtering/LabelErodeDilate/itk-module.cmake | Adds the GoogleTest test dependency. |
| Modules/Filtering/LabelErodeDilate/test/CMakeLists.txt | Registers the new GoogleTest driver source. |
| Modules/Filtering/LabelErodeDilate/test/itkLabelSetMorphBaseImageFilterGTest.cxx | Adds tests for zero-radius erosion and dilation behavior. |
Reviews (2): Last reviewed commit: "BUG: Fix uninitialized output in LabelSe..." | Re-trigger Greptile
a384847 to
143c105
Compare
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
GenerateData only called AllocateOutputs, so output stayed uninitialized until a per-axis pass wrote it. Erode's write was gated on lastpass comparing to the geometrically-last dimension instead of the last axis with nonzero scale, so a zero scale on the last axis skipped the only write; a fully zero radius skipped it for both filters. Gate erode's lastpass on the last axis with nonzero scale, and seed identity only when no axis will run a pass at all. Addresses item B90 of InsightSoftwareConsortium#6575.
143c105 to
6d14b6b
Compare
|
Force-push fixes the Root cause and fix
Fixed by keying Two finder passes in review proposed re-keying on Also fixed: Local validationNew test
|
LabelSetErodeImageFilterandLabelSetDilateImageFilteronly callAllocateOutputs()and gate every write onm_Scale[d] > 0, so a zero radius on the last axis skips erosion's only output-writing pass and the filter returns uninitialized memory. Addresses B90 of #6575.Root cause and fix
Erosion commits to the output only on
lastpass, defined as the geometrically last dimension. UnderUseImageSpacing, a zero radius on that axis makes its scale zero, the axis pass never runs,lastpassis never reached, and the output is whateverAllocateOutputs()left there. With every radius zero, neither filter writes the output at all.Two changes, both in the shared base:
lastpassis now gated onm_LastActiveDimension— the highest-index axis that actually runs a pass — so the commit happens on an axis that exists; and when no axis is active at all, the output is seeded from the input, which is the correct identity result for a zero-radius morphological operation.The seed is deliberately scoped to the fully-degenerate case. An unconditional seed was measured at 7-10% of
GenerateData()wall time on a 182x218x182 label volume and is pure waste, because on any active configuration thelastpassblock writes every pixel of the region — verified by poisoning the seed with a sentinel and confirming all six baseline-compared tests still match bit-for-bit.Local validation
New GoogleTest
itkLabelSetMorphBaseImageFilterGTest.cxxin a new driver:ErodeZeroRadiusOnLastAxisStillErodesActiveAxis— fail-before: uninitialized garbage. Pass-after: correct erosion on the active axis.ErodeAllZeroRadiusIsIdentity/DilateAllZeroRadiusIsIdentity— fail-before: uninitialized garbage (e.g. 147 where 0 was expected). Pass-after: identity.ctest -L LabelErodeDilate: 8/8 pass, bit-identical baselines.AI assistance