36#ifndef AIMS_DIFFUSION_SMOOTHER_D_H
37#define AIMS_DIFFUSION_SMOOTHER_D_H
42#include <aims/utility/converter_volume.h>
58 carto::AllocatorContext::fast() );
79 std::cerr <<
"diffusionConvolution Smoother: "
80 <<
"maxiter negative value is forbidden" << std::endl;
93 kernel(0,1,1) = kernel(2,1,1) = this->
_dt / ( vs[0] * vs[0] );
94 kernel(1,0,1) = kernel(1,2,1) = this->
_dt / ( vs[1] * vs[1] );
95 kernel(1,1,0) = kernel(1,1,2) = this->
_dt / ( vs[2] * vs[2] );
96 kernel(1,1,1) = -this->
_dt * (2. / (vs[0] * vs[0])
97 + 2. / (vs[1] * vs[1])
98 + 2. / (vs[2] * vs[2]) );
101 kernel(1,1,1) = 1. + kernel(1,1,1);
111 std::vector<int> dim = ima->
getSize();
115 tmp1 = &imaF; tmp2 = &ima2;
117 for (
int i = 0; i < maxiter; i++)
119 if (verbose) std::cout <<
"+" << std::flush;
120 if( _hasConstantSources )
123 for( z=0; z<dim[2]; ++z )
124 for( y=0; y<dim[1]; ++y )
125 for( x=0; x<dim[0]; ++x )
127 T & v = _constantSources( x, y, z );
128 if( v != _constantSourcesBackground )
129 (*tmp1)( x, y, z ) = v;
132 (*tmp2) = convolution.
doit( *tmp1, kernel );
138 if( _hasConstantSources )
141 for( z=0; z<dim[2]; ++z )
142 for( y=0; y<dim[1]; ++y )
143 for( x=0; x<dim[0]; ++x )
145 T & v = _constantSources( x, y, z );
146 if( v != _constantSourcesBackground )
147 (*tmp1)( x, y, z ) = v;
151 if (verbose) std::cout <<
"Finished" << std::endl;
165 _constantSources = sources;
166 _constantSourcesBackground = bgr;
167 _hasConstantSources =
true;
174 _hasConstantSources =
false;
183 this->
check(maxiter);
187 kernel(0,1,1) = kernel(2,1,1) = this->
_dt / ( vs[0] * vs[0] );
188 kernel(1,0,1) = kernel(1,2,1) = this->
_dt / ( vs[1] * vs[1] );
189 kernel(1,1,0) = kernel(1,1,2) = this->
_dt / ( vs[2] * vs[2] );
190 kernel(1,1,1) = -this->
_dt * (2. / (vs[0] * vs[0])
191 + 2. / (vs[1] * vs[1])
192 + 2. / (vs[2] * vs[2]) );
195 kernel(1,1,1) = 1. + kernel(1,1,1);
207 std::vector<int> dim = ima->
getSize();
210 tmp1 = &imaF; tmp2 = &ima2;
212 for (
int i = 0; i < maxiter; i++)
214 if (verbose) std::cout <<
"+" << std::flush;
215 if (_has_neumann_condition)
216 update_neumann_conditions(*tmp1);
217 (*tmp2) = convolution.
doit((*tmp1), kernel);
223 if (verbose) std::cout <<
"Finished" << std::endl;
233template<
typename T>
inline
235add_neumann_condition(
const Point3df &p)
237 _has_neumann_condition =
true;
238 _neumann_conditions.push_back(p);
250 for (
unsigned int i = 0; i < _neumann_conditions.size(); ++i)
253 const Point3df &p = _neumann_conditions[i];
254 for (i = 0; i < 3; ++i)
255 for (d = -1; d <= 1; d += 2)
259 if (p2[i] < 0 or p2[i] >= dim[i])
continue;
260 if (((this->_mask))(p2[0], p2[1], p2[2]) != 0)
262 ima(p[0], p[1], p[2]) =ima(p2[0], p2[1], p2[2]);
271template<
typename T> carto::VolumeRef<T>
275 this->
check(maxiter);
280 std::vector<int> dim = ima->
getSize();
283 tmp1 = &imaF; tmp2 = &ima2;
285 for (
int i = 0; i < maxiter; i++)
287 if (verbose) std::cout <<
"+" << std::flush;
294 if (verbose) std::cout <<
"Finished" << std::endl;
303template<
typename T>
void
307 int i, d, x, y, z, t, n;
314 for (t = 0; t <
dt; t++)
315 for (z = 0; z < dz; z++)
316 for (y = 0; y < dy; y++)
317 for (x = 0; x < dx; x++)
319 std::cout <<
"x,y,z = " << x <<
", " << y <<
", " << z << std::endl;
320 std::cout <<
"mask = " << ((*this->
_mask)(x, y, z, t)) << std::endl;
322 (*this->
_mask)(x, y, z, t) == this->_neumann_value)
324 ima2(x, y, z, t) = ima1(x, y, z, t);
330 for (i = 0; i < 3; ++i)
331 for (d = -1; d <= 1; d += 2)
335 if (p2[i] < 0 or p2[i] >= dim[i])
continue;
336 if ((*this->
_mask)(p2[0], p2[1], p2[2], t)
337 == this->_neumann_value)
continue;
339 val += ima1(p2[0], p2[1], p2[2], t);
341 val -= n * ima1(x, y, z, t);
342 ima2(x, y, z, t) = ima1(x, y, z, t) + this->
_dt * val;
The template class to make convolutions.
carto::VolumeRef< T > doit(carto::rc_ptr< carto::Volume< T > > &, carto::rc_ptr< carto::Volume< T > > &)
Make convolution only on a specified mask.
static carto::VolumeRef< float > init_laplacian(void)
static carto::VolumeRef< float > laplacian
carto::VolumeRef< short > _mask
void setConstantSources(const carto::VolumeRef< T > &, const T &background)
void removeConstantSources()
virtual carto::VolumeRef< T > doSmoothing(const carto::VolumeRef< T > &ima, int maxiter, bool verbose=false)
MaskedDiffusionSmoother(float delta_t, bool safe=true)
void convolution(const carto::VolumeRef< float > &ima1, carto::VolumeRef< float > &ima2) const
MaskedDiffusionSmoother(float delta_t, bool safe=true)
virtual void convert(const INP &in, OUTP &out) const
std::vector< float > getVoxelSize() const
std::vector< int > getSize() const
carto::VolumeRef< float > BaseDiffusionSmoother< T >::laplacian
AimsVector< float, 3 > Point3df
AimsVector< int32_t, 3 > Point3di