Skip to content

Commit 3abace1

Browse files
blowekampLeengit
authored andcommitted
BUG: Fix StatisticsLabelMap median for even number of pixels
When there are an even number of elements, average the bins measurements vectors of the middle two.
1 parent 55d0fdf commit 3abace1

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

Modules/Filtering/LabelMap/include/itkStatisticsLabelMapFilter.hxx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,28 @@ StatisticsLabelMapFilter<TImage, TFeatureImage>::ThreadedProcessLabelObject(Labe
177177
}
178178

179179
// the median
180-
double median = 0;
181-
double count = 0; // will not be fully set, so do not use later !
182-
for (SizeValueType i = 0; i < histogram->Size(); i++)
180+
double median = 0.0;
181+
double count = 0.0; // will not be fully set, so do not use later !
182+
for (SizeValueType i = 0; i < histogram->Size(); ++i)
183183
{
184184
count += histogram->GetFrequency(i);
185185

186186
if (count >= (totalFreq / 2))
187187
{
188188
median = histogram->GetMeasurementVector(i)[0];
189+
// If there are an even number of elements average with the next bin with elements
190+
if (labelObject->Size() % 2 == 0 && count == totalFreq / 2)
191+
{
192+
while (++i < histogram->Size())
193+
{
194+
if (histogram->GetFrequency(i) > 0)
195+
{
196+
median += histogram->GetMeasurementVector(i)[0];
197+
median *= 0.5;
198+
break;
199+
}
200+
}
201+
}
189202
break;
190203
}
191204
}

Modules/Filtering/LabelMap/test/itkStatisticsLabelMapFilterGTest.cxx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,39 @@ TEST_F(StatisticsLabelMapFixture, 2D_rand_with_outliers)
249249
labelObject->Print(std::cout);
250250
}
251251
}
252+
253+
254+
TEST_F(StatisticsLabelMapFixture, 2D_even)
255+
{
256+
using Utils = FixtureUtilities<2, unsigned char>;
257+
258+
auto image = Utils::CreateImage();
259+
auto labelImage = Utils ::CreateLabelImage();
260+
261+
// Set label with two elements far apart, the median should be average
262+
image->SetPixel({ 0, 0 }, 10);
263+
image->SetPixel({ 0, 1 }, 100);
264+
image->SetPixel({ 0, 2 }, 1);
265+
image->SetPixel({ 0, 3 }, 200);
266+
267+
Utils::LabelPixelType label = 1;
268+
labelImage->SetPixel({ 0, 0 }, label);
269+
labelImage->SetPixel({ 0, 1 }, label);
270+
labelImage->SetPixel({ 0, 2 }, label);
271+
labelImage->SetPixel({ 0, 3 }, label);
272+
273+
274+
Utils::LabelObjectType::ConstPointer labelObject = Utils::ComputeLabelObject(labelImage, image, label, 1 << 8);
275+
276+
EXPECT_NEAR(1.0, labelObject->GetMinimum(), 1e-12);
277+
EXPECT_NEAR(200.0, labelObject->GetMaximum(), 1e-12);
278+
EXPECT_NEAR(Utils::ComputeExactMedian(labelObject, image), labelObject->GetMedian(), 0.5);
279+
EXPECT_NEAR(311.0, labelObject->GetSum(), 1e-12);
280+
EXPECT_NEAR(8640.25, labelObject->GetVariance(), 1e-10);
281+
EXPECT_NEAR(92.95294, labelObject->GetStandardDeviation(), 1e-5);
282+
283+
if (::testing::Test::HasFailure())
284+
{
285+
labelObject->Print(std::cout);
286+
}
287+
}

0 commit comments

Comments
 (0)