Go to the documentation of this file.00001
00013 #ifndef GaussOperator_H
00014 #define GaussOperator_H
00015
00016 #include "ImageToImageOperator.h"
00017 #include "SingleElementImage.h"
00018 #include <cmath>
00019
00020 namespace puma2 {
00021
00033 template <class T> class GaussOperator :
00034 public ImageToImageOperator<SingleElementImage<T>,SingleElementImage<T> >
00035 {
00036 private:
00037
00042 int maskradius;
00043
00047 float sigma;
00048
00053 double* kernel;
00054
00055
00056 public:
00057
00075 GaussOperator(float sigma=3.0f, int maskRadius=0);
00076
00083 virtual ~GaussOperator();
00084
00094 virtual void apply(const SingleElementImage<T> & iImg,
00095 SingleElementImage<T> & oImg);
00096
00097 float getSigma() const { return sigma; }
00098 };
00099
00100
00101
00102
00103
00104 template <class T> GaussOperator<T>::GaussOperator(float sigma, int maskSize)
00105 {
00106 this->sigma = sigma;
00107
00108
00109 if (sigma < 0.5f)
00110 sigma = 0.5f;
00111 else if (sigma > 10.0f)
00112 sigma = 10.0f;
00113
00114 int masksize;
00115
00116
00117 if (maskSize >= 3 && maskSize <= 61)
00118 masksize = maskSize;
00119
00120 else
00121 masksize = (int) (floor(6 * sigma + 0.5));
00122
00123 if (masksize % 2 == 0)
00124 ++masksize;
00125
00126 this->maskradius = masksize / 2;
00127
00128 kernel = new double[masksize];
00129 float sigma2 = sigma*sigma;
00130
00131
00132 double teiler = sqrt(2 * M_PI) * sigma;
00133 for(int i = -maskradius; i <= maskradius; i++)
00134 {
00135 double distance = (double) (i * i);
00136 double e = exp( -distance / (2.0 * sigma2) );
00137 kernel[i + maskradius] = e / teiler;
00138 }
00139 }
00140
00141
00142
00143
00144 template <class T> GaussOperator<T>::~GaussOperator()
00145 {
00146 delete[] kernel;
00147 }
00148
00149
00150
00151
00152
00153 template <class T> void GaussOperator<T>::apply(
00154 const SingleElementImage<T> & iImg, SingleElementImage<T> & oImg)
00155 {
00156 int imageWidth = iImg.getWidth();
00157 int imageHeight = iImg.getHeight();
00158
00159 assert(2 * maskradius + 1 < imageHeight);
00160 assert(2 * maskradius + 1 < imageWidth);
00161
00162 SingleElementImage<T> tempImage(imageWidth,imageHeight);
00163
00164
00165
00166 for(int y_x = 0; y_x < imageHeight; ++y_x)
00167 {
00168 for(int x_x = 0; x_x < imageWidth; ++x_x)
00169 {
00170 double xValue = 0.0;
00171 for(int m = maskradius; m >= -maskradius; --m)
00172 {
00173 int xx = 0;
00174 if( x_x - m < 0 )
00175 xx = 0;
00176 else if ( x_x - m > imageWidth - 1)
00177 xx = imageWidth - 1;
00178 else
00179 xx = x_x - m;
00180 xValue += iImg[y_x][xx] * kernel[m + maskradius];
00181 }
00182 tempImage[y_x][x_x] = (T) xValue;
00183 }
00184 }
00185
00186
00187
00188 for(int y_y = 0; y_y < imageHeight; ++y_y)
00189 {
00190 for(int x_y = 0; x_y < imageWidth; ++x_y)
00191 {
00192 double yValue = 0.0;
00193 for(int m = maskradius; m >= -maskradius; --m)
00194 {
00195 int yy = 0;
00196
00197
00198
00199 if ( y_y - m < 0 )
00200 yy = 0;
00201 else if ( y_y - m > imageHeight - 1 )
00202 yy = imageHeight - 1;
00203 else
00204 yy = y_y - m;
00205 yValue += tempImage[yy][x_y] * kernel[m + maskradius];
00206 }
00207 oImg[y_y][x_y] = (T) yValue;
00208 }
00209 }
00210 }
00211
00212 }
00213
00214 #endif