aimsalgo  5.0.5
Neuroimaging image processing
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>(),
105  _lalgo( SingleChannelImageAlgorithmType( f ).clone() )
106  {
107  ImageAlgorithm<T>::_algo.reset( _lalgo );
108  }
110  ImageAlgorithm<T>(),
111  _lalgo( other._lalgo->clone() )
112  {
113  ImageAlgorithm<T>::_algo.reset( _lalgo );
114  }
116  {
117  _lalgo = other._lalgo->clone();
118  ImageAlgorithm<T>::_algo.reset( _lalgo );
119  return *this;
120  }
121  public:
123 
124  //----------------------------------------------------------------------
125  // member
126  //----------------------------------------------------------------------
127  protected:
128  SingleChannelImageAlgorithmType * _lalgo;
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  {
168  _ealgo->setStructuringElement( se );
169  }
170 
171  //----------------------------------------------------------------------
172  // constructor (default+copy) & destructor
173  //----------------------------------------------------------------------
174  protected:
177  const StructuringElement & se = strel::Cube(1.)
178  ):
179  ImageAlgorithm<T>(),
180  _ealgo( SingleChannelImageAlgorithmType( f, se ).clone() )
181  {
182  ImageAlgorithm<T>::_algo.reset( _ealgo );
183  }
185  ImageAlgorithm<T>(),
186  _ealgo(other._ealgo->clone())
187  {
188  ImageAlgorithm<T>::_algo.reset( _ealgo );
189  }
191  {
192  _ealgo = other._ealgo->clone();
193  ImageAlgorithm<T>::_algo.reset( _ealgo );
194  return *this;
195  }
196  public:
198 
199  //----------------------------------------------------------------------
200  // member
201  //----------------------------------------------------------------------
202  protected:
203  SingleChannelImageAlgorithmType * _ealgo;
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:
244  _func(f.clone())
245  {}
246 
247  LinearFilteringImageAlgorithm( const ::aims::singlechannel::LinearFilteringImageAlgorithm<T> & other ):
249  _func(other._func->clone())
250  {}
251 
253  const LinearFilteringImageAlgorithm & other )
254  {
255  assert( typeid(other) == typeid(*this) );
256  if( this != &other )
257  _func.reset( other._func->clone() );
258  return *this;
259  }
260 
262 
263  //--------------------------------------------------------------------
264  // member
265  //--------------------------------------------------------------------
266  protected:
268  };
269 
270  template <typename T>
271  inline
273  const carto::VolumeRef<T> & in,
274  carto::VolumeRef<T> & out ) const
275  {
276  int sx, sy, sz, ex, ey, ez, x, y, z, t;
277  typename carto::Volume<T>::Position4Di pos(0,0,0,0), size(1,1,1,1);
278 
279  // set voxel size
281  std::vector<float> vs(4, 1.);
282  in.header().getProperty( "voxel_size", vs );
283  options->setProperty( "voxel_size", vs );
284  _func->updateOptions( options );
285 
286  // Manage borders / structuring element size
287  const std::vector<int> & border = in->getBorders();
288  const std::vector<int> & amplitude = _func->getAmplitude();
289 
290  // When volume has borders, it is possible to use it to process filtering
291  sz = (amplitude[4] < border[4]) ? 0 : amplitude[4] - border[4];
292  sy = (amplitude[2] < border[2]) ? 0 : amplitude[2] - border[2];
293  sx = (amplitude[0] < border[0]) ? 0 : amplitude[0] - border[0];
294  ez = (amplitude[5] < border[5]) ? in->getSizeZ() : in->getSizeZ() - amplitude[5] + border[5];
295  ey = (amplitude[3] < border[3]) ? in->getSizeY() : in->getSizeY() - amplitude[3] + border[3];
296  ex = (amplitude[1] < border[1]) ? in->getSizeX() : in->getSizeX() - amplitude[1] + border[1];
297 
299  std::cout << "Filter amplitude (voxels): [ ";
300  for(int i = 0; i < 6; ++i)
301  std::cout << carto::toString(amplitude[i]) << ( i==5 ? " " : ", ");
302  std::cout << "]" << std::endl;
303  std::cout << "Processing with borders (voxels): [ ";
304  for(int i = 0; i < 8; ++i)
305  std::cout << carto::toString(border[i]) << ( i==7 ? " " : ", ");
306  std::cout << "]" << std::endl;
307  std::cout << "Start: [" << carto::toString(sx) << ", "
308  << carto::toString(sy) << ", "
309  << carto::toString(sz) << "]" << std::endl;
310  std::cout << "End: [" << carto::toString(ex) << ", "
311  << carto::toString(ey) << ", "
312  << carto::toString(ez) << "]" << std::endl;
313  }
314 
315  size[0] = amplitude[0] + amplitude[1] + 1;
316  size[1] = amplitude[2] + amplitude[3] + 1;
317  size[2] = amplitude[4] + amplitude[5] + 1;
318  carto::VolumeRef<T> win( new carto::Volume<T>( in, pos, size ) );
319 
320  aims::Progression progress( static_cast<size_t>(out->getSizeT())
321  * (ez - sz) * (ey - sy) * (ex - sx) );
323  std::cout << "Filtering progress: ";
324 
325  for( t = 0; t < in->getSizeT(); ++t )
326  for( z = sz; z < ez; ++z )
327  for( y = sy; y < ey; ++y )
328  for( x = sx; x < ex; ++x )
329  {
330  if( this->_verbose > 0 )
331  (++progress).print();
332  // Set view position in the volume
333  pos[0] = x - amplitude[0];
334  pos[1] = y - amplitude[2];
335  pos[2] = z - amplitude[4];
336  pos[3] = t;
337  win->setPosInRefVolume( pos );
338  (*out)( x, y, z, t ) = _func->execute( win );
339  }
340 
342  std::cout << std::endl;
343  }
344 
345 
346  //========================================================================
347  // ELEMENT FILTERING IMAGE ALGORITHM: SINGLE CHANNEL
348  //========================================================================
349  template <typename T>
351  {
352  public:
353  //--------------------------------------------------------------------
354  // image algorithm interface: implementation
355  //--------------------------------------------------------------------
356  virtual void execute( const carto::VolumeRef<T> & in,
357  carto::VolumeRef<T> & out ) const;
358 
359  virtual void setOptions( const carto::Object & options )
360  {
361  _func->setOptions( options );
362  }
363 
364  virtual void updateOptions( const carto::Object & options )
365  {
366  _func->updateOptions( options );
367  }
368 
369  virtual ::aims::singlechannel::ElementFilteringImageAlgorithm<T> * clone() const {
370  return new ::aims::singlechannel::ElementFilteringImageAlgorithm<T>(*this);
371  }
372 
373  //--------------------------------------------------------------------
374  // member method
375  //--------------------------------------------------------------------
376  virtual void setStructuringElement( const StructuringElement & se )
377  {
378  _strel.reset( se.clone() );
379  }
380 
381  //--------------------------------------------------------------------
382  // constructor (default+copy) & destructor
383  //--------------------------------------------------------------------
384  protected:
386 
387  public:
389  const StructuringElement & se = strel::Cube(1.) ):
391  _func(f.clone()),
392  _strel(se.clone())
393  {}
394 
395  ElementFilteringImageAlgorithm( const ::aims::singlechannel::ElementFilteringImageAlgorithm<T> & other ):
397  _func(other._func->clone()),
398  _strel(other._strel->clone())
399  {}
400 
402  const ::aims::singlechannel::ElementFilteringImageAlgorithm<T> & other )
403  {
404  assert( typeid(other) == typeid(*this) );
405  if( *this != other )
406  {
407  _func.reset( other._func->clone() );
408  _strel.reset( other._strel->clone() );
409  }
410  return *this;
411  }
412 
414 
415  //--------------------------------------------------------------------
416  // members
417  //--------------------------------------------------------------------
418  protected:
421  };
422 
423  template <typename T>
424  inline
426  const carto::VolumeRef<T> & in,
427  carto::VolumeRef<T> & out
428  ) const
429  {
430  int sx, sy, sz, ex, ey, ez, x, y, z, t;
431  typename carto::Volume<T>::Position4Di pos(0,0,0), size(1,1,1);
432 
433  // Manage borders / structuring element size
434  const std::vector<int> & border = in->getBorders();
435  const std::vector<int> amplitude = _strel->getAmplitude();
436 
437  // When volume has borders, it is possible to use it to process filtering
438  sz = (amplitude[4] < border[4]) ? 0 : amplitude[4] - border[4];
439  sy = (amplitude[2] < border[2]) ? 0 : amplitude[2] - border[2];
440  sx = (amplitude[0] < border[0]) ? 0 : amplitude[0] - border[0];
441  ez = (amplitude[5] < border[5]) ? in->getSizeZ() : in->getSizeZ() - amplitude[5] + border[5];
442  ey = (amplitude[3] < border[3]) ? in->getSizeY() : in->getSizeY() - amplitude[3] + border[3];
443  ex = (amplitude[1] < border[1]) ? in->getSizeX() : in->getSizeX() - amplitude[1] + border[1];
444 
446  std::cout << "Filter amplitude (voxels): [ ";
447  for(int i = 0; i < 6; ++i)
448  std::cout << carto::toString(amplitude[i]) << ( i==8 ? " " : ", ");
449  std::cout << "]" << std::endl;
450  std::cout << "Processing with borders (voxels): [ ";
451  for(int i = 0; i < 8; ++i)
452  std::cout << carto::toString(border[i]) << ( i==8 ? " " : ", ");
453  std::cout << "]" << std::endl;
454  std::cout << "Start: [" << carto::toString(sx) << ", "
455  << carto::toString(sy) << ", "
456  << carto::toString(sz) << "]" << std::endl;
457  std::cout << "End: [" << carto::toString(ex) << ", "
458  << carto::toString(ey) << ", "
459  << carto::toString(ez) << "]" << std::endl;
460  }
461 
462  carto::VolumeRef<T> win( new carto::Volume<T>( in, pos, size ) );
463 
464  aims::Progression progress( static_cast<size_t>(out->getSizeT())
465  * (ez - sz) * (ey - sy) *(ex - sx) );
467  std::cout << "Filtering progress: ";
468 
469  for( t = 0; t < in->getSizeT(); ++t )
470  for( z = sz; z < ez; ++z )
471  for( y = sy; y < ey; ++y )
472  for( x = sx; x < ex; ++x )
473  {
474  if( this->_verbose > 0 )
475  (++progress).print();
476  // Set view position in the volume
477  pos[0] = x;
478  pos[1] = y;
479  pos[2] = z;
480  pos[3] = t;
481  win->setPosInRefVolume( pos );
482  (*out)( x, y, z, t ) = _func->execute( win, _strel );
483  }
484 
486  std::cout << std::endl;
487  }
488 
489  } // namespace singlechannel
490 
491 } // namespace aims
492 
493 #endif
LinearFilteringImageAlgorithm(const LinearFilteringFunction< T > &f)
int getSizeX() const
int getSizeY() const
int getSizeZ() const
virtual void updateOptions(const carto::Object &options)
SingleChannelImageAlgorithmType * _ealgo
virtual void setStructuringElement(const StructuringElement &se)
virtual void execute(const carto::VolumeRef< T > &in, carto::VolumeRef< T > &out) const
ImageAlgorithmInterface<T> Pure virtual method.
virtual void updateOptions(const carto::Object &options)
int getSizeT() const
SingleChannelImageAlgorithmType * _lalgo
singlechannel::ElementFilteringImageAlgorithm< ChannelType > SingleChannelImageAlgorithmType
singlechannel::LinearFilteringImageAlgorithm< ChannelType > SingleChannelImageAlgorithmType
Base class for filtering functions applied in a structuring element.
const PropertySet & header() const
virtual ElementFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface<T> Pure virtual method.
virtual LinearFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface<T> Pure virtual method.
virtual void setOptions(const carto::Object &options)
carto::rc_ptr< LinearFilteringFunction< T > > _func
virtual ::aims::singlechannel::ElementFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface<T> Pure virtual method.
virtual ::aims::singlechannel::LinearFilteringImageAlgorithm< T > * clone() const
ImageAlgorithmInterface<T> Pure virtual method.
virtual void updateOptions(const carto::Object &options)
LinearFilteringImageAlgorithm(const LinearFilteringFunction< ChannelType > &f)
virtual void setStructuringElement(const StructuringElement &se)
void setPosInRefVolume(const Position4Di &pos)
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)
ElementFilteringImageAlgorithm(const ElementFilteringImageAlgorithm< T > &other)
static Object value()
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)
LinearFilteringImageAlgorithm(const ::aims::singlechannel::LinearFilteringImageAlgorithm< T > &other)
virtual void execute(const carto::VolumeRef< T > &in, carto::VolumeRef< T > &out) const
ImageAlgorithmInterface<T> Pure virtual method.
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.))
virtual void setOptions(const carto::Object &options)
::aims::singlechannel::ElementFilteringImageAlgorithm< T > & operator=(const ::aims::singlechannel::ElementFilteringImageAlgorithm< T > &other)
std::vector< int > getBorders() const
virtual void updateOptions(const carto::Object &options)
ElementFilteringImageAlgorithm(const ElementFilteringFunction< ChannelType > &f, const StructuringElement &se=strel::Cube(1.))
virtual StructuringElement * clone() const