Skip to content

BUG: Fix bisection midpoint in ThresholdMaximumConnectedComponents#6595

Merged
thewtex merged 1 commit into
InsightSoftwareConsortium:mainfrom
physwkim:bug-threshold-max-connected-bisection-6575
Jul 13, 2026
Merged

BUG: Fix bisection midpoint in ThresholdMaximumConnectedComponents#6595
thewtex merged 1 commit into
InsightSoftwareConsortium:mainfrom
physwkim:bug-threshold-max-connected-bisection-6575

Conversation

@physwkim

Copy link
Copy Markdown
Contributor

Seed the bisection search at lowerBound + span/2 instead of span/2 in ThresholdMaximumConnectedComponentsImageFilter. Addresses B13 of #6575.

Root cause

itkThresholdMaximumConnectedComponentsImageFilter.hxx:107:

PixelType midpoint = (upperBound - lowerBound) / 2;                  // span/2, not the midpoint
PixelType midpointL = (lowerBound + (midpoint - lowerBound) / 2);
PixelType midpointR = (upperBound - (upperBound - midpoint) / 2);

The seed is the span, correct only when lowerBound == 0. For a nonzero lower bound midpoint lands below lowerBound, so the next line's unsigned midpoint - lowerBound wraps and corrupts the initial search bounds before the loop starts. The in-loop update at :147-148 already uses the correct lowerBound + (upperBound - lowerBound) / 2 form — the fix makes the seed use the same rule.

Local validation

New GoogleTest ThresholdMaximumConnectedComponentsImageFilter.BisectionIsTranslationInvariant: the same image, translated by an intensity offset of 3,000,000,000 (unsigned int pixels), must yield the same object count and a threshold shifted by exactly that offset.

Fail-before:

filterB->GetNumberOfObjects() = 1, filterA->GetNumberOfObjects() = 2
filterB->GetThresholdValue() = 11, filterA->GetThresholdValue() + offset = 3000000011
[  FAILED  ] ThresholdMaximumConnectedComponentsImageFilter.BisectionIsTranslationInvariant

Pass-after: [ PASSED ] 8 tests. (whole module GTest driver)

ctest -L ITKConnectedComponents: 15/16 pass, including itkThresholdMaximumConnectedComponentsImageFilterTest1/Test2 (real-image baselines) — unchanged. The 1 non-pass is ITKConnectedComponentsKWStyleTest, "Not Run" (KWStyle binary absent in this build tree; pre-existing, affects all KWStyle tests).

AI assistance

The initial midpoint used span/2 instead of lowerBound + span/2,
matching the in-loop update formula only when lowerBound is zero.
For unsigned pixel types with a nonzero lower bound, the subtraction
that follows wrapped, corrupting the initial search bounds.

Addresses item B13 of InsightSoftwareConsortium#6575.
@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Segmentation Issues affecting the Segmentation module labels Jul 13, 2026
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the first bisection midpoint used by the connected-components threshold filter. The main changes are:

  • Initial midpoint now starts at lowerBound + span / 2.
  • ConnectedComponents GTest driver includes a new regression test source.
  • New test checks threshold translation with a large unsigned-int offset.

Confidence Score: 5/5

This looks safe to merge.

No blocking issues found in the changed code.

No files need attention.

T-Rex T-Rex Logs

What T-Rex did

  • I reviewed the tool-availability log and confirmed that cmake, ctest, ninja, and pixi exits were 127, indicating missing executables, while C++ and make are reported as available.
  • I examined the driver-search log and confirmed that no ITKConnectedComponentsGTestDriver executable could be located, explaining why tests cannot run.
  • I checked the source-registration log and confirmed that CMakeLists.txt includes itkThresholdMaximumConnectedComponentsImageFilterGTest.cxx and that the GTest source defines a test named ThresholdMaximumConnectedComponentsImageFilter, BisectionIsTranslationInvariant.
  • These findings show that the test environment is currently blocked by missing tooling and by the absence of a GTest driver, outlining what would be needed to proceed.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
Modules/Segmentation/ConnectedComponents/include/itkThresholdMaximumConnectedComponentsImageFilter.hxx Corrects the initial threshold-search midpoint so nonzero image minima stay inside the search range.
Modules/Segmentation/ConnectedComponents/test/CMakeLists.txt Adds the new threshold maximum connected components GTest source to the existing driver.
Modules/Segmentation/ConnectedComponents/test/itkThresholdMaximumConnectedComponentsImageFilterGTest.cxx Adds a focused unsigned-int regression test for large-offset translation invariance.

Reviews (1): Last reviewed commit: "BUG: Fix bisection midpoint in Threshold..." | Re-trigger Greptile

@thewtex
thewtex merged commit 584f866 into InsightSoftwareConsortium:main Jul 13, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Segmentation Issues affecting the Segmentation module type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants