00001 #ifndef __MEDIAN_FILTER_H__
00002 #define __MEDIAN_FILTER_H__
00003
00004 #include <vuVector.h>
00005 #include <Utilities.h>
00006 #include <vuML.h>
00007 #include <Dataset.h>
00008
00009 #include <VVector.h>
00010 #include <VVectorFun.h>
00011 using namespace math;
00012
00013 #include <assert.h>
00014 #include <cmath>
00015
00016 #include <string>
00017 #include <algorithm>
00018 using namespace std;
00019
00021 class Neighborhood {
00022
00023 public:
00024
00026 Neighborhood(): m_size(0) {}
00027
00029 void print() const {
00030
00031
00032
00033
00034 cout << "Neighborhood size is " << m_size << endl;
00035 }
00036
00038 int getSize() const { return m_size; }
00039
00041 Vector3i& operator[](int i) {
00042 assert ( i >= 0 && i < MAX_NUM );
00043 return m_locations[i];
00044 }
00045
00047 const Vector3i& operator[](int i) const {
00048 assert ( i >= 0 && i < MAX_NUM );
00049 return m_locations[i];
00050 }
00051
00053
00056 void setSize(int s) { m_size = s; }
00057
00059 void addNeighbor(const Vector3i& l) {
00060 m_locations[m_size] = l;
00061 m_size++;
00062 }
00063
00064 private:
00065
00066 Vector3i m_locations[MAX_NUM];
00067 int m_size;
00068 };
00069
00071 class SphericalFilter {
00072
00073 public:
00074
00076 SphericalFilter(): m_radius(0.0) {}
00077
00079 void filter(const Dataset& in, Dataset& out) {
00080 int numSamples = in.getNumSamples();
00081
00082 out.copyAttribs(in);
00083
00084 int i;
00085 for ( i = 0; i < numSamples; i++ ) {
00086 out[i] = filter(in, i);
00087 }
00088 }
00089
00091 int getNeighborhoodSize() const { return m_neighborhood.getSize(); }
00092
00094 void print() const {
00095 cout << "Filter radius = " << m_radius << endl;
00096 int numNeighbors = m_neighborhood.getSize();
00097 cout << "Neighorhood size = " << numNeighbors << endl;
00098 int i;
00099 for ( i = 0; i < numNeighbors; i++ ) {
00100 cout << "Neighbor " << i << " = " << m_neighborhood[i]
00101 << " has weight " << m_weights[i] << endl;
00102 }
00103 }
00104
00106 static double gaussianFunc(const double& sigma,
00107 const double& x,
00108 const double& y,
00109 const double& z) {
00110 return exp( -(x*x + y*y + z*z) / (2.0 * sigma*sigma));
00111 }
00112
00114 static double gaussianFunc(const double& sigma, const Vector3i& p) {
00115 double x = double(p[0]);
00116 double y = double(p[1]);
00117 double z = double(p[2]);
00118
00119 return gaussianFunc(sigma, x, y, z);
00120 }
00121
00123 double getRadius() const { return m_radius; }
00124
00126 virtual void setRadius(const double& r) = 0;
00127
00128 protected:
00129
00131 virtual double filter(const Dataset& in, int i) = 0;
00132
00134 Neighborhood m_neighborhood;
00135
00137
00140 double m_weights[MAX_NUM];
00141
00143
00147 double m_radius;
00148 };
00149
00151 class SphericalFilterCC : public SphericalFilter {
00152 public:
00153
00155 void setRadius(const double& r) {
00156 m_neighborhood.setSize(0);
00157
00158 m_radius = 0;
00159
00160
00161 int radius_int = int(r);
00162 Vector3i min(-radius_int);
00163 Vector3i max(radius_int);
00164
00165 int x, y, z;
00166 for ( x = min[0]; x <= max[0]; x++ ) {
00167 for ( y = min[1]; y <= max[1]; y++ ) {
00168 for ( z = min[2]; z <= max[2]; z++ ) {
00169 int p_arr[] = {x,y,z};
00170 Vector3i p(p_arr);
00171 double norm_p = norm(p);
00172 if ( norm_p <= r ) {
00173 m_neighborhood.addNeighbor(p);
00174
00175
00176 if ( norm_p > m_radius ) {
00177 m_radius = norm_p;
00178 }
00179 }
00180 }
00181 }
00182 }
00183
00184 printf("Radius is %lf, ", m_radius);
00185 m_neighborhood.print();
00186 }
00187
00188 };
00189
00191 class MedianSphericalFilterCC : public SphericalFilterCC {
00192 private:
00193
00195 double filter(const Dataset& in, int index) {
00196 int numNeighbors = m_neighborhood.getSize();
00197 Vector3i p = in.mindex_cc(index);
00198
00199 assert(numNeighbors > 0);
00200
00201 int i;
00202 for ( i = 0; i < numNeighbors; i++ ) {
00203 Vector3i neighbor = p + m_neighborhood[i];
00204 int neighbor_index = in.lindex_cc(neighbor);
00205 m_weights[i] = in[neighbor_index];
00206 }
00207
00208 sort(m_weights, m_weights+numNeighbors);
00209
00210 if ( ODD(numNeighbors) ) {
00211 int median = (numNeighbors - 1) / 2;
00212
00213 return m_weights[median];
00214 }
00215
00216
00217 int m1 = numNeighbors / 2;
00218 int m2 = m1 - 1;
00219
00220 return 0.5*(m_weights[m1] + m_weights[m2]);
00221 }
00222 };
00223
00225 class GaussianSphericalFilterCC : public SphericalFilterCC {
00226 public:
00227
00229 void setRadius(const double& r) {
00230
00231
00232
00233 SphericalFilterCC::setRadius(r);
00234
00235
00236 if ( EQUALS(m_radius, 0.0) ) {
00237 m_weights[0] = 1.0;
00238 return;
00239 }
00240
00241
00242 double N = 3.0;
00243 double sigma = m_radius / N;
00244
00245
00246 int i;
00247 int numNeighbors = m_neighborhood.getSize();
00248 double sum = 0;
00249 for ( i = 0; i < numNeighbors; i++ ) {
00250 Vector3i neighbor = m_neighborhood[i];
00251 m_weights[i] = gaussianFunc(sigma, neighbor);
00252 sum += m_weights[i];
00253 }
00254
00255
00256 for ( i = 0; i < numNeighbors; i++ ) {
00257 m_weights[i] /= sum;
00258 }
00259 }
00260
00261 private:
00262
00264 double filter(const Dataset& in, int index) {
00265 int numNeighbors = m_neighborhood.getSize();
00266 Vector3i p = in.mindex_cc(index);
00267
00268 assert(numNeighbors > 0);
00269
00270 double filtered_val = 0.0;
00271 int i;
00272 for ( i = 0; i < numNeighbors; i++ ) {
00273 Vector3i neighbor = p + m_neighborhood[i];
00274 int neighbor_index = in.lindex_cc(neighbor);
00275 filtered_val += in[neighbor_index] * m_weights[i];
00276 }
00277
00278 return filtered_val;
00279 }
00280 };
00281
00283 class SphericalFilterBCC : public SphericalFilter {
00284 public:
00286 void setRadius(const double& r) {
00287 m_neighborhood.setSize(0);
00288
00289 m_radius = 0;
00290
00291
00292 int radius_int = int(r);
00293 Vector3i min(-radius_int);
00294 Vector3i max(radius_int);
00295
00296 int x, y, z;
00297 for ( x = min[0]; x <= max[0]; x++ ) {
00298 for ( y = min[1]; y <= max[1]; y++ ) {
00299 for ( z = min[2]; z <= max[2]; z++ ) {
00300 int p_arr[] = {x,y,z};
00301 Vector3i p(p_arr);
00302 double norm_p = norm(p);
00303 if ( norm_p <= r ) {
00304
00305 if ( ( ODD(x) && ODD(y) && ODD(z) ) ||
00306 ( EVEN(x) && EVEN(y) && EVEN(z) ) ) {
00307 m_neighborhood.addNeighbor(p);
00308
00309
00310 if ( norm_p > m_radius ) {
00311 m_radius = norm_p;
00312 }
00313 }
00314 }
00315 }
00316 }
00317 }
00318
00319 printf("Radius is %lf, ", m_radius);
00320 m_neighborhood.print();
00321 }
00322 };
00323
00325 class MedianSphericalFilterBCC : public SphericalFilterBCC {
00326 private:
00327
00329 double filter(const Dataset& in, int index) {
00330 int numNeighbors = m_neighborhood.getSize();
00331 Vector3i p = in.mindex_bcc(index);
00332
00333 assert(numNeighbors > 0);
00334
00335 int i;
00336 for ( i = 0; i < numNeighbors; i++ ) {
00337 Vector3i neighbor = p + m_neighborhood[i];
00338 int neighbor_index = in.lindex_bcc(neighbor);
00339 m_weights[i] = in[neighbor_index];
00340 }
00341
00342 sort(m_weights, m_weights+numNeighbors);
00343
00344 if ( ODD(numNeighbors) ) {
00345 int median = (numNeighbors - 1) / 2;
00346
00347 return m_weights[median];
00348 }
00349
00350
00351 int m1 = numNeighbors / 2;
00352 int m2 = m1 - 1;
00353
00354 return 0.5*(m_weights[m1] + m_weights[m2]);
00355 }
00356 };
00357
00359 class GaussianSphericalFilterBCC : public SphericalFilterBCC {
00360 public:
00361
00363 void setRadius(const double& r) {
00364
00365
00366
00367 SphericalFilterBCC::setRadius(r);
00368
00369
00370 if ( EQUALS(m_radius, 0.0) ) {
00371 m_weights[0] = 1.0;
00372 return;
00373 }
00374
00375
00376 double N = 3.0;
00377 double sigma = m_radius / N;
00378
00379
00380 int i;
00381 int numNeighbors = m_neighborhood.getSize();
00382 double sum = 0;
00383 for ( i = 0; i < numNeighbors; i++ ) {
00384 Vector3i neighbor = m_neighborhood[i];
00385 m_weights[i] = gaussianFunc(sigma, neighbor);
00386 sum += m_weights[i];
00387 }
00388
00389
00390 for ( i = 0; i < numNeighbors; i++ ) {
00391 m_weights[i] /= sum;
00392 }
00393 }
00394
00395 private:
00396
00398 double filter(const Dataset& in, int index) {
00399 int numNeighbors = m_neighborhood.getSize();
00400 Vector3i p = in.mindex_bcc(index);
00401
00402 assert(numNeighbors > 0);
00403
00404 double filtered_val = 0.0;
00405 int i;
00406 for ( i = 0; i < numNeighbors; i++ ) {
00407 Vector3i neighbor = p + m_neighborhood[i];
00408 int neighbor_index = in.lindex_bcc(neighbor);
00409 filtered_val += in[neighbor_index] * m_weights[i];
00410 }
00411
00412 return filtered_val;
00413 }
00414 };
00415
00416 #endif