31 #include "WMAnisotropicFiltering.h"
32 #include "WMAnisotropicFiltering.xpm"
33 #include "core/common/WPropertyHelper.h"
34 #include "core/dataHandler/WDataHandler.h"
35 #include "core/kernel/WKernel.h"
57 return "Anisotropic Filter";
62 return "Filters MRI data, preserving edges.";
67 return WMAnisotropicFiltering_xpm;
72 m_input = std::shared_ptr< WModuleInputData < WDataSetSingle > >(
76 m_output = std::shared_ptr< WModuleOutputData < WDataSetSingle > >(
122 std::shared_ptr< WDataSetSingle > newDataSet =
m_input->getData();
123 bool dataChanged = (
m_dataSet != newDataSet );
124 bool dataValid = ( newDataSet != NULL );
141 infoLog() <<
"Calculation complete.";
147 debugLog() <<
"Finished! Good Bye!";
155 std::size_t numImages =
m_dataSet->getValueSet()->rawSize() /
m_dataSet->getGrid()->size();
156 infoLog() <<
"Images: " << numImages;
158 std::shared_ptr< std::vector< double > > smoothed(
new std::vector< double >(
m_dataSet->getValueSet()->rawSize() ) );
159 std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >(
m_dataSet->getGrid() );
165 std::vector< double > deriv( 3 *
m_dataSet->getGrid()->size() );
168 std::vector< double > coeff(
m_dataSet->getGrid()->size() );
170 std::shared_ptr< WProgress > prog(
new WProgress(
"Smoothing images", numImages ) );
173 for( std::size_t k = 0; k < numImages; ++k )
175 for(
int i = 0; i < iterations; ++i )
177 calcDeriv( deriv, smoothed, grid, k, numImages );
191 diffusion( deriv, coeff, smoothed, grid, k, numImages );
209 std::shared_ptr< WDataSetSingle > ds =
m_dataSet->clone( vs );
215 std::size_t x, std::size_t y, std::size_t z )
217 return x + y * grid->getNbCoordsX() + z * grid->getNbCoordsX() * grid->getNbCoordsY();
221 std::shared_ptr< WGridRegular3D >
const& )
223 for( std::size_t k = 0; k <
m_dataSet->getValueSet()->rawSize(); ++k )
225 ( *smoothed )[ k ] =
m_dataSet->getValueSet()->getScalarDouble( k );
230 std::shared_ptr< std::vector< double > >
const& smoothed,
231 std::shared_ptr< WGridRegular3D >
const& grid, std::size_t image, std::size_t numImages )
233 std::size_t s[] = { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() };
234 double d[] = { fabs( grid->getOffsetX() ), fabs( grid->getOffsetY() ), fabs( grid->getOffsetZ() ) };
236 for( std::size_t x = 0; x < grid->getNbCoordsX(); ++x )
238 for( std::size_t y = 0; y < grid->getNbCoordsY(); ++y )
240 for( std::size_t z = 0; z < grid->getNbCoordsZ(); ++z )
242 double const& x1 = ( *smoothed )[ numImages *
coordsToIndex( grid, ( x + 1 ) % s[ 0 ], y, z ) + image ];
243 double const& x2 = ( *smoothed )[ numImages *
coordsToIndex( grid, ( x + s[ 0 ] - 1 ) % s[ 0 ], y, z ) + image ];
244 deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 0 ] = ( x1 - x2 ) / ( 2.0 * d[ 0 ] );
246 double const& y1 = ( *smoothed )[ numImages *
coordsToIndex( grid, x, ( y + 1 ) % s[ 1 ], z ) + image ];
247 double const& y2 = ( *smoothed )[ numImages *
coordsToIndex( grid, x, ( y + s[ 1 ] - 1 ) % s[ 1 ], z ) + image ];
248 deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 1 ] = ( y1 - y2 ) / ( 2.0 * d[ 1 ] );
250 double const& z1 = ( *smoothed )[ numImages *
coordsToIndex( grid, x, y, ( z + 1 ) % s[ 2 ] ) + image ];
251 double const& z2 = ( *smoothed )[ numImages *
coordsToIndex( grid, x, y, ( z + s[ 2 ] - 1 ) % s[ 2 ] ) + image ];
252 deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 2 ] = ( z1 - z2 ) / ( 2.0 * d[ 2 ] );
259 std::vector< double >
const& deriv,
260 std::shared_ptr< WGridRegular3D >
const& grid )
262 for( std::size_t x = 0; x < grid->getNbCoordsX(); ++x )
264 for( std::size_t y = 0; y < grid->getNbCoordsY(); ++y )
266 for( std::size_t z = 0; z < grid->getNbCoordsZ(); ++z )
269 double gradIAbsSquared = deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 0 ]
282 std::shared_ptr< std::vector< double > >& smoothed,
283 std::shared_ptr< WGridRegular3D >
const& grid, std::size_t image, std::size_t numImages )
285 std::size_t s[] = { grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ() };
286 double d[] = { fabs( grid->getOffsetX() ), fabs( grid->getOffsetY() ), fabs( grid->getOffsetZ() ) };
288 for( std::size_t x = 0; x < grid->getNbCoordsX(); ++x )
290 for( std::size_t y = 0; y < grid->getNbCoordsY(); ++y )
292 for( std::size_t z = 0; z < grid->getNbCoordsZ(); ++z )
295 double const& dIx = deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 0 ];
296 double const& dIy = deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 1 ];
297 double const& dIz = deriv[ 3 *
coordsToIndex( grid, x, y, z ) + 2 ];
300 double dcx = ( coeff[
coordsToIndex( grid, ( x + 1 ) % s[ 0 ], y, z ) ]
301 - coeff[
coordsToIndex( grid, ( x + s[ 0 ] - 1 ) % s[ 0 ], y, z ) ] )
303 double dcy = ( coeff[
coordsToIndex( grid, x, ( y + 1 ) % s[ 1 ], z ) ]
304 - coeff[
coordsToIndex( grid, x, ( y + s[ 1 ] - 1 ) % s[ 1 ], z ) ] )
306 double dcz = ( coeff[
coordsToIndex( grid, x, y, ( z + 1 ) % s[ 2 ] ) ]
307 - coeff[
coordsToIndex( grid, x, y, ( z + s[ 2 ] - 1 ) % s[ 2 ] ) ] )
314 double ddIxx = ( deriv[ 3 *
coordsToIndex( grid, ( x + 1 ) % s[ 0 ], y, z ) + 0 ]
315 - deriv[ 3 *
coordsToIndex( grid, ( x + s[ 0 ] - 1 ) % s[ 0 ], y, z ) + 0 ] )
317 double ddIyy = ( deriv[ 3 *
coordsToIndex( grid, x, ( y + 1 ) % s[ 1 ], z ) + 1 ]
318 - deriv[ 3 *
coordsToIndex( grid, x, ( y + s[ 1 ] - 1 ) % s[ 1 ], z ) + 1 ] )
320 double ddIzz = ( deriv[ 3 *
coordsToIndex( grid, x, y, ( z + 1 ) % s[ 2 ] ) + 2 ]
321 - deriv[ 3 *
coordsToIndex( grid, x, y, ( z + s[ 2 ] - 1 ) % s[ 2 ] ) + 2 ] )
325 ( *smoothed )[ numImages *
coordsToIndex( grid, x, y, z ) + image ] +=
m_d * ( dIx * dcx + dIy * dcy + dIz * dcz
326 + c * ( ddIxx + ddIyy + ddIzz ) );
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
This module smoothes images of a dataset while preserving edges.
std::shared_ptr< WDataSetSingle > m_dataSet
This is a pointer to the dataset the module is currently working on.
virtual void moduleMain()
Entry point after loading the module.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
double m_d
The size of the time steps.
WPropDouble m_Kcoeff
A property for the edge preservation parameter.
void calcDeriv(std::vector< double > &deriv, std::shared_ptr< std::vector< double > > const &smoothed, std::shared_ptr< WGridRegular3D > const &grid, std::size_t image, std::size_t numImages)
Calculates an array containing the derivatives in x, y and z directions of the image intensity (i....
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const std::string getName() const
Gives back the name of this module.
WPropDouble m_delta
A property for the time step size.
virtual const char ** getXPMIcon() const
Return an icon for this module.
void calcCoeff(std::vector< double > &coeff, std::vector< double > const &deriv, std::shared_ptr< WGridRegular3D > const &grid)
Calculates the diffusion coeff for every voxel.
virtual ~WMAnisotropicFiltering()
Destructor.
std::shared_ptr< WModuleOutputData< WDataSetSingle > > m_output
An output connector for the output dataset.
void copyData(std::shared_ptr< std::vector< double > > &smoothed, std::shared_ptr< WGridRegular3D > const &grid)
Copy the datasets image data to a temp array.
void diffusion(std::vector< double > const &deriv, std::vector< double > const &coeff, std::shared_ptr< std::vector< double > > &smoothed, std::shared_ptr< WGridRegular3D > const &grid, std::size_t image, std::size_t numImages)
Do the diffusion.
virtual const std::string getDescription() const
Gives back a description of this module.
virtual void properties()
Initialize the properties for this module.
std::shared_ptr< WModuleInputData< WDataSetSingle > > m_input
An input connector that accepts multi image datasets.
WMAnisotropicFiltering()
Standard constructor.
void calcSmoothedImages(int iterations)
Calculates the resulting smoothed image.
virtual void connectors()
Initialize the connectors this module is using.
std::size_t coordsToIndex(std::shared_ptr< WGridRegular3D > const &grid, std::size_t x, std::size_t y, std::size_t z)
Calculates grid indices from voxel coords.
double m_k
The edge preservation parameter used for diffusion coeff calculation.
WPropInt m_iterations
A property for the number of iterations.
virtual void activate()
Callback for m_active.
Class representing a single module of OpenWalnut.
virtual void properties()
Initialize properties in this function.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
std::shared_ptr< WProperties > m_properties
The property object for the module.
void ready()
Call this whenever your module is ready and can react on property changes.
WConditionSet m_moduleState
The internal state of the module.
virtual void activate()
Callback for m_active.
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
wlog::WStreamedLogger infoLog() const
Logger instance for comfortable info logging.
virtual void connectors()
Initialize connectors in this function.
Class managing progress inside of modules.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.