00001
00030 #ifndef DistanceTransform_h
00031 #define DistanceTransform_h
00032
00033 #include <assert.h>
00034 #include <float.h>
00035 #include <limits.h>
00036
00037 #include <math.h>
00040 #ifndef M_SQRT2
00041 #define M_SQRT2 1.41421356237309504880
00042 #endif
00043
00044 #include <stdio.h>
00045
00047 class DistanceTransform {
00048
00049 public:
00054 static const int IntInfinity;
00059 static const double FloatInfinity;
00060
00062
00066 DistanceTransform ( const int xSize, const int ySize,
00067 const bool unload=true );
00068 virtual ~DistanceTransform ( );
00069
00071 virtual void doTransform ( const unsigned char* const I ) = 0;
00072
00074 inline double getD ( const int x, const int y ) const {
00075 if (dD != NULL) return dD[sub(x,y)];
00076
00077 assert( iD!=NULL );
00078 return iD[sub(x,y)];
00079 }
00080
00082
00089 virtual inline bool getP ( const int x, const int y, int& px, int& py )
00090 const {
00091 px = py = -1;
00092 return false;
00093 }
00094
00095 protected:
00096 int xSize;
00097 int ySize;
00098
00099
00100 double* dD;
00101 int* iD;
00102
00104 class P {
00105 public:
00106 int x;
00107 int y;
00108 inline P ( const int x, const int y ) {
00109 this->x = x;
00110 this->y = y;
00111 }
00112 };
00113
00116 inline int sub ( const int x, const int y ) const {
00117 if (x<0 || x>=this->xSize) {
00118 assert( x>=0 && x<this->xSize );
00119 }
00120 if (y<0 || y>=this->ySize) {
00121 assert( y>=0 && y<this->ySize );
00122 }
00123 assert( rowOffsets!=NULL );
00124 return rowOffsets[y] + x;
00125 }
00126
00128 template <class T>
00129 void initImmediate ( const unsigned char* const I, T* d,
00130 const T halfDx=0, const T halfDy=0 ) {
00131
00132
00133 for (int y=1; y<ySize-1; y++) {
00134 for (int x=1; x<xSize-1; x++) {
00135 if ( I[sub(x-1,y)] != I[sub(x,y)] ||
00136 I[sub(x+1,y)] != I[sub(x,y)] ) {
00137 if (halfDx < d[sub(x,y)]) d[sub(x,y)] = halfDx;
00138 }
00139 if ( I[sub(x,y-1)] != I[sub(x,y)] ||
00140 I[sub(x,y+1)] != I[sub(x,y)] ) {
00141 if (halfDy < d[sub(x,y)]) d[sub(x,y)] = halfDy;
00142 }
00143 }
00144 }
00145 };
00146
00147 template <class T>
00148 inline void check ( T* d, const int center, const int X, const int Y,
00149 const T Delta ) {
00150 const int Near = sub(X,Y);
00151 const T possible = d[Near] + Delta;
00152 if (possible < d[center]) {
00153 d[center] = possible;
00154 }
00155 }
00156
00157 virtual void borderCheck ( const unsigned char* const I );
00158 void cleanUp ( );
00159 void finish ( const unsigned char* const I, double* d );
00160 void finish ( const unsigned char* const I, int* d,
00161 const int dx, const int dy );
00162
00163 private:
00164 int* rowOffsets;
00165 bool unloadFlag;
00166 };
00167
00168 #endif
00169
00170