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