Go to the documentation of this file.00001 #include "bsta_gauss.h"
00002
00003
00004 #include <vcl_cmath.h>
00005
00006 double bsta_gauss::bsta_gaussian(const double x, const double sigma)
00007 {
00008 double x_on_sigma = x / sigma;
00009 return (double)vcl_exp(- x_on_sigma * x_on_sigma / 2);
00010 }
00011
00012
00013 void bsta_gauss::bsta_1d_gaussian_kernel(const double sigma,
00014 const double fuzz,
00015 int& radius,
00016 vcl_vector<double>& kernel)
00017 {
00018 for (radius = 0; bsta_gaussian(double(radius), sigma) > fuzz; radius++)
00019 {;}
00020
00021 kernel.resize(2*radius + 1);
00022 if (!radius)
00023 {
00024 kernel[0]=1;
00025 return;
00026 }
00027 for (int i=0; i<=radius; ++i)
00028 kernel[radius+i] = kernel[radius-i] = bsta_gaussian(double(i), sigma);
00029 double sum = 0;
00030 for (int i= 0; i <= 2*radius; ++i)
00031 sum += kernel[i];
00032 for (int i= 0; i <= 2*radius; ++i)
00033 kernel[i] /= sum;
00034 }
00035
00036
00037
00038
00039
00040 void bsta_gauss::bsta_1d_gaussian(const double sigma,
00041 vcl_vector<double> const& in_buf,
00042 vcl_vector<double>& out_buf)
00043 {
00044 int n = in_buf.size(), r = 0;
00045 if (!n)
00046 return;
00047 out_buf.resize(n);
00048 if (n==1)
00049 {
00050 out_buf[0]=in_buf[0];
00051 return;
00052 }
00053
00054 vcl_vector<double> ker;
00055 bsta_1d_gaussian_kernel(sigma, 0.02, r, ker);
00056 for (int i = 0; i<n; i++)
00057 {
00058 double sum = 0;
00059
00060
00061 if (i>r&&((n-1)-i>=r))
00062 {
00063 for (int k = -r; k<=r; k++)
00064 sum += ker[k+r]*in_buf[i+k];
00065 out_buf[i]=sum;
00066 continue;
00067 }
00068
00069
00070 int r_minus = i;
00071 if (r_minus>r)
00072 r_minus=r;
00073 int r_plus = (n-1)-i;
00074 if (r_plus>r)
00075 r_plus=r;
00076 double ker_sum =0;
00077 for (int k = -r_minus; k<=r_plus; k++)
00078 {
00079 ker_sum += ker[k+r];
00080 sum += ker[k+r]*in_buf[i+k];
00081 }
00082 out_buf[i]=sum/ker_sum;
00083 }
00084 }
00085
00086
00087
00088 void bsta_gauss::bsta_2d_gaussian(const double sigma,
00089 vbl_array_2d<double> const& in_buf,
00090 vbl_array_2d<double>& out_buf)
00091 {
00092 int n = in_buf.cols(), m = in_buf.rows();
00093 out_buf.resize(m, n);
00094
00095
00096 for (int row = 0; row<m; row++)
00097 {
00098 vcl_vector<double> row_buf(n), temp;
00099 for (int col = 0; col<n; col++)
00100 row_buf[col]=in_buf[row][col];
00101 bsta_1d_gaussian(sigma, row_buf, temp);
00102 for (int col = 0; col<n; col++)
00103 out_buf[row][col]=temp[col];
00104 }
00105
00106 for (int col = 0; col<n; col++)
00107 {
00108 vcl_vector<double> col_buf(m), temp;
00109 for (int row = 0; row<m; row++)
00110 col_buf[row]=out_buf[row][col];
00111 bsta_1d_gaussian(sigma, col_buf, temp);
00112 for (int row = 0; row<m; row++)
00113 out_buf[row][col]=temp[row];
00114 }
00115 }
00116 void bsta_gauss::bsta_3d_gaussian(const double sigma,
00117 vbl_array_3d<double> const& in_buf,
00118 vbl_array_3d<double>& out_buf)
00119 {
00120 int ni = in_buf.get_row1_count(),
00121 nj = in_buf.get_row2_count(), nk = in_buf.get_row3_count();
00122 out_buf.resize(ni, nj, nk);
00123
00124 for (int j = 0; j<nj; j++)
00125 for (int k = 0; k<nk; k++)
00126 {
00127 vcl_vector<double> ibuf(ni), temp;
00128 for (int i = 0; i<ni; i++)
00129 ibuf[i]=in_buf[i][j][k];
00130 bsta_1d_gaussian(sigma, ibuf, temp);
00131 for (int i = 0; i<ni; i++)
00132 out_buf[i][j][k]=temp[i];
00133 }
00134
00135 for (int i = 0; i<ni; i++)
00136 for (int k = 0; k<nk; k++)
00137 {
00138 vcl_vector<double> jbuf(nj), temp;
00139 for (int j = 0; j<nj; j++)
00140 jbuf[j]=in_buf[i][j][k];
00141 bsta_1d_gaussian(sigma, jbuf, temp);
00142 for (int j = 0; j<nj; j++)
00143 out_buf[i][j][k]=temp[j];
00144 }
00145
00146 for (int i = 0; i<ni; i++)
00147 for (int j = 0; j<nj; j++)
00148 {
00149 vcl_vector<double> kbuf(nk), temp;
00150 for (int k = 0; k<nk; k++)
00151 kbuf[k]=in_buf[i][j][k];
00152 bsta_1d_gaussian(sigma, kbuf, temp);
00153 for (int k = 0; k<nk; k++)
00154 out_buf[i][j][k]=temp[k];
00155 }
00156 }