iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MakeImagePyramidImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Randolph Voorhies
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 // ######################################################################
37 template <NRT_PROMOTE_PIX_NO_DEFAULT>
39 nrt::gaussianPyramid(nrt::Image<PixType> const source, size_t const numOctaves,
40  size_t const firstOctave, size_t const filterSize)
41 {
42  nrt::ImagePyramid<DestType> pyramid(numOctaves, 1);
43 
44  nrt::Image<DestType> currLayer = nrt::Image<DestType>(source);
45 
46  pyramid.octave(0).layer(0) = currLayer;
47  for(size_t octaveIdx = 1; octaveIdx < numOctaves; ++octaveIdx)
48  {
49  if (filterSize == 5)
50  currLayer = nrt::lowPass5yDecY<promo>(nrt::lowPass5xDecX<promo>(currLayer,2),2);
51  else
52  currLayer = nrt::decimateY<promo>(nrt::lowPassY<promo>(filterSize,
53  nrt::decimateX<promo>(nrt::lowPassX<promo>(filterSize, currLayer))));
54 
55  pyramid.octave(octaveIdx).layer(0) = currLayer;
56  }
57 
58  if(firstOctave != 0)
59  for(size_t i=0; i<firstOctave; ++i)
60  pyramid.octave(i).layer(0) = Image<DestType>();
61 
62  return pyramid;
63 }
64 
65 // ######################################################################
66 template <NRT_PROMOTE_PIX_NO_DEFAULT>
68 nrt::laplacianPyramid(nrt::Image<PixType> const source, size_t const numOctaves,
69  size_t const firstOctave, size_t const filterSize)
70 {
71  nrt::ImagePyramid<DestType> pyramid(numOctaves, 1);
72 
73  nrt::Image<DestType> dec(source);
74  nrt::Image<DestType> lpf = nrt::lowPass<promo>(filterSize, source);
75 
76  for (size_t octaveIdx = 0; octaveIdx < numOctaves; ++octaveIdx)
77  {
78  pyramid.octave(octaveIdx).layer(0) = dec - lpf;
79 
80  dec = nrt::decimateXY<void>(lpf);
81  lpf = nrt::lowPass<void>(filterSize, dec);
82  }
83 
84  if(firstOctave != 0)
85  for(size_t i=0; i<firstOctave; ++i)
86  pyramid.octave(i).layer(0) = Image<DestType>();
87 
88  return pyramid;
89 }
90 
91 // ######################################################################
92 template <NRT_PROMOTE_PIX_NO_DEFAULT>
94 nrt::orientedPyramid(nrt::Image<PixType> const source, size_t const numOctaves, size_t const firstOctave,
95  int const filterSize, float theta, float intensity, bool const fastMath)
96 {
97  nrt::ImagePyramid<DestType> laplacian = laplacianPyramid<promo>(source, numOctaves, firstOctave, filterSize);
98  return orientedPyramid<promo>(laplacian, filterSize, theta, intensity, fastMath);
99 }
100 
101 
102 // ######################################################################
103 template <NRT_PROMOTE_PIX_NO_DEFAULT>
105 nrt::orientedPyramid(ImagePyramid<PixType> const laplacian, int filterSize, float theta,
106  float intensity, bool const fastMath)
107 {
108  int attenuation_width = -1;
109  float spatial_freq = -1.0;
110 
111  switch (filterSize)
112  {
113  case 5: attenuation_width = 3; spatial_freq = M_PI_2; break;
114  case 9: attenuation_width = 5; spatial_freq = 2.6; break;
115  default: NRT_FATAL("Filter size " << filterSize << " is not supported");
116  }
117 
118  ImagePyramid<DestType> pyramid(laplacian.numOctaves(), 1);
119 
120  for(size_t octaveIdx = 0; octaveIdx < laplacian.numOctaves(); ++octaveIdx)
121  {
122  if(laplacian.octave(octaveIdx).layer(0).size() > 0)
123  {
124  pyramid.octave(octaveIdx).layer(0) =
125  nrt::Image<DestType>( orientedFilter( laplacian.octave(octaveIdx).layer(0), spatial_freq,
126  theta, intensity, fastMath ) );
127 
128  //attenuate borders that are overestimated due to filter truncation:
129  inplaceAttenuateBorders(pyramid.octave(octaveIdx).layer(0), attenuation_width);
130  }
131  }
132 
133  return pyramid;
134 }
135 
136 template<class PixType>
137 nrt::PyramidReichardt<PixType>::PyramidReichardt(size_t const depth, size_t const firstLevel,
138  float dx, float dy, float filterSize) :
139  itsDepth(depth),
140  itsFirstLevel(firstLevel),
141  itsDx(dx),
142  itsDy(dy),
143  itsFilterSize(filterSize)
144 { }
145 
146 template<class PixType>
149 {
150  // create a pyramid with the input image
151  nrt::ImagePyramid<PixType> upyr = nrt::gaussianPyramid<void>(source, itsDepth, itsFirstLevel, itsFilterSize);
152 
153  //create an empty pyramid
154  nrt::ImagePyramid<PixType> spyr(itsDepth, 1);
155 
156  //fill the empty pyramid with the shifted version
157  for(size_t i = itsFirstLevel; i < itsDepth; ++i)
158  spyr.octave(i).layer(0) = shiftImage<void>(upyr.octave(i).layer(0), itsDx, itsDy);
159 
160  // store both pyramids in the deques
161  unshifted.push_back(upyr);
162  shifted.push_back(spyr);
163 
164  // so, it's our first time? Pretend the pyramid before this was
165  // the same as the current one ...
166  if (unshifted.size() == 1)
167  {
168  unshifted.push_back(upyr);
169  shifted.push_back(spyr);
170  }
171 
172  // need to pop off old pyramid?
173  if (unshifted.size() == 3)
174  {
175  unshifted.pop_front();
176  shifted.pop_front();
177  }
178 
179  nrt::ImagePyramid<PixType> result(itsDepth, 1);
180 
181  // compute the Reichardt maps
182  for (size_t i = itsFirstLevel; i < itsDepth; ++i)
183  {
184  result.octave(i).layer(0) =
185  (unshifted.back().octave(i).layer(0) * shifted.front().octave(i).layer(0)) -
186  (unshifted.front().octave(i).layer(0) * shifted.back().octave(i).layer(0));
187  }
188 
189  return result;
190 }
191 
192 
193 
194 //// ######################################################################
195 //template <NRT_PROMOTE_PIX_NO_DEFAULT>
196 //nrt::ImagePyramid<DestType> SIFTPyramid(nrt::Image<PixType> const source, size_t const numberOctaves, size_t const layersPerOctave, float const sigma)
197 //{
198 // // assert(octScale > 0.0F);
199 // const float k = powf(2.0F, 1.0F /s);
200 // std::vector<typename ImagePyramidNEW<DestType>::Octave> octaves;
201 // std::vector<nrt::Image<DestType> > layers(s+3);
202 // nrt::ImagePyramid<DestType> pyramid(numberOctaves, layersPerOctave);
203 // // our bottom image is just the original. We here assume that the caller has pre-blurred it if necessary.
204 // pyramid.octaves(0).layers(0) = source;
205 // // compute the additional gaussian blurred maps:
206 // for (size_t ss = 1; ss < layersPerOctave+3; ++ss)
207 // {
208 // // compute the stdev of a Gaussian we should convolve the previous blurred image by, so as to multiply the total
209 // // effective blurring sigma by a factor k:
210 // float const std = sigma * powf(k, float(ss-1)) * sqrt(k*k - 1.0F);
211 // // get a Gaussian kernel by that stdev, normalized to unit sum:
212 // nrt::Image<DestType> kernelx = gaussian<nrt::PixGray<float> >(1.0F, std, source.width(), 1.0F);
213 // nrt::Image<DestType> kernely = kernelx;
214 // kernely.reshape(nrt::Dims<nrt::int32>(kernelx.height(), kernelx.width()));
215 // DestType sumK = std::accumulate(kernelx.const_begin(), kernelx.const_end(), DestType(0.0F));
216 // std::transform(kernelx.const_begin(), kernelx.const_end(), kernelx.begin(),
217 // [=sumK](DestType const & p) {return p/sumK;});
218 // std::transform(kernely.const_begin(), kernely.const_end(), kernely.begin(),
219 // [=sumK](DestType const & p) {return p/sumK;});
220 // // do the convolution:
221 // layers[ss] = sepFilter<promo>(layers[ss-1], kernelx, kernely, nrt::ConvolutionBoundaryStrategy::CLEAN);
222 // }
223 // typename ImagePyramidNEW<DestType>::Octave someOctave(layers);
224 // octaves.push_back(someOctave);
225 // ImagePyramidNEW<DestType> thePyramid(octaves);
226 // return thePyramid;
227 //}
228 
229