# HG changeset patch # User Chris Cannam # Date 1424688174 0 # Node ID 5ec47007b8734b586fcc4586f05d0b3cefcb4818 # Parent b2772559aebcfb99b403e021910a6cac8c80446b Fix handling of NaNs in MedianFilter, & test for it diff -r b2772559aebc -r 5ec47007b873 maths/MedianFilter.h --- a/maths/MedianFilter.h Tue Aug 05 17:12:46 2014 +0100 +++ b/maths/MedianFilter.h Mon Feb 23 10:42:54 2015 +0000 @@ -48,8 +48,9 @@ void push(T value) { if (value != value) { - std::cerr << "WARNING: MedianFilter::push: attempt to push NaN" << std::endl; - return; // nan + std::cerr << "WARNING: MedianFilter::push: attempt to push NaN, pushing zero instead" << std::endl; + // we do need to push something, to maintain the filter length + value = T(); } drop(m_frame[0]); const int sz1 = m_size-1; diff -r b2772559aebc -r 5ec47007b873 tests/TestMedianFilter.cpp --- a/tests/TestMedianFilter.cpp Tue Aug 05 17:12:46 2014 +0100 +++ b/tests/TestMedianFilter.cpp Mon Feb 23 10:42:54 2015 +0000 @@ -3,6 +3,7 @@ #include "maths/MedianFilter.h" #include +#include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN @@ -171,6 +172,51 @@ BOOST_CHECK_EQUAL(ifilt.get(), 2); } +BOOST_AUTO_TEST_CASE(inf) +{ + // Inf and -Inf should behave normally + double pinf = strtod("Inf", 0); + double ninf = strtod("-Inf", 0); + MedianFilter dfilt(3); + dfilt.push(1.0); + dfilt.push(2.0); + dfilt.push(pinf); + BOOST_CHECK_EQUAL(dfilt.get(), 2.0); + dfilt.push(pinf); + BOOST_CHECK_EQUAL(dfilt.get(), pinf); + dfilt.push(pinf); + BOOST_CHECK_EQUAL(dfilt.get(), pinf); + dfilt.push(2.0); + BOOST_CHECK_EQUAL(dfilt.get(), pinf); + dfilt.push(1.0); + BOOST_CHECK_EQUAL(dfilt.get(), 2.0); + dfilt.push(ninf); + BOOST_CHECK_EQUAL(dfilt.get(), 1.0); + dfilt.push(pinf); + BOOST_CHECK_EQUAL(dfilt.get(), 1.0); + dfilt.push(ninf); + BOOST_CHECK_EQUAL(dfilt.get(), ninf); +} + +BOOST_AUTO_TEST_CASE(nan) +{ + // The filter should never accept a NaN, because it breaks sorting + // and comparison and that will break the filter. Instead it + // should insert 0. + double nan = strtod("NaN", 0); + MedianFilter dfilt(3); + dfilt.push(1.0); + dfilt.push(2.0); + dfilt.push(nan); + BOOST_CHECK_EQUAL(dfilt.get(), 1.0); + dfilt.push(nan); + BOOST_CHECK_EQUAL(dfilt.get(), 0.0); + dfilt.push(-11.0); + BOOST_CHECK_EQUAL(dfilt.get(), 0.0); + dfilt.push(-1.0); + BOOST_CHECK_EQUAL(dfilt.get(), -1.0); +} + BOOST_AUTO_TEST_SUITE_END()