00001 #include <map>
00002 #include "MedianFilter.h"
00003
00004
00005 using std::ostringstream;
00006 using std::map;
00007 using std::multimap;
00008 using std::less;
00009 using std::pair;
00010 using std::min;
00011 using std::max;
00012
00013 using namespace Marsyas;
00014
00015 MedianFilter::MedianFilter(mrs_string inName)
00016 :MarSystem("MedianFilter",inName)
00017 {
00018 addControls();
00019 }
00020
00021 MedianFilter::MedianFilter(const MedianFilter& inToCopy)
00022 :MarSystem(inToCopy)
00023 {
00024 ctrl_WindowSize_ = getctrl("mrs_natural/WindowSize");
00025 WindowSize_ = inToCopy.WindowSize_;
00026 }
00027
00028 MedianFilter::~MedianFilter(){}
00029
00030 MarSystem* MedianFilter::clone() const
00031 {
00032 return new MedianFilter(*this);
00033 }
00034
00035 void MedianFilter::addControls()
00036 {
00037 addctrl("mrs_natural/WindowSize",10,ctrl_WindowSize_);
00038 ctrl_WindowSize_->setState(true);
00039 WindowSize_ = 10;
00040 }
00041
00042 void MedianFilter::myUpdate(MarControlPtr inSender)
00043 {
00044 WindowSize_ = ctrl_WindowSize_->to<mrs_natural>();
00045 MarSystem::myUpdate(inSender);
00046 }
00047
00048 void MedianFilter::myProcess(realvec& inVec, realvec& outVec)
00049 {
00050
00051
00052
00053
00054
00055
00056 mrs_natural N = WindowSize_;
00057 multimap<mrs_real,mrs_natural,less<mrs_real> > theWindow;
00058 typedef multimap<mrs_real,mrs_natural,less<mrs_real> >::iterator iter;
00059 typedef pair<mrs_real,mrs_natural> element;
00060
00061
00062 mrs_natural M = (mrs_natural)floor((mrs_real)N/2.);
00063
00064
00065
00066 for (int p=-M; p<=0; p++)
00067 theWindow.insert(element(inVec(0),p));
00068 for (int p=1; p<=N-M-1; p++)
00069 theWindow.insert(element(inVec(p),p));
00070
00071 mrs_natural I = inVec.getSize();
00072 for (int i=0; i<I; ++i)
00073 {
00074
00075 element theNewOne(inVec(min(i+N-M,I-1)),i+N-M);
00076
00077
00078 int theOffset = -M;
00079
00080 iter theMedian, theToDelete, theToInsert = theWindow.begin();
00081 for (iter theIter=theWindow.begin(); theIter!=theWindow.end(); theIter++)
00082 {
00083 if (theOffset == 0)
00084 theMedian = theIter;
00085 if (theIter->second == i-M)
00086
00087 theToDelete = theIter;
00088 if (theNewOne.first > theIter->first)
00089 {
00090
00091
00092 theToInsert = theIter;
00093 theToInsert++;
00094 }
00095 theOffset++;
00096 }
00097
00098 if (theToInsert == theToDelete)
00099 theToInsert++;
00100
00101 outVec(i) = theMedian->first;
00102 theWindow.erase(theToDelete);
00103 theWindow.insert(theToInsert,theNewOne);
00104 }
00105 }