changeset 407:f898c901c055

Fix handling of NaNs in MedianFilter, & test for it
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 23 Feb 2015 10:42:54 +0000
parents ebde9a50bb74
children 5316fa4b0f33
files maths/MedianFilter.h tests/TestMedianFilter.cpp
diffstat 2 files changed, 49 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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 <cmath>
+#include <cstdlib>
 
 #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<double> 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<double> 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()