#include "MainWnd.h" #include "ui_MainWnd.h" #include #include #include #include #include #include #include #include #include #include #include // ------------------------------------------------------------------------- #define IDMS_QT_ACTION( name ) \ QObject::connect( \ this->m_UI->action##name, SIGNAL( triggered( ) ), \ this, SLOT( _triggered_action##name( ) ) \ ) // ------------------------------------------------------------------------- MainWnd::MainWnd( QWidget* parent ) : QMainWindow( parent ), m_UI( new Ui::MainWnd ), m_InputImage( NULL ), m_SegmentedImage( NULL ), m_ActivePlugin( NULL ), m_ActiveParameters( NULL ), m_ActivePluginType( Self::NonePluginType ), m_ActivePluginCategory( Self::NonePluginCategory ) { this->m_UI->setupUi( this ); // Configuration files this->m_ApplicationPreferencesFile = "idms.config"; this->m_PluginsConfigurationFile = "idms.plugins"; this->_LoadApplicationPreferences( ); // Create MPR objects this->m_MPR = new TMPR( this->m_UI->m_XPlaneVTK->GetRenderWindow( ), this->m_UI->m_YPlaneVTK->GetRenderWindow( ), this->m_UI->m_ZPlaneVTK->GetRenderWindow( ), 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 = 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( ); */ // Qt signals <-> slots IDMS_QT_ACTION( ReloadPlugins ); IDMS_QT_ACTION( OpenInputImage ); IDMS_QT_ACTION( OpenSegmentedImage ); QObject::connect( this->m_UI->actionNavigation, SIGNAL( triggered( ) ), this, SLOT( _triggered_actionSwitchMode( ) ) ); QObject::connect( this->m_UI->actionSegmentationInteractiveDeformation, SIGNAL( triggered( ) ), this, SLOT( _triggered_actionSwitchMode( ) ) ); // Historic configuration this->m_LastOpenedFile = "."; // Start: load all disponible plugins this->_triggered_actionReloadPlugins( ); } // ------------------------------------------------------------------------- MainWnd:: ~MainWnd( ) { // Close all connections this->m_Plugins.UnloadAll( ); // Delete objects delete this->m_UI; delete this->m_MPR; if( this->m_ActiveParameters != NULL ) { this->m_ActiveParameters->close( ); delete this->m_ActiveParameters; } // fi if( this->m_ActivePlugin != NULL ) delete this->m_ActivePlugin; if( this->m_InputImage != NULL ) delete this->m_InputImage; if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage; } // ------------------------------------------------------------------------- void MainWnd:: _LoadApplicationPreferences( ) { this->m_ApplicationPreferences.clear( ); std::ifstream in( this->m_ApplicationPreferencesFile.c_str( ) ); if( in ) { std::string line; std::getline( in, line ); while( !( in.eof( ) ) ) { long pos = line.find_last_of( "=" ); std::string key = line.substr( 0, pos ); std::string value = line.substr( pos + 1 ); key.erase( std::remove_if( key.begin( ), key.end( ), isspace ), key.end( ) ); value.erase( std::remove_if( value.begin( ), value.end( ), isspace ), value.end( ) ); this->m_ApplicationPreferences[ key ] = value; std::getline( in, line ); } // elihw } else { this->m_ApplicationPreferences[ "data_dimensions" ] = "3"; this->m_ApplicationPreferences[ "input_image_type" ] = "short"; this->m_ApplicationPreferences[ "segmented_image_type" ] = "uchar"; this->m_ApplicationPreferences[ "mesh_type" ] = "double"; } // fi in.close( ); } // ------------------------------------------------------------------------- MainWnd:: TPluginImage* MainWnd:: _LoadImage( const std::string& image_type, const std::string& image_dim ) { // Show dialog and check if it was accepted QFileDialog dialog( this ); dialog.setFileMode( QFileDialog::ExistingFiles ); dialog.setDirectory( tr( this->m_LastOpenedFile.c_str( ) ) ); dialog.setNameFilter( tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" ) ); dialog.setDefaultSuffix( tr( "mhd" ) ); if( !( dialog.exec( ) ) ) return( NULL ); TPluginImage* ret = NULL; unsigned int nFiles = dialog.selectedFiles( ).size( ); if( nFiles == 1 ) { if( this->m_BaseClasses[ "ImageReader" ] == "" ) { QMessageBox::critical( this, tr( "No plugin to read a single image file found!" ), tr( "No plugin to read a single image file found!" ) ); return( ret ); } // fi std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( ); this->m_LastOpenedFile = fname; TPlugin* reader = dynamic_cast< TPlugin* >( this->m_Plugins.CreateObject( this->m_BaseClasses[ "ImageReader" ] ) ); TParameters reader_params = reader->GetDefaultParameters( ); reader_params[ "FileName" ].second = fname; reader_params[ "PixelType" ].second = image_type; reader_params[ "ImageDimension" ].second = image_dim; reader_params[ "IsColorImage" ].second = "0"; reader->SetParameters( reader_params ); std::string err = reader->Update( ); if( err == "" ) { ret = dynamic_cast< TPluginImage* >( reader->GetOutput( 0 ) ); reader->DisconnectOutputs( ); } else QMessageBox::critical( this, tr( "Error reading single image" ), tr( err.c_str( ) ) ); delete reader; } else if( nFiles > 1 ) { /* TODO if( this->m_ImageSeriesReaderClassName == "" ) { QMessageBox::critical( this, tr( "No plugin to read an image series found!" ), tr( "No plugin to read an image series found!" ) ); return( ret ); } // fi std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( ); this->m_LastOpenedFile = fname; */ } // fi return( ret ); } // ------------------------------------------------------------------------- void MainWnd:: _UpdateEnabledFlags( ) { bool img = ( this->m_InputImage != NULL ); this->m_UI->menuSegmentInputImage->setEnabled( img ); this->m_UI->actionOpenSegmentedImage->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_SegmentedImage != NULL ); this->m_UI->menuFilterSegmentedImage->setEnabled( seg ); this->m_UI->menuExtractMesh->setEnabled( seg ); this->m_UI->menuProcessMesh->setEnabled( seg ); this->m_UI->actionOpenMesh->setEnabled( seg ); this->m_UI->actionNavigation->setEnabled( img && seg ); this->m_UI->actionSegmentationInteractiveDeformation-> setEnabled( img && seg ); } // ------------------------------------------------------------------------- void MainWnd:: _triggered_actionReloadPlugins( ) { if( !( this->_LoadPlugins( ) ) ) { QMessageBox::critical( this, tr( "Could not load plugins from given file." ), tr( "Could not load plugins from given file." ) ); } // fi this->_UpdateEnabledFlags( ); } // ------------------------------------------------------------------------- void MainWnd:: _triggered_actionOpenInputImage( ) { if( this->m_InputImage != NULL ) delete this->m_InputImage; this->m_InputImage = this->_LoadImage( this->m_ApplicationPreferences[ "input_image_type" ], this->m_ApplicationPreferences[ "data_dimensions" ] ); if( this->m_InputImage != NULL ) { this->m_MPR->SetImage( this->m_InputImage->GetVTKImageData( ) ); // Update activations this->_UpdateEnabledFlags( ); this->m_UI->actionNavigation->setChecked( true ); this->_triggered_actionSwitchMode( ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: _triggered_actionOpenSegmentedImage( ) { if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage; this->m_SegmentedImage = this->_LoadImage( this->m_ApplicationPreferences[ "segmented_image_type" ], this->m_ApplicationPreferences[ "data_dimensions" ] ); if( this->m_SegmentedImage != NULL ) { this->m_MPR->SetSegmentation( this->m_SegmentedImage->GetVTKImageData( ) ); /* TODO cpPlugins::Interface::Image* img = dynamic_cast< cpPlugins::Interface::Image* >( this->m_SegmentedImage ); this->m_ImageActors->SetSegmentation( img->GetVTKImageData( ) ); */ // Ok, start! this->m_MPR->Render( 0 ); this->m_MPR->Render( 1 ); this->m_MPR->Render( 2 ); this->_UpdateEnabledFlags( ); } // fi } // ------------------------------------------------------------------------- void MainWnd:: _triggered_actionSwitchMode( ) { QAction* snd = dynamic_cast< QAction* >( this->sender( ) ); if( snd == this->m_UI->actionNavigation ) { this->m_UI->actionSegmentationInteractiveDeformation->setChecked( !( this->m_UI->actionNavigation->isChecked( ) ) ); } else if( snd == this->m_UI->actionSegmentationInteractiveDeformation ) { this->m_UI->actionNavigation->setChecked( !( this->m_UI->actionSegmentationInteractiveDeformation->isChecked( ) ) ); } else { this->m_UI->actionNavigation->setChecked( true ); this->m_UI->actionSegmentationInteractiveDeformation->setChecked( false ); } // fi /* TODO 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 */ } // ------------------------------------------------------------------------- /* TODO // ------------------------------------------------------------------------- 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 ); } // ------------------------------------------------------------------------- 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_Plugins.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 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_Plugins.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$