Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
GradientGauss.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "GradientGauss.hh"
27 #include "Convolution.hh"
28 
29 using namespace BIAS;
30 using namespace std;
31 
32 //////////////////////////////////////////////////////////////////////////
33 // implementation
34 //////////////////////////////////////////////////////////////////////////
35 
36 template <class StorageType, class OutputStorageType>
39 {
40  _LastSigma=-DBL_MAX;
41  _GradGaussSigma=1.0;
42  _GradGaussRatio=0.01;
43 }
44 
45 template <class StorageType, class OutputStorageType>
48  : _GradGaussSigma(other._GradGaussSigma),
49  _GradGaussRatio(other._GradGaussRatio),
50  _LastSigma(other._LastSigma),
51  _LastRatio(other._LastRatio),
52  _Conv(other._Conv)
53 {
54 }
55 
56 template <class InputStorageType, class OutputStorageType>
58 }
59 
60 template <class InputStorageType, class OutputStorageType>
63 {
64  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientGauss::Filter(src, dst)\n");
65 
67  int res = Filter(src, grad, gy);
68  grad.AppendChannel(gy);
69  return res;
70 }
71 
72 template <class InputStorageType, class OutputStorageType>
76 {
77  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientGauss::Filter(src, gx, gy)\n");
78  // SetDebugLevel(D_GRADGAUSS_KERNEL);
79  //cout <<"GradientGauss values are "<< *_GradGaussSigma<< " "<<
80  // *_GradGaussRatio<<endl;
81  if ((fabs(_GradGaussSigma-_LastSigma)>=DBL_EPSILON) ||
82  (fabs(_GradGaussRatio-_LastRatio)>=DBL_EPSILON)){
83  _CalculateKernels(_GradGaussSigma, _GradGaussRatio);
84  }
85  if (!gx.SamePixelAndChannelCount(src)){
86  gx.Release();
87  gx.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
88  }
89  if (!gy.SamePixelAndChannelCount(src)){
90  gy.Release();
91  gy.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
92  }
93 
94  if (_Conv.Filter(src, gx)!=0) {
95  BIASERR("Error in gradient x computation...");
96  return -1;
97  }
98  FilterMask f;
99  _Conv.GetKernel(f);
100  f.Transpose();
101  _Conv.SetKernel(f);
102  int res = _Conv.Filter(src, gy);
103  f.Transpose();
104  _Conv.SetKernel(f);
105  return res;
106 }
107 
108 template <class InputStorageType, class OutputStorageType>
112 {
113  BIASCDOUT(D_FILTERBASE_CALLSTACK, "GradientGauss::Filter(src, gx, gy, absg)\n");
114 
115  if (!src.SamePixelAndChannelCount(absg)){
116  if (!absg.IsEmpty()) absg.Release();
117  absg.Init(src.GetWidth(), src.GetHeight(), src.GetChannelCount());
118  }
119  int res = Filter(src,gx,gy);
120  int absres = this->VecLen(gx, gy, absg);
121  return (res==0 && absres ==0)?0:-1;
122 }
123 
124 template <class InputStorageType, class OutputStorageType>
126 _CalculateKernels(double Sigma, double Ratio)
127 {
128  const int hws=(int)(floor(sqrt(-2.0*Sigma*Sigma*log(Ratio))));
129  const int size=(hws<<1)+1;
130  Vector<FM_FLOAT> H(size), V(size);
131 
132  BIASCDOUT(D_GRADGAUSS_KERNEL, "Sigma = "<<Sigma<<"\tRatio = "<<Ratio<<endl);
133  BIASCDOUT(D_GRADGAUSS_KERNEL, "size = "<<size<<"\thws = "<<hws<<endl);
134 
135  int i, ip, im;
136  double fac=1.0/(2.0*Sigma*Sigma);
137  register double g;
138  double sum=0.0, dsum=0.0;
139  // calculate the filter coefficients as gauss function
140  // this is a filtermask in the sense of convolution
141  // it is reflected at its symmetry center before being "dropped"
142  // onto the image !
143  for (i=0; i<=hws; i++){
144  ip=hws+i;
145  im=hws-i;
146  g=expf((float)(-(double)(i*i)*fac));
147  V[ip] = V[im] = (FM_FLOAT) g;
148  BIASCDOUT(D_GRADGAUSS_KERNEL, i<<" v:"<<V[im]<<" "<<endl);
149  sum += g*2.0;
150  // why, it is now not a symmetric filter??
151  g = double(i)*g;
152  H[im] = (FM_FLOAT) g;
153  H[ip] = (FM_FLOAT) -g;
154  dsum+=fabs(2.0*double(i)*g);
155  BIASCDOUT(D_GRADGAUSS_KERNEL, i<<" h:"<< H[im]<<" "<<endl);
156  }
157  // added double, sub one here for consistency
158  sum -= H[hws];
159  BIASCDOUT(D_GRADGAUSS_KERNEL, "sum = "<<sum<<"\tdsum = "<<dsum<<endl);
160 
161  // normalize filter, so that the sum is 1.0
162  sum = 1.0 / sum;
163  dsum = 1.0 / dsum;
164  BIASCDOUT(D_GRADGAUSS_KERNEL, "sum = "<<sum<<"\tdsum = "<<dsum<<endl);
165  for (i=0; i<=hws; i++){
166  ip = hws+i;
167  im = hws-i;
168  H[ip] *= (FM_FLOAT)dsum;
169  H[im] *= (FM_FLOAT)dsum;
170  V[ip] = V[im] = V[im]*(FM_FLOAT)sum;
171  BIASCDOUT(D_GRADGAUSS_KERNEL, "h:"<< H[im]<<" "<<endl);
172  //BIASCDOUT(D_GRADGAUSS_KERNEL, "v:"<<_VVec[im]<<" "<<endl);
173  }
174  FilterMask F(H,V);
175  int thebits = F.ComputeIntPrecisionBits(sizeof(InputStorageType)*8,
176  sizeof(CONV_INT)*8-1);
177  F.CreateIntFilter(thebits,thebits,thebits);
178 
179  _Conv.SetKernel(F);
180  _LastSigma = Sigma;
181  _LastRatio = Ratio;
182 
183 
184 #ifdef BIAS_DEBUG
185  sum=dsum=0.0;
186  for (i=-hws; i<=hws; i++){
187  sum += H[i+hws];
188  BIASCDOUT(D_GRADGAUSS_KERNEL, H[i+hws]<<" ");
189  }
190  BIASCDOUT(D_GRADGAUSS_KERNEL, " sum = "<<sum<<endl);
191  for (i=-hws; i<=hws; i++){
192  dsum += V[i+hws];
193  BIASCDOUT(D_GRADGAUSS_KERNEL, V[i+hws]<<" ");
194  }
195  BIASCDOUT(D_GRADGAUSS_KERNEL, " sum = "<<dsum<<endl);
196 #endif
197 
198 
199 }
200 
201 template <class InputStorageType, class OutputStorageType>
203 GetBordersValid_(int &border_x, int &border_y) const
204 {
205  _Conv.GetBorders(border_x, border_y);
206 }
207 
208 //////////////////////////////////////////////////////////////////////////
209 // instantiation
210 //////////////////////////////////////////////////////////////////////////
211 
212 namespace BIAS{
213 #define FILTER_INSTANTIATION_CLASS GradientGauss
214 #define FILTER_INSTANTIATION_NO_UNSIGNED_OUTPUT
215 #include "Filterinst.hh"
216 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
gradient calculation with separated gauss masks
void CreateIntFilter(int rshift, int rshifth, int rshiftv)
create the int filter from the float filter
Definition: FilterMask.cpp:113
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void Transpose()
transposes the kernel (and adapts all dependent data)
Definition: FilterMask.cpp:197
int AppendChannel(Image< StorageType > &img)
Definition: Image.cpp:1457
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void _CalculateKernels(double Sigma, double Ratio)
Fills _HVec with gaussian function and _VVec with derivative of gaussian function with standard devia...
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &grad)
returns a 2 channel image containig gx and gy
unsigned int GetHeight() const
Definition: ImageBase.hh:319
virtual void GetBordersValid_(int &border_x, int &border_y) const
int ComputeIntPrecisionBits(int NumberOfBitsInInputData, int NumberOfBitsInTempData)
compute the number of shiftable bits for int-from-float mask
Definition: FilterMask.cpp:211
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
A filter mask (or a kernel) used for convolution.
Definition: FilterMask.hh:61