m_InputImage( NULL ),
m_SegmentedImage( NULL ),
m_ActivePlugin( NULL ),
- m_ActiveParameters( NULL )
+ m_ActiveParameters( NULL ),
+ m_ActivePluginType( Self::NonePluginType ),
+ m_ActivePluginCategory( Self::NonePluginCategory )
{
this->m_UI->setupUi( this );
this->m_UI->m_3DVTK->GetRenderWindow( )
);
+ // Associate observer
+ this->m_DoubleClickCommand =
+ vtkSmartPointer< DoubleClickCommand >::New( );
+ this->m_DoubleClickCommand->SetMainWnd( this );
+ this->m_MPR->AddDoubleClickObserver( this->m_DoubleClickCommand );
+
// Orientation marks
/* TODO
vtkSmartPointer< vtkAnnotatedCubeActor > oCube =
*/
// Ok, start!
- this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
- this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
- this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
+ this->m_MPR->Render( 0 );
+ this->m_MPR->Render( 1 );
+ this->m_MPR->Render( 2 );
this->_UpdateEnabledFlags( );
} // fi
#include <QWidget>
// vtk stuff
+#include <vtkCommand.h>
#include <vtkOrientationMarkerWidget.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <cpPlugins/Interface/DataObject.h>
#include <cpPlugins/Extensions/Visualization/MPRWithDifferentWindows.h>
+// -------------------------------------------------------------------------
+class MainWnd;
+
+class DoubleClickCommand
+ : public vtkCommand
+{
+public:
+ typedef DoubleClickCommand Self;
+
+public:
+ vtkTypeMacro( DoubleClickCommand, vtkCommand );
+
+public:
+ static DoubleClickCommand* New( );
+
+ void SetMainWnd( MainWnd* wnd );
+ void Execute( vtkObject* caller, unsigned long eid, void* data );
+
+protected:
+ DoubleClickCommand( );
+ virtual ~DoubleClickCommand( );
+
+private:
+ // Purposely not implemented
+ DoubleClickCommand( const Self& );
+ Self& operator=( const Self& );
+
+protected:
+ MainWnd* m_MainWnd;
+};
+
// -------------------------------------------------------------------------
namespace Ui
{
Q_OBJECT;
public:
+ friend class DoubleClickCommand;
+
+ typedef MainWnd Self;
+
// Plugins types
typedef cpPlugins::Interface::Interface TPluginsInterface;
typedef cpPlugins::Interface::Object TPluginObject;
typedef cpPlugins::Interface::DataObject TPluginData;
typedef cpPlugins::Interface::Image TPluginImage;
typedef cpPlugins::Interface::ProcessObject TPlugin;
+ typedef TPlugin::TParameter TParameter;
typedef TPlugin::TParameters TParameters;
typedef cpPlugins::Extensions::Visualization::MPRWithDifferentWindows TMPR;
typedef std::map< std::string, std::string > TStringMap;
+ enum PluginType
+ {
+ GlobalPluginType = 0,
+ DoubleClickPluginType,
+ SpherePluginType,
+ NonePluginType
+ };
+
+ enum PluginCategory
+ {
+ SegmentationPluginCategory = 0,
+ SegmentationFilteringPluginCategory,
+ MeshProcessingPluginCategory,
+ NonePluginCategory
+ };
+
public:
explicit MainWnd( QWidget* parent = 0 );
virtual ~MainWnd( );
void _UpdateEnabledFlags( );
bool _ParametersDialog( const TParameters& parameters );
+ void _ExecuteDoubleClickPlugin( const double* pnt );
+
+ template< class P >
+ void _JoinSegmentations( );
/* TODO
template< class I >
// Active plugin
TPlugin* m_ActivePlugin;
QWidget* m_ActiveParameters;
+ Self::PluginType m_ActivePluginType;
+ Self::PluginCategory m_ActivePluginCategory;
+
+ vtkSmartPointer< DoubleClickCommand > m_DoubleClickCommand;
};
#endif // __MAINWND__H__
#include "ui_MainWnd.h"
#include <cstdlib>
+#include <sstream>
#include <QDoubleSpinBox>
#include <QLabel>
+#include <QMessageBox>
+
+#include <itkImageRegionIterator.h>
+#include <itkImageRegionConstIterator.h>
+#define ITK_MANUAL_INSTANTIATION
+#include <itkImage.h>
// -------------------------------------------------------------------------
bool MainWnd::
} // rof
gridLayout->addLayout( verticalLayout, 0, 0, 1, 1 );
+
+ // Infere plugin type
+ TParameters::const_iterator seedIt = parameters.find( "Seed" );
+ TParameters::const_iterator radiusIt = parameters.find( "Radius" );
+ TParameters::const_iterator endIt = parameters.end( );
+ if( seedIt == endIt && radiusIt == endIt )
+ this->m_ActivePluginType = Self::GlobalPluginType;
+ else if( seedIt != endIt && radiusIt == endIt )
+ this->m_ActivePluginType = Self::DoubleClickPluginType;
+ else if( seedIt != endIt && radiusIt != endIt )
+ this->m_ActivePluginType = Self::SpherePluginType;
+ else
+ this->m_ActivePluginType = Self::NonePluginType;
+
QMetaObject::connectSlotsByName( this->m_ActiveParameters );
this->m_ActiveParameters->show( );
- /*
- typedef std::map< std::string, QWidget* > _TWidgets;
- _TWidgets widgets;
- TParameters::const_iterator pIt = parameters.begin( );
- for( ; pIt != parameters.end( ); ++pIt )
- {
- unsigned long pos = pIt->first.find_last_of( ":" );
- std::string v_name = pIt->first.substr( 0, pos );
- std::string v_type = pIt->first.substr( pos + 1 );
- QHBoxLayout* horizontalLayout = new QHBoxLayout( );
- QLabel* label = new QLabel( this->m_ActiveParameters );
- label->setText( QString( v_name.c_str( ) ) );
- horizontalLayout->addWidget( label );
- if( v_type == "real" )
- {
- QDoubleSpinBox* v_double = new QDoubleSpinBox( this->m_ActiveParameters );
- v_double->setDecimals( 3 );
- v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
- v_double->setMaximum( std::numeric_limits< double >::max( ) );
- v_double->setValue( std::atof( pIt->second.c_str( ) ) );
- horizontalLayout->addWidget( v_double );
- widgets[ pIt->first ] = v_double;
- }
- else if( v_type == "atomic_real" )
- {
- if( v_name == "MeshType" )
- {
- QLabel* info = new QLabel( this->m_ActiveParameters );
- if( typeid( TScalar ) == typeid( float ) )
- info->setText( QString( "float" ) );
- else if( typeid( TScalar ) == typeid( double ) )
- info->setText( QString( "double" ) );
- horizontalLayout->addWidget( info );
- widgets[ pIt->first ] = info;
- } // fi
- } // fi
- verticalLayout.addLayout( horizontalLayout );
- } // rof
- gridLayout.addLayout( &verticalLayout, 0, 0, 1, 1 );
- // Buttons box
- QDialogButtonBox buttonBox( this->m_ActiveParameters );
- buttonBox.setOrientation( Qt::Horizontal );
- buttonBox.setStandardButtons(
- QDialogButtonBox::Cancel | QDialogButtonBox::Ok
- );
- gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 );
- QObject::connect(
- &buttonBox, SIGNAL( accepted( ) ),
- this->m_ActiveParameters, SLOT( accept( ) )
- );
- QObject::connect(
- &buttonBox, SIGNAL( rejected( ) ),
- this->m_ActiveParameters, SLOT( reject( ) )
- );
- QMetaObject::connectSlotsByName( this->m_ActiveParameters );
-
- // Execute dialog
- if( dlg.exec( ) == QDialog::Accepted )
- {
- _TWidgets::const_iterator wIt = widgets.begin( );
- for( ; wIt != widgets.end( ); ++wIt )
- {
- unsigned long pos = wIt->first.find_last_of( ":" );
- std::string v_name = wIt->first.substr( 0, pos );
- std::string v_type = wIt->first.substr( pos + 1 );
- std::stringstream sstr;
- if( v_type == "real" )
- {
- QDoubleSpinBox* v_double =
- dynamic_cast< QDoubleSpinBox* >( wIt->second );
- if( v_double != NULL )
- sstr << v_double->value( );
- }
- else if( v_type == "atomic_real" )
- {
- if( v_name == "MeshType" )
+ return( false );
+}
+
+// -------------------------------------------------------------------------
+void MainWnd::
+_ExecuteDoubleClickPlugin( const double* pnt )
+{
+ if(
+ this->m_InputImage == NULL ||
+ this->m_SegmentedImage == NULL ||
+ this->m_ActivePlugin == NULL ||
+ this->m_ActiveParameters == NULL ||
+ this->m_ActivePluginType != Self::DoubleClickPluginType
+ )
+ return;
+
+ TParameters parameters = this->m_ActivePlugin->GetDefaultParameters( );
+
+ // Variable parameters
+ for(
+ TParameters::iterator pIt = parameters.begin( );
+ pIt != parameters.end( );
+ ++pIt
+ )
+ {
+ if( pIt->first != "Seed" )
{
- QLabel* info = dynamic_cast< QLabel* >( wIt->second );
- if( info != NULL )
- sstr << info->text( ).toStdString( );
+ if( pIt->second.first == "double" )
+ {
+ QDoubleSpinBox* v_double = this->m_ActiveParameters->
+ findChild< QDoubleSpinBox* >( pIt->first.c_str( ) );
+ if( v_double != NULL )
+ parameters[ pIt->first ] =
+ TParameter( "double", v_double->text( ).toStdString( ) );
+
+ } // fi
} // fi
- } // fi
- parameters[ wIt->first ] = sstr.str( );
+ } // rof
- } // rof
- return( true );
- }
- */
- return( false );
+ // Seed
+ std::stringstream seed_str;
+ seed_str << pnt[ 0 ] << ":" << pnt[ 1 ] << ":" << pnt[ 2 ];
+ parameters[ "Seed" ] = TParameter( "point", seed_str.str( ) );
+
+ // Execute
+ this->m_ActivePlugin->SetParameters( parameters );
+ this->m_ActivePlugin->SetInput( 0, this->m_InputImage );
+ this->m_ActivePlugin->SetInput( 1, this->m_SegmentedImage );
+ std::string err = this->m_ActivePlugin->Update( );
+ if( err != "" )
+ {
+ QMessageBox::critical( this, tr( "Error caugth!" ), tr( err.c_str( ) ) );
+ return;
+
+ } // fi
+
+ // Join results
+ itk::DataObject* s = this->m_SegmentedImage->GetDataObject( );
+ if( dynamic_cast< itk::Image< char, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< char >( );
+ else if( dynamic_cast< itk::Image< short, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< short >( );
+ else if( dynamic_cast< itk::Image< int, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< int >( );
+ else if( dynamic_cast< itk::Image< long, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< long >( );
+ else if( dynamic_cast< itk::Image< unsigned char, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< unsigned char >( );
+ else if( dynamic_cast< itk::Image< unsigned short, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< unsigned short >( );
+ else if( dynamic_cast< itk::Image< unsigned int, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< unsigned int >( );
+ else if( dynamic_cast< itk::Image< unsigned long, 3 >* >( s ) != NULL )
+ this->_JoinSegmentations< unsigned long >( );
+
+ // Update visualization
+ this->m_SegmentedImage->UpdateVTKImageData( );
+ this->m_MPR->Render( 0 );
+ this->m_MPR->Render( 1 );
+ this->m_MPR->Render( 2 );
}
// -------------------------------------------------------------------------
this->m_SegmentationFilterClasses[ filter_name ]
)
);
+ this->m_ActivePluginCategory = Self::SegmentationFilteringPluginCategory;
// Show parameters dialog
this->_ParametersDialog( this->m_ActivePlugin->GetDefaultParameters( ) );
{
}
+// -------------------------------------------------------------------------
+template< class P >
+void MainWnd::
+_JoinSegmentations( )
+{
+ typedef itk::Image< P, 3 > _TImage;
+
+ _TImage* old_segmentation =
+ dynamic_cast< _TImage* >( this->m_SegmentedImage->GetDataObject( ) );
+ _TImage* new_segmentation =
+ dynamic_cast< _TImage* >(
+ dynamic_cast< TPluginImage* >(
+ this->m_ActivePlugin->GetOutput( 0 )
+ )->GetDataObject( )
+ );
+
+ /* TODO: InPlaceOn does not execute correctly on input image
+ typedef itk::AndImageFilter< _TImage, _TImage, _TImage > _TFilter;
+ typename _TFilter::Pointer filter = _TFilter::New( );
+ filter->InPlaceOn( );
+ filter->SetInput( 0, old_segmentation );
+ filter->SetInput( 1, new_segmentation );
+ filter->Update( );
+ //old_segmentation->DisconnectPipeline( );
+
+ std::cout << old_segmentation->GetRequestedRegion( ) << std::endl;
+ std::cout << new_segmentation->GetRequestedRegion( ) << std::endl;
+ std::cout << old_segmentation->GetBufferedRegion( ) << std::endl;
+ std::cout << new_segmentation->GetBufferedRegion( ) << std::endl;
+ */
+ typedef itk::ImageRegionConstIterator< _TImage > _TConstIt;
+ typedef itk::ImageRegionIterator< _TImage > _TIt;
+ _TConstIt nIt( new_segmentation, new_segmentation->GetRequestedRegion( ) );
+ _TIt oIt( old_segmentation, old_segmentation->GetRequestedRegion( ) );
+ nIt.GoToBegin( );
+ oIt.GoToBegin( );
+ for( ; !nIt.IsAtEnd( ); ++nIt, ++oIt )
+ oIt.Set( nIt.Get( ) | oIt.Get( ) );
+}
+
+// -------------------------------------------------------------------------
+DoubleClickCommand* DoubleClickCommand::
+New( )
+{
+ return( new DoubleClickCommand( ) );
+}
+
+// -------------------------------------------------------------------------
+void DoubleClickCommand::
+SetMainWnd( MainWnd* wnd )
+{
+ this->m_MainWnd = wnd;
+}
+
+// -------------------------------------------------------------------------
+void DoubleClickCommand::
+Execute( vtkObject* caller, unsigned long eid, void* data )
+{
+ if( this->m_MainWnd != NULL )
+ this->m_MainWnd->_ExecuteDoubleClickPlugin(
+ reinterpret_cast< const double* >( data )
+ );
+}
+
+// -------------------------------------------------------------------------
+DoubleClickCommand::
+DoubleClickCommand( )
+ : Superclass( ),
+ m_MainWnd( NULL )
+{
+}
+
+// -------------------------------------------------------------------------
+DoubleClickCommand::
+~DoubleClickCommand( )
+{
+}
+
// eof - $RCSfile$
);
// Historic objects
-
-
-
- /*
- this->m_ImageReaderClassName = "";
- this->m_ImageSeriesReaderClassName = "";
- this->m_ImageWriterClassName = "";
-
- if( in )
- {
- std::string plugin;
- std::getline( in, plugin );
- while( !( in.eof( ) ) )
- {
- if( this->m_Plugins.Load( plugin ) )
- {
- TPluginsInterface::TClassesIterator cIt =
- this->m_Plugins.GetClasses( ).begin( );
- TPluginsInterface::TClassesIterator end_cIt =
- this->m_Plugins.GetClasses( ).end( );
- for( ; cIt != end_cIt; ++cIt )
- {
- std::string c_name = cIt->first;
- c_name = c_name.substr( c_name.find_last_of( ":" ) + 1 );
- if( c_name == "ImageReader" )
- {
- this->m_ImageReaderClassName = cIt->first;
- }
- else if( c_name == "ImageSeriesReader" )
- {
- this->m_ImageSeriesReaderClassName = cIt->first;
- }
- else if( c_name == "ImageWriter" )
- {
- this->m_ImageWriterClassName = cIt->first;
- }
- else
- {
- } // fi
-
- } // rof
-
- TFilterPlugins::TClassesIterator cIt =
- this->m_Plugins.BeginClasses( );
- for( ; cIt != this->m_Plugins.EndClasses( ); ++cIt )
- {
- TFilterObject* filter =
- this->m_Plugins.CreateObject( cIt->first );
- if( filter == NULL )
- continue;
- std::string cat = filter->GetCategory( );
- std::string catType = cat.substr( cat.find_last_of( ":" ) );
- if( catType == ":BinaryImageToBinaryImageFilter" )
- {
- QAction* action = this->m_UI->menuFilterSegmentedImage->
- addAction( QString( cIt->first.c_str( ) ) );
- QObject::connect(
- action, SIGNAL( triggered( ) ),
- this, SLOT( triggered_aFilterSegmentedImage( ) )
- );
- }
- else if( catType == ":ImageToMeshFilter" )
- {
- QAction* action = this->m_UI->menuExtractMesh->
- addAction( QString( cIt->first.c_str( ) ) );
- QObject::connect(
- action, SIGNAL( triggered( ) ),
- this, SLOT( triggered_aSegmentedImageToMesh( ) )
- );
-
- } // fi
- delete filter;
- } // rof
- }
- else
- {
- QMessageBox::warning(
- this,
- tr( "Ignoring plugin" ),
- tr( plugin.c_str( ) )
- );
-
- } // fi
- std::getline( in, plugin );
-
- } // elihw
- }
- else
- {
- QMessageBox::critical(
- this,
- tr( "No plugins file loaded!" ),
- tr( this->m_PluginsConfigurationFile.c_str( ) )
- );
-
- } // fi
- in.close( );
-
- if( this->m_ImageReaderClassName == "" )
- {
- QMessageBox::critical(
- this,
- tr( "No ImageReader found in plugins!" ),
- tr( this->m_PluginsConfigurationFile.c_str( ) )
- );
-
- } // fi
-
- if( this->m_ImageWriterClassName == "" )
- {
- QMessageBox::critical(
- this,
- tr( "No ImageWriter found in plugins!" ),
- tr( this->m_PluginsConfigurationFile.c_str( ) )
- );
-
- } // fi
- this->_UpdateEnabledFlags( );
- */
- }
+}
// -------------------------------------------------------------------------
bool MainWnd::
#include <cpm/Plugins/SimpleFillRegion.h>
+#include <cpPlugins/Interface/Image.h>
+
+#include <itkBinaryThresholdImageFunction.h>
+#include <itkFloodFilledImageFunctionConditionalConstIterator.h>
+
+#define ITK_MANUAL_INSTANTIATION
+#include <itkImage.h>
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Dimension( r, d, i1, i2, f ) \
+ if( \
+ dynamic_cast< itk::ImageBase< d >* >( i1 ) != NULL && \
+ dynamic_cast< itk::ImageBase< d >* >( i2 ) != NULL \
+ ) \
+ r = this->f< d >( )
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Pixel1( r, p, d, i, f ) \
+ if( dynamic_cast< itk::Image< p, d >* >( i ) != NULL ) \
+ r = this->f< p, d >( )
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Pixel2( r, p1, p2, d, i, f ) \
+ if( dynamic_cast< itk::Image< p2, d >* >( i ) != NULL ) \
+ r = this->f< p1, p2, d >( )
// -------------------------------------------------------------------------
cpm::Plugins::SimpleFillRegion::
: Superclass( )
{
this->SetNumberOfInputs( 2 );
+ this->SetNumberOfOutputs( 1 );
+ this->_MakeOutput< cpPlugins::Interface::Image >( 0 );
this->m_DefaultParameters[ "MinDelta" ] = TParameter( "double", "0" );
this->m_DefaultParameters[ "MaxDelta" ] = TParameter( "double", "0" );
std::string cpm::Plugins::SimpleFillRegion::
_GenerateData( )
{
- std::cout << "Simple fill region" << std::endl;
+ itk::DataObject* i1 = this->_GetInput( 0 );
+ itk::DataObject* i2 = this->_GetInput( 1 );
+
+ std::string r =
+ "cpm::Plugins::SimpleFillRegion: itk::Image(s) dimensions not supported";
+ cpmPlugins_SimpleFillRegion_Dimension( r, 2, i1, i2, _GD0 );
+ else cpmPlugins_SimpleFillRegion_Dimension( r, 3, i1, i2, _GD0 );
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int D >
+std::string cpm::Plugins::SimpleFillRegion::
+_GD0( )
+{
+ typedef itk::ImageBase< D > _TImage;
+
+ _TImage* i1 = dynamic_cast< _TImage* >( this->_GetInput( 0 ) );
+
+ std::string r =
+ "cpm::Plugins::SimpleFillRegion: first image's pixel type not supported";
+ cpmPlugins_SimpleFillRegion_Pixel1( r, char, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, short, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, int, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, long, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned char, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned short, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned int, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned long, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, float, D, i1, _GD1 );
+ else cpmPlugins_SimpleFillRegion_Pixel1( r, double, D, i1, _GD1 );
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class P1, unsigned int D >
+std::string cpm::Plugins::SimpleFillRegion::
+_GD1( )
+{
+ typedef itk::ImageBase< D > _TImage;
+
+ _TImage* i2 = dynamic_cast< _TImage* >( this->_GetInput( 1 ) );
+
+ std::string r =
+ "cpm::Plugins::SimpleFillRegion: second image's pixel type not supported";
+ cpmPlugins_SimpleFillRegion_Pixel2( r, P1, char, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, short, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, int, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, long, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned char, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned short, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned int, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned long, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, float, D, i2, _GD2 );
+ else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, double, D, i2, _GD2 );
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< typename I1, class I2, typename TCoordRep >
+class SimpleFillRegionFunction
+ : public itk::BinaryThresholdImageFunction< I1, TCoordRep >
+{
+public:
+ typedef SimpleFillRegionFunction Self;
+ typedef itk::BinaryThresholdImageFunction< I1, TCoordRep > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ itkTypeMacro( SimpleFillRegionFunction, itkBinaryThresholdImageFunction );
+ itkNewMacro( Self );
+
+ itkSetConstObjectMacro( InputSegmentation, I2 );
+
+ typedef typename Superclass::InputImageType InputImageType;
+ typedef typename I1::PixelType PixelType;
+ itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);
+ typedef typename Superclass::PointType PointType;
+ typedef typename Superclass::IndexType IndexType;
+ typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
+
+ virtual bool EvaluateAtIndex( const IndexType& index ) const
+ {
+ bool cont = true;
+ if( this->m_InputSegmentation.IsNotNull( ) )
+ cont = (
+ this->m_InputSegmentation->GetPixel( index ) ==
+ ( typename I2::PixelType )( 0 )
+ );
+ if( cont )
+ return( this->Superclass::EvaluateAtIndex( index ) );
+ else
+ return( false );
+ }
+
+protected:
+ SimpleFillRegionFunction( )
+ : Superclass( )
+ {
+ }
+ virtual ~SimpleFillRegionFunction( )
+ {
+ }
+
+private:
+ // Purposely not implemented
+ SimpleFillRegionFunction( const Self& );
+ Self& operator=( const Self& );
+
+protected:
+ typename I2::ConstPointer m_InputSegmentation;
+};
+
+// -------------------------------------------------------------------------
+template< class P1, class P2, unsigned int D >
+std::string cpm::Plugins::SimpleFillRegion::
+_GD2( )
+{
+ typedef itk::Image< P1, D > _TImage1;
+ typedef itk::Image< P2, D > _TImage2;
+
+ _TImage1* i1 = dynamic_cast< _TImage1* >( this->_GetInput( 0 ) );
+ _TImage2* i2 = dynamic_cast< _TImage2* >( this->_GetInput( 1 ) );
+
+ // Transform input seed
+ typename _TImage1::PointType pnt;
+ TParameters::const_iterator sIt;
+ sIt = this->m_Parameters.find( "Seed" );
+ if( sIt == this->m_Parameters.end( ) )
+ return( "cpm::Plugins::SimpleFillRegion: no seed given." );
+ char* buff = new char[ sIt->second.second.size( ) + 1 ];
+ std::memcpy( buff, sIt->second.second.c_str( ), sIt->second.second.size( ) );
+ buff[ sIt->second.second.size( ) ] = '\0';
+ char* tok = std::strtok( buff, ":" );
+ for( unsigned int d = 0; d < D; ++d )
+ {
+ pnt[ d ] = std::atof( tok );
+ tok = std::strtok( NULL, ":" );
+
+ } // rof
+ delete [] buff;
+ typename _TImage1::IndexType idx;
+ if( !( i1->TransformPhysicalPointToIndex( pnt, idx ) ) )
+ return( "cpm::Plugins::SimpleFillRegion: seed is outside image regions." );
+
+ // Check spatial compatilibity
+ if( i1->GetLargestPossibleRegion( ) != i2->GetLargestPossibleRegion( ) )
+ return( "cpm::Plugins::SimpleFillRegion: incompatible regions." );
+ if( i1->GetSpacing( ) != i2->GetSpacing( ) )
+ return( "cpm::Plugins::SimpleFillRegion: incompatible spacings." );
+ if( i1->GetOrigin( ) != i2->GetOrigin( ) )
+ return( "cpm::Plugins::SimpleFillRegion: incompatible origins." );
+ if( i1->GetDirection( ) != i2->GetDirection( ) )
+ return( "cpm::Plugins::SimpleFillRegion: incompatible directions." );
+
+ // Create output
+ cpPlugins::Interface::Image* out_obj =
+ dynamic_cast< cpPlugins::Interface::Image* >( this->GetOutput( 0 ) );
+ typename _TImage2::Pointer out =
+ dynamic_cast< _TImage2* >( out_obj->GetDataObject( ) );
+ if( out.IsNull( ) )
+ {
+ out = _TImage2::New( );
+ this->_SetOutput( 0, out );
+
+ } // fi
+
+ // Create memory, if needed
+ if(
+ i1->GetLargestPossibleRegion( ) != out->GetLargestPossibleRegion( ) ||
+ i1->GetSpacing( ) != out->GetSpacing( ) ||
+ i1->GetOrigin( ) != out->GetOrigin( ) ||
+ i1->GetDirection( ) != out->GetDirection( )
+ )
+ {
+ out->SetLargestPossibleRegion( i1->GetLargestPossibleRegion( ) );
+ out->SetRequestedRegion( i1->GetRequestedRegion( ) );
+ out->SetBufferedRegion( i1->GetBufferedRegion( ) );
+ out->SetDirection( i1->GetDirection( ) );
+ out->SetOrigin( i1->GetOrigin( ) );
+ out->SetSpacing( i1->GetSpacing( ) );
+ out->Allocate( );
+
+ } // fi
+ out->FillBuffer( P2( 0 ) );
+
+ P1 min_delta = P1( std::atof( this->m_Parameters[ "MinDelta" ].second.c_str( ) ) );
+ P1 max_delta = P1( std::atof( this->m_Parameters[ "MaxDelta" ].second.c_str( ) ) );
+ P1 lower = i1->GetPixel( idx ) - min_delta;
+ P1 upper = i1->GetPixel( idx ) + min_delta;
+
+ typedef SimpleFillRegionFunction< _TImage1, _TImage2, double > _TFunction;
+ typename _TFunction::Pointer f = _TFunction::New( );
+ f->SetInputImage( i1 );
+ f->SetInputSegmentation( i2 );
+ f->ThresholdBetween( lower, upper );
+
+ typedef
+ itk::FloodFilledImageFunctionConditionalConstIterator< _TImage1, _TFunction >
+ _TIterator;
+ _TIterator fIt( i1, f, idx );
+ for( fIt.GoToBegin( ); !fIt.IsAtEnd( ); ++fIt )
+ out->SetPixel( fIt.GetIndex( ), 1 );
+
+ return( "" );
}
// eof - $RCSfile$
protected:
virtual std::string _GenerateData( );
+ template< unsigned int D >
+ std::string _GD0( );
+
+ template< class P1, unsigned int D >
+ std::string _GD1( );
+
+ template< class P1, class P2, unsigned int D >
+ std::string _GD2( );
+
protected:
itk::ProcessObject::Pointer m_Filter;
};