A.I.M.S algorithms


filteringimagealgorithm.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef AIMSALGO_SIGNALFILTER_FILTERINGIMAGEALGORITHM_H
35 #define AIMSALGO_SIGNALFILTER_FILTERINGIMAGEALGORITHM_H
36 
37 //--- aims -------------------------------------------------------------------
39 #include <aims/data/data.h>
40 #include <aims/utility/progress.h>
42 //--- cartodata --------------------------------------------------------------
44 //--- cartobase --------------------------------------------------------------
46 #include <cartobase/type/types.h>
50 //--- std --------------------------------------------------------------------
51 #include <iostream>
52 #include <assert.h>
53 //----------------------------------------------------------------------------
54 
55 namespace aims {
56  template <typename T> class FilteringImageAlgorithmInterface;
57  template <typename T> class LinearFilteringImageAlgorithm;
58  template <typename T> class LinearFilteringFunction;
59  template <typename T> class ElementFilteringImageAlgorithm;
60  template <typename T> class ElementFilteringFunction;
61  namespace singlechannel {
62  template <typename T> class LinearFilteringImageAlgorithm;
63  template <typename T> class ElementFilteringImageAlgorithm;
64  }
65 
66  //==========================================================================
67  // LINEAR FILTERING IMAGE ALGORITHM: MULTI CHANNELS
68  //==========================================================================
69  template <typename T>
71  {
72  public:
73  //----------------------------------------------------------------------
74  // typedef
75  //----------------------------------------------------------------------
76  typedef T VoxelType;
79 
80  //----------------------------------------------------------------------
81  // image algorithm interface: implementation
82  //----------------------------------------------------------------------
83  virtual void setOptions( const carto::Object & options )
84  {
85  _lalgo->setOptions( options );
86  }
87 
88  virtual void updateOptions( const carto::Object & options )
89  {
90  _lalgo->updateOptions( options );
91  }
92 
94  {
95  return new LinearFilteringImageAlgorithm<T>(*this);
96  }
97 
98  //----------------------------------------------------------------------
99  // constructor (default+copy) & destructor
100  //----------------------------------------------------------------------
101  protected:
104  ImageAlgorithm<T>(),
106  {
108  }
110  ImageAlgorithm<T>(),
111  _lalgo( other._lalgo->clone() )
112  {
114  }
116  {
117  _lalgo = other._lalgo->clone();
119  return *this;
120  }
121  public:
123 
124  //----------------------------------------------------------------------
125  // member
126  //----------------------------------------------------------------------
127  protected:
129 
130  };
131 
132  //==========================================================================
133  // ELEMENT FILTERING IMAGE ALGORITHM: MULTI CHANNELS
134  //==========================================================================
135  template <typename T>
137  {
138  public:
139  //----------------------------------------------------------------------
140  // typedef
141  //----------------------------------------------------------------------
142  typedef T VoxelType;
145 
146  //----------------------------------------------------------------------
147  // image algorithm interface: implementation
148  //----------------------------------------------------------------------
149  virtual void setOptions( const carto::Object & options )
150  {
151  _ealgo->setOptions( options );
152  }
153 
154  virtual void updateOptions( const carto::Object & options )
155  {
156  _ealgo->updateOptions( options );
157  }
158 
160  return new ElementFilteringImageAlgorithm<T>(*this);
161  }
162 
163  //----------------------------------------------------------------------
164  // member method
165  //----------------------------------------------------------------------
166  virtual void setStructuringElement( const StructuringElement & se )
167  {
169  }
170 
171  //----------------------------------------------------------------------
172  // constructor (default+copy) & destructor
173  //----------------------------------------------------------------------
174  protected:
177  const StructuringElement & se = strel::Cube(1.)
178  ):
179  ImageAlgorithm<T>(),
181  {
183  }
185  ImageAlgorithm<T>(),
186  _ealgo(other._ealgo->clone())
187  {
189  }
191  {
192  _ealgo = other._ealgo->clone();
194  return *this;
195  }
196  public:
198 
199  //----------------------------------------------------------------------
200  // member
201  //----------------------------------------------------------------------
202  protected:
204  };
205 
206  namespace singlechannel {
207 
208  //========================================================================
209  // LINEAR FILTERING IMAGE ALGORITHM: SINGLE CHANNEL
210  //========================================================================
211  template <typename T>
213  {
214  public:
215  //--------------------------------------------------------------------
216  // image algorithm interface: implementation
217  //--------------------------------------------------------------------
218  virtual void execute( const carto::VolumeRef<T> & in,
219  carto::VolumeRef<T> & out ) const;
220 
221  virtual void setOptions( const carto::Object & options )
222  {
223  _func->setOptions( options );
224  }
225 
226  virtual void updateOptions( const carto::Object & options )
227  {
228  _func->updateOptions( options );
229  }
230 
231  virtual ::aims::singlechannel::LinearFilteringImageAlgorithm<T> * clone() const {
232  return new ::aims::singlechannel::LinearFilteringImageAlgorithm<T>(*this);
233  }
234 
235  //--------------------------------------------------------------------
236  // constructor (default+copy) & destructor
237  //--------------------------------------------------------------------
238  protected:
240 
241  public:
243  _func(f.clone())
244  {}
245 
246  LinearFilteringImageAlgorithm( const ::aims::singlechannel::LinearFilteringImageAlgorithm<T> & other ):
247  _func(other._func->clone())
248  {}
249 
251  const LinearFilteringImageAlgorithm & other )
252  {
253  assert( typeid(other) == typeid(*this) );
254  if( this != &other )
255  _func.reset( other._func->clone() );
256  return *this;
257  }
258 
260 
261  //--------------------------------------------------------------------
262  // member
263  //--------------------------------------------------------------------
264  protected:
266  };
267 
268  template <typename T>
269  inline
271  const carto::VolumeRef<T> & in,
272  carto::VolumeRef<T> & out ) const
273  {
274  int sx, sy, sz, ex, ey, ez, x, y, z, t;
275  typename carto::Volume<T>::Position4Di pos(0,0,0,0), size(1,1,1,1);
276 
277  // set voxel size
279  std::vector<float> vs(4, 1.);
280  in.header().getProperty( "voxel_size", vs );
281  options->setProperty( "voxel_size", vs );
282  _func->updateOptions( options );
283 
284  // Manage borders / structuring element size
285  const std::vector<int> & border = in->getBorders();
286  const std::vector<int> & amplitude = _func->getAmplitude();
287 
288  // When volume has borders, it is possible to use it to process filtering
289  sz = (amplitude[4] < border[4]) ? 0 : amplitude[4] - border[4];
290  sy = (amplitude[2] < border[2]) ? 0 : amplitude[2] - border[2];
291  sx = (amplitude[0] < border[0]) ? 0 : amplitude[0] - border[0];
292  ez = (amplitude[5] < border[5]) ? in->getSizeZ() : in->getSizeZ() - amplitude[5] + border[5];
293  ey = (amplitude[3] < border[3]) ? in->getSizeY() : in->getSizeY() - amplitude[3] + border[3];
294  ex = (amplitude[1] < border[1]) ? in->getSizeX() : in->getSizeX() - amplitude[1] + border[1];
295 
297  std::cout << "Filter amplitude (voxels): [ ";
298  for(int i = 0; i < 6; ++i)
299  std::cout << carto::toString(amplitude[i]) << ( i==5 ? " " : ", ");
300  std::cout << "]" << std::endl;
301  std::cout << "Processing with borders (voxels): [ ";
302  for(int i = 0; i < 8; ++i)
303  std::cout << carto::toString(border[i]) << ( i==7 ? " " : ", ");
304  std::cout << "]" << std::endl;
305  std::cout << "Start: [" << carto::toString(sx) << ", "
306  << carto::toString(sy) << ", "
307  << carto::toString(sz) << "]" << std::endl;
308  std::cout << "End: [" << carto::toString(ex) << ", "
309  << carto::toString(ey) << ", "
310  << carto::toString(ez) << "]" << std::endl;
311  }
312 
313  size[0] = amplitude[0] + amplitude[1] + 1;
314  size[1] = amplitude[2] + amplitude[3] + 1;
315  size[2] = amplitude[4] + amplitude[5] + 1;
316  carto::VolumeRef<T> win( new carto::Volume<T>( in, pos, size ) );
317 
318  aims::Progression progress( out->getSizeT() * (ez - sz) * (ey - sy) - 1 );
320  std::cout << "Filtering progress: ";
321 
322  for( t = 0; t < in->getSizeT(); ++t )
323  for( z = sz; z < ez; ++z )
324  for( y = sy; y < ey; ++y, ++progress ) {
326  // Display progression
327  // The "normal" operator << should be as:
328  // std::cout << progress << std::flush;
329  // but it doesn't work in gcc 4.0, there is a namespace
330  // confusion, so we have to specify ::operator <<
331  ::operator << ( std::cout, progress ) << std::flush;
332  }
333  for( x = sx; x < ex; ++x )
334  {
335  // Set view position in the volume
336  pos[0] = x - amplitude[0];
337  pos[1] = y - amplitude[2];
338  pos[2] = z - amplitude[4];
339  pos[3] = t;
340  win->setPosInRefVolume( pos );
341  (*out)( x, y, z, t ) = _func->execute( win );
342  }
343  }
344 
346  std::cout << std::endl;
347  }
348 
349 
350  //========================================================================
351  // ELEMENT FILTERING IMAGE ALGORITHM: SINGLE CHANNEL
352  //========================================================================
353  template <typename T>
355  {
356  public:
357  //--------------------------------------------------------------------
358  // image algorithm interface: implementation
359  //--------------------------------------------------------------------
360  virtual void execute( const carto::VolumeRef<T> & in,
361  carto::VolumeRef<T> & out ) const;
362 
363  virtual void setOptions( const carto::Object & options )
364  {
365  _func->setOptions( options );
366  }
367 
368  virtual void updateOptions( const carto::Object & options )
369  {
370  _func->updateOptions( options );
371  }
372 
373  virtual ::aims::singlechannel::ElementFilteringImageAlgorithm<T> * clone() const {
374  return new ::aims::singlechannel::ElementFilteringImageAlgorithm<T>(*this);
375  }
376 
377  //--------------------------------------------------------------------
378  // member method
379  //--------------------------------------------------------------------
380  virtual void setStructuringElement( const StructuringElement & se )
381  {
382  _strel.reset( se.clone() );
383  }
384 
385  //--------------------------------------------------------------------
386  // constructor (default+copy) & destructor
387  //--------------------------------------------------------------------
388  protected:
390 
391  public:
393  const StructuringElement & se = strel::Cube(1.) ):
394  _func(f.clone()),
395  _strel(se.clone())
396  {}
397 
398  ElementFilteringImageAlgorithm( const ::aims::singlechannel::ElementFilteringImageAlgorithm<T> & other ):
399  _func(other._func->clone()),
400  _strel(other._strel->clone())
401  {}
402 
404  const ::aims::singlechannel::ElementFilteringImageAlgorithm<T> & other )
405  {
406  assert( typeid(other) == typeid(*this) );
407  if( *this != other )
408  {
409  _func.reset( other._func->clone() );
410  _strel.reset( other._strel->clone() );
411  }
412  return *this;
413  }
414 
416 
417  //--------------------------------------------------------------------
418  // members
419  //--------------------------------------------------------------------
420  protected:
423  };
424 
425  template <typename T>
426  inline
428  const carto::VolumeRef<T> & in,
429  carto::VolumeRef<T> & out
430  ) const
431  {
432  int sx, sy, sz, ex, ey, ez, x, y, z, t;
433  typename carto::Volume<T>::Position4Di pos(0,0,0), size(1,1,1);
434 
435  // Manage borders / structuring element size
436  const std::vector<int> & border = in->getBorders();
437  const std::vector<int> amplitude = _strel->getAmplitude();
438 
439  // When volume has borders, it is possible to use it to process filtering
440  sz = (amplitude[4] < border[4]) ? 0 : amplitude[4] - border[4];
441  sy = (amplitude[2] < border[2]) ? 0 : amplitude[2] - border[2];
442  sx = (amplitude[0] < border[0]) ? 0 : amplitude[0] - border[0];
443  ez = (amplitude[5] < border[5]) ? in->getSizeZ() : in->getSizeZ() - amplitude[5] + border[5];
444  ey = (amplitude[3] < border[3]) ? in->getSizeY() : in->getSizeY() - amplitude[3] + border[3];
445  ex = (amplitude[1] < border[1]) ? in->getSizeX() : in->getSizeX() - amplitude[1] + border[1];
446 
448  std::cout << "Filter amplitude (voxels): [ ";
449  for(int i = 0; i < 6; ++i)
450  std::cout << carto::toString(amplitude[i]) << ( i==8 ? " " : ", ");
451  std::cout << "]" << std::endl;
452  std::cout << "Processing with borders (voxels): [ ";
453  for(int i = 0; i < 8; ++i)
454  std::cout << carto::toString(border[i]) << ( i==8 ? " " : ", ");
455  std::cout << "]" << std::endl;
456  std::cout << "Start: [" << carto::toString(sx) << ", "
457  << carto::toString(sy) << ", "
458  << carto::toString(sz) << "]" << std::endl;
459  std::cout << "End: [" << carto::toString(ex) << ", "
460  << carto::toString(ey) << ", "
461  << carto::toString(ez) << "]" << std::endl;
462  }
463 
464  carto::VolumeRef<T> win( new carto::Volume<T>( in, pos, size ) );
465 
466  aims::Progression progress( out->getSizeT() * (ez - sz) * (ey - sy) - 1 );
468  std::cout << "Filtering progress: ";
469 
470  for( t = 0; t < in->getSizeT(); ++t )
471  for( z = sz; z < ez; ++z )
472  for( y = sy; y < ey; ++y, ++progress ) {
474  // Display progression
475  // The "normal" operator << should be as:
476  // std::cout << progress << std::flush;
477  // but it doesn't work in gcc 4.0, there is a namespace
478  // confusion, so we have to specify ::operator <<
479  ::operator << ( std::cout, progress ) << std::flush;
480  }
481  for( x = sx; x < ex; ++x )
482  {
483  // Set view position in the volume
484  pos[0] = x;
485  pos[1] = y;
486  pos[2] = z;
487  pos[3] = t;
488  win->setPosInRefVolume( pos );
489  (*out)( x, y, z, t ) = _func->execute( win, _strel );
490  }
491  }
492 
494  std::cout << std::endl;
495  }
496 
497  } // namespace singlechannel
498 
499 } // namespace aims
500 
501 #endif
int getSizeY() const
LinearFilteringImageAlgorithm(const LinearFilteringFunction< T > &f)
virtual void updateOptions(const carto::Object &options)
LinearFilteringImageAlgorithm & operator=(LinearFilteringImageAlgorithm &other)
SingleChannelImageAlgorithmType * _ealgo
virtual void execute(const carto::VolumeRef< T > &in, carto::VolumeRef< T > &out) const
ImageAlgorithmInterface Pure virtual method.
virtual ::aims::singlechannel::LinearFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface Pure virtual method.
virtual void setStructuringElement(const StructuringElement &se)
virtual void updateOptions(const carto::Object &options)
SingleChannelImageAlgorithmType * _lalgo
int getSizeZ() const
singlechannel::ElementFilteringImageAlgorithm< ChannelType > SingleChannelImageAlgorithmType
singlechannel::LinearFilteringImageAlgorithm< ChannelType > SingleChannelImageAlgorithmType
Base class for filtering functions applied in a structuring element.
virtual StructuringElement * clone() const
virtual ::aims::singlechannel::ElementFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface Pure virtual method.
int getSizeT() const
virtual void setOptions(const carto::Object &options)
carto::rc_ptr< LinearFilteringFunction< T > > _func
virtual void updateOptions(const carto::Object &options)
LinearFilteringImageAlgorithm(const LinearFilteringFunction< ChannelType > &f)
virtual void setStructuringElement(const StructuringElement &se)
void setPosInRefVolume(const Position4Di &pos)
ElementFilteringImageAlgorithm & operator=(ElementFilteringImageAlgorithm &other)
carto::DataTypeTraits< T >::ChannelType ChannelType
aims::ImageAlgorithm class used to implement image algorithms
virtual void setOptions(const carto::Object &options)
LinearFilteringImageAlgorithm & operator=(const LinearFilteringImageAlgorithm &other)
LinearFilteringImageAlgorithm(const LinearFilteringImageAlgorithm< T > &other)
virtual void setProperty(const std::string &key, Object value)=0
ElementFilteringImageAlgorithm(const ElementFilteringImageAlgorithm< T > &other)
static Object value()
virtual ElementFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface Pure virtual method.
carto::rc_ptr< ElementFilteringFunction< T > > _func
aims::ImageAlgorithmInterface is the interface for an image processing algorithm. ...
Base class for linear filtering functions.
virtual void setOptions(const carto::Object &options)
int getSizeX() const
const PropertySet & header() const
LinearFilteringImageAlgorithm(const ::aims::singlechannel::LinearFilteringImageAlgorithm< T > &other)
ElementFilteringImageAlgorithm(const ::aims::singlechannel::ElementFilteringImageAlgorithm< T > &other)
std::string toString(const T &object)
carto::DataTypeTraits< T >::ChannelType ChannelType
ElementFilteringImageAlgorithm(const ElementFilteringFunction< T > &f, const StructuringElement &se=strel::Cube(1.))
std::vector< int > getBorders() const
virtual void setOptions(const carto::Object &options)
virtual void execute(const carto::VolumeRef< T > &in, carto::VolumeRef< T > &out) const
ImageAlgorithmInterface Pure virtual method.
::aims::singlechannel::ElementFilteringImageAlgorithm< T > & operator=(const ::aims::singlechannel::ElementFilteringImageAlgorithm< T > &other)
virtual void updateOptions(const carto::Object &options)
virtual LinearFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface Pure virtual method.
ElementFilteringImageAlgorithm(const ElementFilteringFunction< ChannelType > &f, const StructuringElement &se=strel::Cube(1.))