aimsalgo  5.0.5
Neuroimaging image processing
peronaMalikSmoother_d.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 
35 #ifndef AIMS_PRIMALSKETCH_PERONAMALIKSMOOTHER_D_H
36 #define AIMS_PRIMALSKETCH_PERONAMALIKSMOOTHER_D_H
37 
38 #include <cstdlib>
42 
43 namespace aims
44 {
45 
46  template<class T> AimsData<T> PeronaMalikSmoother<T>::doSmoothing(const AimsData<T> & ima, int maxiter, bool /*verbose*/)
47  {
48  if (maxiter >= 0)
49  {
50  AimsData<float> kernel(3, 3, 3, 1);
51  AimsData<float> *tmp1, *tmp2, *swap, grad;
52  int i;
53  int x,y,z, count=0;
54  int sx=ima.dimX(), sy=ima.dimY(), sz=ima.dimZ();
55  std::map<float, int> valueSet;
56  std::map<float,int>::iterator itVal;
57  float nbThresh;
58  float gxm, gxp, gym, gyp, gzm, gzp, cxm, cxp, cym, cyp, czm, czp;
59 
63 
65  AimsData< float > imaF( ima.dimX(), ima.dimY(), ima.dimZ(), ima.dimT() ),
66  ima2( ima.dimX(), ima.dimY(), ima.dimZ(), ima.dimT() );
67  conv.convert( ima, imaF );
68 
69 
70  std::cout << "Evaluating gradient bound : " << std::endl;
71 
72  grad=gaussGrad.doit(imaF);
73  Writer<AimsData<float> > writerG( "gradient.ima" );
74  writerG.write( grad );
75 
76  // Evaluation of the gradient parameter from K
77 
78  std::cout << "Ordering values" << std::endl;
79 
80  nbThresh=sx*sz*sy*_K;
81 
82  for (z=0; z<sz; z++)
83  for (y=0; y<sy; y++)
84  for (x=0; x<sx; x++)
85  {
86  if (valueSet.find(grad(x,y,z)) != valueSet.end())
87  valueSet[grad(x,y,z)]++;
88  else
89  valueSet.insert(std::pair<float,int>(grad(x,y,z), 1));
90  }
91  itVal=valueSet.begin();
92 
93  std::cout << "Looking for bound with K= " << _K << " at value number " << nbThresh << std::endl;
94  for (; itVal!=valueSet.end(); ++itVal)
95  {
96  count+=(*itVal).second;
97  if ((count>=nbThresh) && ((count-1)<nbThresh))
98  _gradK=(*itVal).first;
99  }
100  std::cout << "Gradient bound has been set to " << _gradK << std::endl;
101 
102  tmp1=&imaF; tmp2=&ima2;
103  std::cout << "Starting " << maxiter << " iterations of diffusion process" << std::endl;
104 
105  for (i=0; i<maxiter; i++)
106  {
107  std::cout << "+" << std::flush;
108  grad=gaussGrad.doit((*tmp1));
109 
110  for (z=0; z<sz; z++)
111  for (y=0; y<sy; y++)
112  for (x=0; x<sx; x++)
113  {
114  if (x==0)
115  {
116  gxm=0; gxp=(*tmp1)(x+1,y,z) - (*tmp1)(x,y,z);
117  cxm=0; cxp=conductance( (grad(x+1,y,z)+grad(x,y,z))/2.0);
118  }
119  else if (x==sx-1)
120  {
121  gxm=(*tmp1)(x-1,y,z) - (*tmp1)(x,y,z); gxp=0;
122  cxm=conductance( (grad(x-1,y,z)+grad(x,y,z))/2.0); cxp=0;
123  }
124  else
125  {
126  gxm=(*tmp1)(x-1,y,z) - (*tmp1)(x,y,z); gxp=(*tmp1)(x+1,y,z) - (*tmp1)(x,y,z);
127  cxm=conductance( (grad(x-1,y,z)+grad(x,y,z))/2.0); cxp=conductance( (grad(x+1,y,z)+grad(x,y,z))/2.0);
128  }
129 
130  if (y==0)
131  {
132  gym=0; gyp=(*tmp1)(x,y+1,z) - (*tmp1)(x,y,z);
133  cym=0; cyp=conductance( (grad(x,y+1,z)+grad(x,y,z))/2.0);
134  }
135  else if (y==sy-1)
136  {
137  gym=(*tmp1)(x,y-1,z) - (*tmp1)(x,y,z); gyp=0;
138  cym=conductance( (grad(x,y-1,z)+grad(x,y,z))/2.0); cyp=0;
139  }
140  else
141  {
142  gym=(*tmp1)(x,y-1,z) - (*tmp1)(x,y,z); gyp=(*tmp1)(x,y+1,z) - (*tmp1)(x,y,z);
143  cym=conductance( (grad(x,y-1,z)+grad(x,y,z))/2.0); cyp=conductance( (grad(x,y+1,z)+grad(x,y,z))/2.0);
144  }
145 
146  if (z==0)
147  {
148  gzm=0; gzp=(*tmp1)(x,y,z+1) - (*tmp1)(x,y,z);
149  czm=0; czp=conductance( (grad(x,y,z+1)+grad(x,y,z))/2.0);
150  }
151  else if (z==sz-1)
152  {
153  gzm=(*tmp1)(x,y,z-1) - (*tmp1)(x,y,z); gzp=0;
154  czm=conductance( (grad(x,y,z-1)+grad(x,y,z))/2.0); czp=0;
155  }
156  else
157  {
158  gzm=(*tmp1)(x,y,z-1) - (*tmp1)(x,y,z); gzp=(*tmp1)(x,y,z+1) - (*tmp1)(x,y,z);
159  czm=conductance( (grad(x,y,z-1)+grad(x,y,z))/2.0); czp=conductance( (grad(x,y,z+1)+grad(x,y,z))/2.0);
160  }
161 
162  (*tmp2)(x,y,z)=(*tmp1)(x,y,z) + _dt *
163  ( cxm*gxm + cxp*gxp
164  +cym*gym + cyp*gyp
165  +czm*gzm + czp*gzp );
166  }
167  swap=tmp1;
168  tmp1=tmp2;
169  tmp2=swap;
170  }
171  std::cout << "Finished" << std::endl;
173  AimsData<T> ima3( ima.dimX(), ima.dimY(), ima.dimZ(), ima.dimT() );
174  conv2.convert( (*tmp1), ima3);
175 
176  return ima3;
177  }
178  else
179  {
180  std::cerr << "PeronaMalik smoother must have tIn < tOut" << std::endl;
181  exit(EXIT_FAILURE);
182  }
183  }
184 
185 }
186 
187 #endif
int dimZ() const
AimsData< T > doSmoothing(const AimsData< T > &ima, int maxiter, bool verbose=false)
int dimY() const
virtual void convert(const INP &in, OUTP &out) const
virtual bool write(const T &obj, bool ascii=false, const std::string *format=0)
int dimT() const
void swap(scoped_ptr< T > &x, scoped_ptr< T > &y)
AimsData< float > doit(const AimsData< T > &)
Definition: ggradient.h:74
int dimX() const