00001 #ifndef FILTER_H
00002 #define FILTER_H
00003
00004 #include <vector>
00005 #include "mimasexception.h"
00006 #include "image.h"
00007
00008 namespace mimas {
00009 class property_image;
00010
00022 template<typename T>
00023 class filter
00024 {
00025 public:
00026
00027
00028
00029 protected:
00030 void filterRows(image<T> &input, image<T>&output,
00031 std::vector<double> * prof1d);
00032 void filterCols(image<T> &input, image<T>&output,
00033 std::vector<double> * prof1d);
00034
00035
00036 public:
00037
00038 virtual ~filter() {}
00039
00040 virtual void filterIt( image<T>& input )=0;
00041 virtual void filterTo( image<T>& input, image<T>& output)=0;
00042
00043
00044
00045 static void gradX( const image<T>& input, image<T>& output );
00046 static void gradY( const image<T>& input, image<T>& output );
00047 static void nonMaximaSuppression( const image<T>& gradx,
00048 const image<T>& grady,
00049 const image<T>& gradsq,
00050 double threshold,
00051 property_image& output )
00052 throw (mimasexception);
00053 };
00054
00055
00056
00057 template<typename T>
00058 void filter<T>::filterRows( image<T> &input, image<T>& output,
00059 std::vector<double>* prof1d )
00060 {
00061 double norm=0;
00062 int mp, w=input.getWidth();
00063 boost::shared_array< T > row( new T[input.getWidth()] );
00064 double v;
00065 int nx;
00066
00067 if ( &output != &input )
00068 output.init( input.getWidth(), input.getHeight());
00069
00070 for(int i=0;i<(signed)prof1d->size();++i)
00071 norm+=(*prof1d)[i];
00072
00073 if (norm==0) return;
00074 mp = prof1d->size()/2;
00075
00076 for(int y=0;y<input.getHeight();++y)
00077 {
00078
00079
00080 for(int x=0;x<mp;++x)
00081 {
00082 v=0;
00083
00084 nx=x-mp;
00085 for(int i=0;i<(signed)prof1d->size();++i,++nx)
00086 {
00087 if (nx>0 && nx<w)
00088 {
00089 v+=input.pixel(nx,y) * (*prof1d)[i];
00090 }
00091 }
00092 v/=norm;
00093 row[x] = (T)v;
00094 }
00095
00096
00097 for(int x=mp;x<(w-mp);++x)
00098 {
00099 v=0;
00100
00101 nx=x-mp;
00102 for(int i=0;i<(signed)prof1d->size();++i,++nx)
00103 v+=input.pixel(nx,y) * (*prof1d)[i];
00104 v/=norm;
00105 row[x] = (T)v;
00106 }
00107
00108
00109 for(int x=w-mp;x<w;++x)
00110 {
00111 v=0;
00112
00113 nx=x-mp;
00114 for(int i=0;i<(signed)prof1d->size();++i,++nx)
00115 {
00116 if (nx>0 && nx<w)
00117 {
00118 v+=input.pixel(nx,y) * (*prof1d)[i];
00119 }
00120 }
00121 v/=norm;
00122 row[x] = (T)v;
00123 }
00124
00125
00126 copy( row.get(), row.get() + input.getWidth(), output.rawData()[y].begin() );
00127 }
00128 }
00129
00130
00131 template<typename T>
00132 void filter<T>::filterCols( image<T> &input, image<T>& output,
00133 std::vector<double>* prof1d )
00134 {
00135 double norm=0;
00136 int i,mp, h=input.getHeight(),y;
00137 boost::shared_array< T > col( new T[input.getHeight()] );
00138 double v=0;
00139 int ny;
00140
00141
00142 if ( &output != &input )
00143 output.init( input.getWidth(), input.getHeight());
00144
00145 for(i=0;i<(signed)prof1d->size();++i)
00146 norm+=(*prof1d)[i];
00147
00148 if (norm==0) return;
00149 mp = prof1d->size()/2;
00150
00151 for(int x=0;x<input.getWidth();++x)
00152 {
00153 for(y=0;y<h;++y)
00154 col[y]=input.pixel(x,y);
00155
00156
00157
00158
00159 for(y=0;y<mp;++y)
00160 {
00161 v=0;
00162
00163 ny=y-mp;
00164 for(i=0;i<(signed)prof1d->size();++i,++ny)
00165 {
00166 if (ny>0 && ny<h)
00167 v+=input.pixel(x,ny) * (*prof1d)[i];
00168 }
00169 v/=norm;
00170 col[y] = (T)v;
00171 }
00172
00173
00174 for(y=mp;y<(h-mp);++y)
00175 {
00176 v=0;
00177
00178 ny=y-mp;
00179 for(i=0;i<(signed)prof1d->size();++i,++ny)
00180 v+=input.pixel(x,ny) * (*prof1d)[i];
00181 v/=norm;
00182 col[y] = (T)v;
00183 }
00184
00185
00186 for(y=(h-mp);y<h;++y)
00187 {
00188 v=0;
00189
00190 ny=y-mp;
00191 for(i=0;i<(signed)prof1d->size();++i,++ny)
00192 {
00193 if (ny>0 && ny<h)
00194 v+=input.pixel(x,ny) * (*prof1d)[i];
00195 }
00196 v/=norm;
00197 col[y] = (T)v;
00198 }
00199
00200 for(y=0;y<h;++y)
00201 output.pixel(x,y)=col[y];
00202 }
00203
00204 }
00206
00207 }
00208
00209 #include "filter_grad.h"
00210 #include "filter_nonmaxsup.h"
00211
00212 #endif