#include "MainWnd.h" #include "ui_MainWnd.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #include "ui_SegmentationParametersDlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include */ // ------------------------------------------------------------------------- #define IDMS_QT_ACTION( action ) \ QObject::connect( \ this->m_UI->a##action, SIGNAL( triggered( ) ), \ this, SLOT( triggered_a##action( ) ) \ ) // ------------------------------------------------------------------------- MainWnd::MainWnd( QWidget* parent ) : QMainWindow( parent ), m_UI( new Ui::MainWnd ) { this->m_UI->setupUi( this ); // Configure strings this->m_LastOpenedFile = "."; this->m_PluginsConfigurationFile = "idms.plugins"; // Create and associate renderers this->m_3DRenderer = vtkSmartPointer< vtkRenderer >::New( ); this->m_XPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); this->m_YPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); this->m_ZPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( ); this->m_AuxRenderer = vtkSmartPointer< vtkRenderer >::New( ); this->m_3DRenderer->SetBackground( 0.2, 0.2, 0.2 ); this->m_XPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); this->m_YPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); this->m_ZPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 ); this->m_AuxRenderer->SetBackground( 0.1, 0.3, 0.8 ); this->m_UI->m_3DVTK->GetRenderWindow( )-> AddRenderer( this->m_3DRenderer ); this->m_UI->m_XPlaneVTK->GetRenderWindow( )-> AddRenderer( this->m_XPlaneRenderer ); this->m_UI->m_YPlaneVTK->GetRenderWindow( )-> AddRenderer( this->m_YPlaneRenderer ); this->m_UI->m_ZPlaneVTK->GetRenderWindow( )-> AddRenderer( this->m_ZPlaneRenderer ); this->m_UI->m_AuxVTK->GetRenderWindow( )-> AddRenderer( this->m_AuxRenderer ); // Configure MPR actors this->m_ImageActors = vtkSmartPointer< idms::VolumeActors >::New( ); // Interaction styles this->m_XStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( ); this->m_YStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( ); this->m_ZStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( ); this->m_XStyle->Configure( this->m_ImageActors, 0 ); this->m_YStyle->Configure( this->m_ImageActors, 1 ); this->m_ZStyle->Configure( this->m_ImageActors, 2 ); this->m_UI->m_XPlaneVTK->GetInteractor( )-> SetInteractorStyle( this->m_XStyle ); this->m_UI->m_YPlaneVTK->GetInteractor( )-> SetInteractorStyle( this->m_YStyle ); this->m_UI->m_ZPlaneVTK->GetInteractor( )-> SetInteractorStyle( this->m_ZStyle ); /* vtkSmartPointer< vtkCallbackCommand > z_callback = vtkSmartPointer< vtkCallbackCommand >::New( ); z_callback->SetCallback( MainWnd::_SliceEventCallback ); z_callback->SetClientData( this ); zstyle->AddObserver( idms::InteractorStyleImage::SliceEvent, z_callback ); // Orientation marks vtkSmartPointer< vtkAnnotatedCubeActor > oCube = vtkSmartPointer< vtkAnnotatedCubeActor >::New( ); oCube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 ); oCube->GetTextEdgesProperty( )->SetLineWidth( 1 ); oCube->GetTextEdgesProperty( )->SetDiffuse( 0 ); oCube->GetTextEdgesProperty( )->SetAmbient( 1 ); oCube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 ); oCube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 ); oCube->GetXPlusFaceProperty( )->SetInterpolationToFlat( ); oCube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 ); oCube->GetXMinusFaceProperty( )->SetInterpolationToFlat( ); oCube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 ); oCube->GetYPlusFaceProperty( )->SetInterpolationToFlat( ); oCube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 ); oCube->GetYMinusFaceProperty( )->SetInterpolationToFlat( ); oCube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 ); oCube->GetZPlusFaceProperty( )->SetInterpolationToFlat( ); oCube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 ); oCube->GetZMinusFaceProperty( )->SetInterpolationToFlat( ); vtkSmartPointer< vtkAxesActor > oAxes = vtkSmartPointer< vtkAxesActor >::New( ); oAxes->AxisLabelsOff( ); oAxes->SetShaftTypeToCylinder( ); oAxes->SetTotalLength( 2.5, 2.5, 2.5 ); vtkSmartPointer< vtkPropAssembly > oActors = vtkSmartPointer< vtkPropAssembly >::New( ); oActors->AddPart( oCube ); oActors->AddPart( oAxes ); this->m_3DOrientationWidget = vtkSmartPointer< vtkOrientationMarkerWidget >::New( ); this->m_3DOrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 ); this->m_3DOrientationWidget->SetOrientationMarker( oActors ); this->m_3DOrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 ); // Add actors, widgets, stuff, ... this->m_3DOrientationWidget-> SetInteractor( this->m_UI->m_3DVTK->GetInteractor( ) ); this->m_3DOrientationWidget->SetEnabled( 1 ); this->m_3DOrientationWidget->InteractiveOff( ); IDMS_QT_ACTION( aLoadInputImage ); IDMS_QT_ACTION( aLoadSegmentedImage ); */ // Qt signals <-> slots QObject::connect( this->m_UI->aNavigation, SIGNAL( triggered( ) ), this, SLOT( triggered_aSwitchMode( ) ) ); QObject::connect( this->m_UI->aSegmentationInteractiveDeformation, SIGNAL( triggered( ) ), this, SLOT( triggered_aSwitchMode( ) ) ); IDMS_QT_ACTION( OpenInputImage ); IDMS_QT_ACTION( OpenSegmentedImage ); IDMS_QT_ACTION( ReloadPlugins ); // Start: load all disponible plugins this->triggered_aReloadPlugins( ); } // ------------------------------------------------------------------------- MainWnd:: ~MainWnd( ) { delete this->m_UI; } // ------------------------------------------------------------------------- void MainWnd:: _UpdateEnabledFlags( ) { bool img = this->m_Image.IsNotNull( ); this->m_UI->menuSegmentInputImage->setEnabled( img ); this->m_UI->aOpenSegmentedImage->setEnabled( img ); this->m_UI->m_3DVTK->setEnabled( img ); this->m_UI->m_XPlaneVTK->setEnabled( img ); this->m_UI->m_YPlaneVTK->setEnabled( img ); this->m_UI->m_ZPlaneVTK->setEnabled( img ); this->m_UI->m_AuxVTK->setEnabled( img ); bool seg = this->m_Segmentation.IsNotNull( ); this->m_UI->menuFilterSegmentedImage->setEnabled( seg ); this->m_UI->menuExtractMesh->setEnabled( seg ); this->m_UI->aOpenMesh->setEnabled( seg ); this->m_UI->aNavigation->setEnabled( img && seg ); this->m_UI->aSegmentationInteractiveDeformation->setEnabled( img && seg ); /* TODO menuProcessMesh */ } // ------------------------------------------------------------------------- bool MainWnd:: _ParametersDialog( TParameters& parameters ) { QDialog dlg( this ); QGridLayout gridLayout( &dlg ); QVBoxLayout verticalLayout; // Put values 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( &dlg ); label->setText( QString( v_name.c_str( ) ) ); horizontalLayout->addWidget( label ); if( v_type == "real" ) { QDoubleSpinBox* v_double = new QDoubleSpinBox( &dlg ); 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( &dlg ); 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( &dlg ); buttonBox.setOrientation( Qt::Horizontal ); buttonBox.setStandardButtons( QDialogButtonBox::Cancel | QDialogButtonBox::Ok ); gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 ); QObject::connect( &buttonBox, SIGNAL( accepted( ) ), &dlg, SLOT( accept( ) ) ); QObject::connect( &buttonBox, SIGNAL( rejected( ) ), &dlg, SLOT( reject( ) ) ); QMetaObject::connectSlotsByName( &dlg ); // 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" ) { QLabel* info = dynamic_cast< QLabel* >( wIt->second ); if( info != NULL ) sstr << info->text( ).toStdString( ); } // fi } // fi parameters[ wIt->first ] = sstr.str( ); } // rof return( true ); } return( false ); } // ------------------------------------------------------------------------- template< class I > bool MainWnd:: _LoadImage( typename I::Pointer& image ) { QStringList qList = QFileDialog::getOpenFileNames( this, tr( "Open an image" ), tr( this->m_LastOpenedFile.c_str( ) ), tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" ) ); if( qList.size( ) == 0 ) return( false ); bool ret = true; QStringList::Iterator fIt = qList.begin( ); if( qList.size( ) == 1 ) { // Read a single image std::string fn = fIt->toStdString( ); this->m_LastOpenedFile = fn; typename itk::ImageFileReader< I >::Pointer reader = itk::ImageFileReader< I >::New( ); reader->SetFileName( fn ); try { reader->Update( ); } catch( itk::ExceptionObject& err ) { QMessageBox::critical( this, tr( "Error opening single image!" ), tr( err.GetDescription( ) ) ); ret = false; } // yrt image = reader->GetOutput( ); image->DisconnectPipeline( ); } else if( qList.size( ) > 1 ) { typedef std::set< std::string > _TOrderedStringList; // Read a slice set _TOrderedStringList filenames; for( ; fIt != qList.end( ); ++fIt ) filenames.insert( fIt->toStdString( ) ); typename itk::ImageSeriesReader< I >::Pointer reader = itk::ImageSeriesReader< I >::New( ); reader->SetImageIO( itk::GDCMImageIO::New( ) ); _TOrderedStringList::const_iterator oIt = filenames.begin( ); for( ; oIt != filenames.end( ); ++oIt ) { reader->AddFileName( *oIt ); this->m_LastOpenedFile = *oIt; } // rof try { reader->Update( ); } catch( itk::ExceptionObject& err ) { QMessageBox::critical( this, tr( "Error opening image series!" ), tr( err.GetDescription( ) ) ); ret = false; } // yrt image = reader->GetOutput( ); image->DisconnectPipeline( ); } // fi return( ret ); } // ------------------------------------------------------------------------- void MainWnd:: triggered_aSwitchMode( ) { QAction* snd = dynamic_cast< QAction* >( this->sender( ) ); if( snd == this->m_UI->aNavigation ) { this->m_UI->aSegmentationInteractiveDeformation->setChecked( !( this->m_UI->aNavigation->isChecked( ) ) ); } else if( snd == this->m_UI->aSegmentationInteractiveDeformation ) { this->m_UI->aNavigation->setChecked( !( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) ) ); } else { this->m_UI->aNavigation->setChecked( true ); this->m_UI->aSegmentationInteractiveDeformation->setChecked( false ); } // fi if( this->m_UI->aNavigation->isChecked( ) ) { this->m_XStyle->SetModeToNavigation( ); this->m_YStyle->SetModeToNavigation( ); this->m_ZStyle->SetModeToNavigation( ); this->m_ImageActors->HideRegion( 0 ); this->m_ImageActors->HideRegion( 1 ); this->m_ImageActors->HideRegion( 2 ); this->m_3DRenderer->RemoveActor( this->m_ImageActors->GetCursorActor( ) ); this->m_3DRenderer->RemoveActor( this->m_ImageActors->GetRegionActor( ) ); this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); } else if( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) ) { this->m_XStyle->SetModeToDeformation( ); this->m_YStyle->SetModeToDeformation( ); this->m_ZStyle->SetModeToDeformation( ); this->m_ImageActors->ShowRegion( 0 ); this->m_ImageActors->ShowRegion( 1 ); this->m_ImageActors->ShowRegion( 2 ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetCursorActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetRegionActor( ) ); this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: triggered_aReloadPlugins( ) { this->m_FilterPlugins.UnloadAll( ); std::ifstream in( this->m_PluginsConfigurationFile.c_str( ) ); if( in ) { std::string plugin; std::getline( in, plugin ); while( !( in.eof( ) ) ) { if( this->m_FilterPlugins.Load( plugin ) ) { TFilterPlugins::TClassesIterator cIt = this->m_FilterPlugins.BeginClasses( ); for( ; cIt != this->m_FilterPlugins.EndClasses( ); ++cIt ) { TFilterObject* filter = this->m_FilterPlugins.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 std::cerr << std::endl << "Ignoring \"" << plugin << "\"" << std::endl; std::getline( in, plugin ); } // elihw } else { QMessageBox::critical( this, tr( "No plugins file loaded!" ), tr( "No plugins file loaded!" ) ); } // fi in.close( ); this->_UpdateEnabledFlags( ); } // ------------------------------------------------------------------------- void MainWnd:: triggered_aOpenInputImage( ) { if( this->_LoadImage< TImage >( this->m_Image ) ) { // Connect image to VTK this->m_VTKImage = TVTKImage::New( ); this->m_VTKImage->SetInput( this->m_Image ); this->m_VTKImage->Update( ); this->m_ImageActors->Configure( this->m_VTKImage->GetOutput( ), this->m_UI->m_XPlaneVTK->GetInteractor( ), this->m_UI->m_YPlaneVTK->GetInteractor( ), this->m_UI->m_ZPlaneVTK->GetInteractor( ) ); this->m_ImageActors-> AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) ); // Associate actors this->m_3DRenderer->AddActor( this->m_ImageActors->GetImageOutlineActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetXBoundsActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetYBoundsActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetZBoundsActor( ) ); // Reset all cameras this->m_3DRenderer->ResetCamera( ); this->m_ImageActors->ResetCameras( ); // Ok, start! this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( ); this->_UpdateEnabledFlags( ); this->m_UI->aNavigation->setChecked( true ); this->triggered_aSwitchMode( ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: triggered_aOpenSegmentedImage( ) { if( this->_LoadImage< TImage >( this->m_Segmentation ) ) { // Connect image to VTK this->m_VTKSegmentation = TVTKImage::New( ); this->m_VTKSegmentation->SetInput( this->m_Segmentation ); this->m_VTKSegmentation->Update( ); this->m_ImageActors->SetSegmentation( this->m_VTKSegmentation->GetOutput( ) ); // Ok, start! this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( ); this->_UpdateEnabledFlags( ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: triggered_aFilterSegmentedImage( ) { // Get filter name if( this->m_Segmentation.IsNull( ) ) return; QAction* action = dynamic_cast< QAction* >( this->sender( ) ); if( action == NULL ) return; std::string filter_name = action->text( ).toStdString( ); // Create filter TFilterObject* filter = this->m_FilterPlugins.CreateObject( filter_name ); if( filter == NULL ) return; TParameters parameters = filter->GetDefaultParameters( ); if( !( this->_ParametersDialog( parameters ) ) ) return; filter->SetInput( this->m_Segmentation ); filter->SetParameters( parameters ); std::string result = filter->Update( ); // Get modified segmentation /* TODO this->m_Mesh = filter->GetCastedOutput< TMesh >( ); if( this->m_Mesh.IsNotNull( ) ) { this->m_Mesh->DisconnectPipeline( ); } // fi */ // Ok, it seems to have runned fine delete filter; } // ------------------------------------------------------------------------- void MainWnd:: triggered_aSegmentedImageToMesh( ) { // Get filter name if( this->m_Segmentation.IsNull( ) ) return; QAction* action = dynamic_cast< QAction* >( this->sender( ) ); if( action == NULL ) return; std::string filter_name = action->text( ).toStdString( ); // Create filter TFilterObject* filter = this->m_FilterPlugins.CreateObject( filter_name ); if( filter == NULL ) return; TParameters parameters = filter->GetDefaultParameters( ); if( !( this->_ParametersDialog( parameters ) ) ) return; filter->SetInput( this->m_Segmentation ); filter->SetParameters( parameters ); std::string result = filter->Update( ); // Get mesh this->m_Mesh = filter->GetCastedOutput< TMesh >( ); if( this->m_Mesh.IsNotNull( ) ) { this->m_Mesh->DisconnectPipeline( ); } // fi // Ok, it seems to have runned fine delete filter; } // ------------------------------------------------------------------------- /* void MainWnd:: _SliceMesh( int axis ) { TCutter* cutter = NULL; if( axis == 2 ) cutter = this->m_ZCutter; if( cutter == NULL ) return; vtkPlane* vplane = this->m_ImageActors->GetSlicePlane( axis ); double vorigin[ 3 ], vnormal[ 3 ]; vplane->GetOrigin( vorigin ); vplane->GetNormal( vnormal ); TCutter::TVector corigin, cnormal; corigin[ 0 ] = TScalar( vorigin[ 0 ] ); corigin[ 1 ] = TScalar( vorigin[ 1 ] ); corigin[ 2 ] = TScalar( vorigin[ 2 ] ); cnormal[ 0 ] = TScalar( vnormal[ 0 ] ); cnormal[ 1 ] = TScalar( vnormal[ 1 ] ); cnormal[ 2 ] = TScalar( vnormal[ 2 ] ); cutter->SetPlanePoint( corigin ); cutter->SetPlaneNormal( cnormal ); cutter->Update( ); } // ------------------------------------------------------------------------- void MainWnd:: _SliceEventCallback( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ) { if( clientData == NULL || callData == NULL ) return; MainWnd* wnd = reinterpret_cast< MainWnd* >( clientData ); int axis = *( reinterpret_cast< int* >( callData ) ); if( wnd == NULL ) return; if( eventId == idms::InteractorStyleImage::SliceEvent ) wnd->_SliceMesh( axis ); } // ------------------------------------------------------------------------- void MainWnd:: triggered_aLoadImage( ) { if( this->_LoadImage< TImage >( this->m_Image ) ) { // Connect image to VTK this->m_VTKImage->SetInput( this->m_Image ); this->m_VTKImage->Update( ); this->m_ImageActors->Configure( this->m_VTKImage->GetOutput( ), this->m_UI->m_XPlaneVTK->GetInteractor( ), this->m_UI->m_YPlaneVTK->GetInteractor( ), this->m_UI->m_ZPlaneVTK->GetInteractor( ) ); this->m_ImageActors-> AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) ); // Associate actors this->m_3DRenderer->AddActor( this->m_ImageActors->GetImageOutlineActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetXBoundsActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetYBoundsActor( ) ); this->m_3DRenderer->AddActor( this->m_ImageActors->GetZBoundsActor( ) ); // Reset all cameras this->m_3DRenderer->ResetCamera( ); this->m_ImageActors->ResetCameras( ); // Ok, start! this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( ); this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( ); // Activate controls this->m_UI->aLoadSegmentedImage->setEnabled( true ); this->m_UI->aSegmentImage->setEnabled( true ); this->m_UI->m_3DVTK->setEnabled( true ); this->m_UI->m_XPlaneVTK->setEnabled( true ); this->m_UI->m_YPlaneVTK->setEnabled( true ); this->m_UI->m_ZPlaneVTK->setEnabled( true ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: triggered_aLoadSegmentedImage( ) { if( this->m_Mesh.IsNotNull( ) ) { QMessageBox::critical( this, tr( "Mesh already loaded!" ), tr( "Mesh already loaded!" ) ); return; } // fi if( this->_LoadImage< TImage >( this->m_Segmentation ) ) { // Compute segmentation values itk::MinimumMaximumImageCalculator< TImage >::Pointer minmax = itk::MinimumMaximumImageCalculator< TImage >::New( ); minmax->SetImage( this->m_Segmentation ); minmax->Compute( ); TPixel min_v = minmax->GetMinimum( ); TPixel max_v = minmax->GetMaximum( ); double thr = double( max_v + min_v ) / double( 2 ); typedef itk::Image< TScalar, Dimension > _TScalarImage; typedef itk::BinaryMinMaxCurvatureFlowImageFilter< TImage, _TScalarImage > _TFilter; typedef _TFilter::TimeStepType _TTimeStep; typedef _TFilter::RadiusValueType _TRadius; _TFilter::Pointer filter = _TFilter::New( ); filter->SetInput( this->m_Segmentation ); filter->SetTimeStep( _TTimeStep( 0.0625 ) ); filter->SetNumberOfIterations( 10 ); filter->SetStencilRadius( _TRadius( 3 ) ); filter->SetThreshold( thr ); filter->Update( ); itk::ImageFileWriter< _TScalarImage >::Pointer w = itk::ImageFileWriter< _TScalarImage >::New( ); w->SetInput( filter->GetOutput( ) ); w->SetFileName( "no_noise.mhd" ); w->Update( ); std::exit( 1 ); typedef itk::LaplacianRecursiveGaussianImageFilter< TImage, _TScalarImage > _TFilter; _TFilter::Pointer filter = _TFilter::New( ); filter->SetInput( this->m_Segmentation ); filter->SetSigma( 3 ); // in spacing units filter->SetNormalizeAcrossScale( false ); typedef itk::ThresholdImageFilter< _TScalarImage > _TThreshold; _TThreshold::Pointer threshold = _TThreshold::New( ); threshold->SetInput( filter->GetOutput( ) ); threshold->ThresholdAbove( TScalar( 0 ) ); threshold->InPlaceOff( ); threshold->Update( ); itk::MinimumMaximumImageCalculator< _TScalarImage >::Pointer t_minmax = itk::MinimumMaximumImageCalculator< _TScalarImage >::New( ); t_minmax->SetImage( threshold->GetOutput( ) ); t_minmax->Compute( ); TScalar min_t = t_minmax->GetMinimum( ); std::cout << min_t << " " << t_minmax->GetMaximum( ) << std::endl; itk::SubtractImageFilter< _TScalarImage >::Pointer subtract = itk::SubtractImageFilter< _TScalarImage >::New( ); subtract->SetInput1( threshold->GetOutput( ) ); subtract->SetConstant2( min_t ); itk::ImageFileWriter< _TScalarImage >::Pointer w = itk::ImageFileWriter< _TScalarImage >::New( ); w->SetInput( subtract->GetOutput( ) ); w->SetFileName( "no_noise_laplace_2.mhd" ); w->Update( ); std::exit( 1 ); // Pass segmentation to VTK this->m_VTKSegmentation = TVTKImage::New( ); this->m_VTKSegmentation->SetInput( this->m_Segmentation ); this->m_VTKSegmentation->Update( ); // Use VTK's marching cubes (it is smoother) vtkSmartPointer< vtkImageMarchingCubes > segmentation_mc = vtkSmartPointer< vtkImageMarchingCubes >::New( ); segmentation_mc->SetInputData( this->m_VTKSegmentation->GetOutput( ) ); segmentation_mc->SetValue( 0, thr ); segmentation_mc->Update( ); // Go back to ITK world typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > _TVTKPDataToMesh; _TVTKPDataToMesh::Pointer itk_mc = _TVTKPDataToMesh::New( ); itk_mc->SetInput( segmentation_mc->GetOutput( ) ); itk_mc->Update( ); this->m_Mesh = itk_mc->GetOutput( ); this->m_Mesh->DisconnectPipeline( ); this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( ); this->m_MeshActor = vtkSmartPointer< vtkActor >::New( ); this->m_MeshMapper->SetInputData( this->m_Mesh ); this->m_MeshActor->SetMapper( this->m_MeshMapper ); this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 ); this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( ); this->m_3DRenderer->AddActor( this->m_MeshActor ); this->m_3DRenderer->ResetCamera( ); this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); unsigned int reduction = 20; typedef TImage::SpacingType::ValueType _TValue; // Compute downsize parameters TImage::SizeType o_size = segmentation->GetLargestPossibleRegion( ).GetSize( ); TImage::SpacingType o_spac = segmentation->GetSpacing( ); _TValue min_spac = std::numeric_limits< _TValue >::max( ); for( unsigned int d = 0; d < Dimension; ++d ) min_spac = ( o_spac[ d ] < min_spac )? o_spac[ d ]: min_spac; min_spac *= _TValue( reduction ); TImage::SpacingType n_spac( min_spac ); TImage::SizeType n_size; for( unsigned int d = 0; d < Dimension; ++d ) n_size[ d ] = ( unsigned long )( _TValue( o_size[ d ] ) * o_spac[ d ] / min_spac ); // Downsize image typedef itk::Image< TScalar, Dimension > _TScalarImage; typedef itk::IdentityTransform< TScalar, Dimension > _TTransform; typedef itk::LinearInterpolateImageFunction< TImage, TScalar > _TInterpolator; typedef itk::ResampleImageFilter< TImage, _TScalarImage, TScalar, TScalar > _TResample; _TResample::Pointer resample = _TResample::New( ); resample->SetInput( segmentation ); resample->SetSize( n_size ); resample->SetOutputDirection( segmentation->GetDirection( ) ); resample->SetOutputOrigin( segmentation->GetOrigin( ) ); resample->SetOutputSpacing( n_spac ); resample->SetTransform( _TTransform::New( ) ); resample->SetInterpolator( _TInterpolator::New( ) ); resample->UpdateLargestPossibleRegion( ); // Try to smooth typedef itk::SignedDanielssonDistanceMapImageFilter< _TScalarImage, _TScalarImage > _TDanielsson; _TDanielsson::Pointer danielsson = _TDanielsson::New( ); danielsson->SetInput( resample->GetOutput( ) ); danielsson->Update( ); // Go back to ITK world typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > TVTKPDataToMesh; TVTKPDataToMesh::Pointer itk_mc = TVTKPDataToMesh::New( ); itk_mc->SetInput( danielsson_mc->GetOutput( ) ); itk_mc->Update( ); this->m_Mesh = itk_mc->GetOutput( ); this->m_Mesh->DisconnectPipeline( ); this->m_ZCutter = TCutter::New( ); this->m_ZCutter->SetInput( this->m_Mesh ); this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( ); this->m_MeshActor = vtkSmartPointer< vtkActor >::New( ); this->m_MeshMapper->SetInputData( this->m_Mesh ); this->m_MeshActor->SetMapper( this->m_MeshMapper ); this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 ); this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( ); this->m_3DRenderer->AddActor( this->m_MeshActor ); this->m_3DRenderer->ResetCamera( ); this->m_UI->m_3DVTK->GetRenderWindow( )->Render( ); } // fi } */ // eof - $RCSfile$