Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef FILTERS_MEDIAN_H
00031 #define FILTERS_MEDIAN_H
00032
00033 #include <stdint.h>
00034 #include <sstream>
00035 #include <cstdio>
00036
00037 #include <boost/scoped_ptr.hpp>
00038
00039 #include "filters/filter_base.h"
00040
00041 #include "filters/realtime_circular_buffer.h"
00042
00043
00044
00045
00046
00047
00048
00049 #define ELEM_SWAP(a,b) { register elem_type t=(a);(a)=(b);(b)=t; }
00050
00051 namespace filters
00052 {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 template <typename elem_type>
00067 elem_type kth_smallest(elem_type a[], int n, int k)
00068 {
00069 register int i,j,l,m ;
00070 register elem_type x ;
00071 l=0 ; m=n-1 ;
00072 while (l<m) {
00073 x=a[k] ;
00074 i=l ;
00075 j=m ;
00076 do {
00077 while (a[i]<x) i++ ;
00078 while (x<a[j]) j-- ;
00079 if (i<=j) {
00080 ELEM_SWAP(a[i],a[j]) ;
00081 i++ ; j-- ;
00082 }
00083 } while (i<=j) ;
00084 if (j<k) l=i ;
00085 if (k<i) m=j ;
00086 }
00087 return a[k] ;
00088 }
00089 #define median(a,n) kth_smallest(a,n,(((n)&1)?((n)/2):(((n)/2)-1)))
00090 #undef ELEM_SWAP
00091
00092
00096 template <typename T>
00097 class MedianFilter: public filters::FilterBase <T>
00098 {
00099 public:
00101 MedianFilter();
00102
00105 ~MedianFilter();
00106
00107 virtual bool configure();
00108
00113 virtual bool update(const T& data_in, T& data_out);
00114
00115 protected:
00116 std::vector<T> temp_storage_;
00117 boost::scoped_ptr<RealtimeCircularBuffer<T > > data_storage_;
00118
00119 T temp;
00120
00121
00122 uint32_t number_of_observations_;
00123
00124 };
00125
00126 template <typename T>
00127 MedianFilter<T>::MedianFilter():
00128 number_of_observations_(0)
00129 {
00130
00131 };
00132
00133 template <typename T>
00134 MedianFilter<T>::~MedianFilter()
00135 {
00136 };
00137
00138
00139 template <typename T>
00140 bool MedianFilter<T>::configure()
00141 {
00142 int no_obs = -1;
00143 if (!FilterBase<T>::getParam(std::string("number_of_observations"), no_obs))
00144 {
00145 fprintf(stderr, "Error: MedianFilter was not given params.\n");
00146 return false;
00147 }
00148 number_of_observations_ = no_obs;
00149
00150 data_storage_.reset( new RealtimeCircularBuffer<T >(number_of_observations_, temp));
00151 temp_storage_.resize(number_of_observations_);
00152
00153 return true;
00154 };
00155
00156 template <typename T>
00157 bool MedianFilter<T>::update(const T& data_in, T& data_out)
00158 {
00159 if (!FilterBase<T>::configured_)
00160 return false;
00161
00162 data_storage_->push_back(data_in);
00163
00164
00165 unsigned int length = data_storage_->size();
00166
00167
00168 for (uint32_t row = 0; row < length; row ++)
00169 {
00170 temp_storage_[row] = (*data_storage_)[row];
00171 }
00172 data_out = median(&temp_storage_[0], length);
00173
00174
00175 return true;
00176 };
00180 template <typename T>
00181 class MultiChannelMedianFilter: public filters::MultiChannelFilterBase <T>
00182 {
00183 public:
00185 MultiChannelMedianFilter();
00186
00189 ~MultiChannelMedianFilter();
00190
00191 virtual bool configure();
00192
00197 virtual bool update(const std::vector<T>& data_in, std::vector<T>& data_out);
00198
00199 protected:
00200 std::vector<T> temp_storage_;
00201 boost::scoped_ptr<RealtimeCircularBuffer<std::vector<T> > > data_storage_;
00202
00203 std::vector<T> temp;
00204
00205
00206 uint32_t number_of_observations_;
00207
00208 };
00209
00210 template <typename T>
00211 MultiChannelMedianFilter<T>::MultiChannelMedianFilter():
00212 number_of_observations_(0)
00213 {
00214
00215 };
00216
00217 template <typename T>
00218 MultiChannelMedianFilter<T>::~MultiChannelMedianFilter()
00219 {
00220 };
00221
00222
00223 template <typename T>
00224 bool MultiChannelMedianFilter<T>::configure()
00225 {
00226 int no_obs = -1;
00227 if (!FilterBase<T>::getParam("number_of_observations", no_obs))
00228 {
00229 fprintf(stderr, "Error: MultiChannelMedianFilter was not given params.\n");
00230 return false;
00231 }
00232 number_of_observations_ = no_obs;
00233
00234 temp.resize(this->number_of_channels_);
00235 data_storage_.reset( new RealtimeCircularBuffer<std::vector<T> >(number_of_observations_, temp));
00236 temp_storage_.resize(number_of_observations_);
00237
00238 return true;
00239 };
00240
00241 template <typename T>
00242 bool MultiChannelMedianFilter<T>::update(const std::vector<T>& data_in, std::vector<T>& data_out)
00243 {
00244
00245 if (data_in.size() != this->number_of_channels_ || data_out.size() != this->number_of_channels_)
00246 return false;
00247 if (!FilterBase<T>::configured_)
00248 return false;
00249
00250 data_storage_->push_back(data_in);
00251
00252
00253 unsigned int length = data_storage_->size();
00254
00255
00256 for (uint32_t i = 0; i < this->number_of_channels_; i++)
00257 {
00258 for (uint32_t row = 0; row < length; row ++)
00259 {
00260 temp_storage_[row] = (*data_storage_)[row][i];
00261 }
00262 data_out[i] = median(&temp_storage_[0], length);
00263 }
00264
00265 return true;
00266 };
00267
00268
00269 }
00270 #endif// FILTERS_MEDIAN_H