2 #include "ui_MainWnd.h"
11 #include <vtkAnnotatedCubeActor.h>
12 #include <vtkAxesActor.h>
13 #include <vtkPropAssembly.h>
14 #include <vtkProperty.h>
15 #include <vtkRenderWindow.h>
17 #include <cpPlugins/Interface/Image.h>
19 // -------------------------------------------------------------------------
20 #define IDMS_QT_ACTION( name ) \
22 this->m_UI->action##name, SIGNAL( triggered( ) ), \
23 this, SLOT( _triggered_action##name( ) ) \
26 // -------------------------------------------------------------------------
27 MainWnd::MainWnd( QWidget* parent )
30 : QMainWindow( parent ),
31 m_UI( new Ui::MainWnd ),
33 m_SegmentedImage( NULL ),
34 m_ActivePlugin( NULL ),
35 m_ActiveParameters( NULL ),
36 m_ActivePluginType( Self::NonePluginType ),
37 m_ActivePluginCategory( Self::NonePluginCategory )
39 this->m_UI->setupUi( this );
41 // Configuration files
42 this->m_ApplicationPreferencesFile = "idms.config";
43 this->m_PluginsConfigurationFile = "idms.plugins";
44 this->_LoadApplicationPreferences( );
47 this->m_MPR = new TMPR(
48 this->m_UI->m_XPlaneVTK->GetRenderWindow( ),
49 this->m_UI->m_YPlaneVTK->GetRenderWindow( ),
50 this->m_UI->m_ZPlaneVTK->GetRenderWindow( ),
51 this->m_UI->m_3DVTK->GetRenderWindow( )
55 this->m_DoubleClickCommand =
56 vtkSmartPointer< DoubleClickCommand >::New( );
57 this->m_DoubleClickCommand->SetMainWnd( this );
58 // this->m_MPR->AddDoubleClickObserver( this->m_DoubleClickCommand );
61 vtkSmartPointer< vtkAnnotatedCubeActor > oCube =
62 vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
63 oCube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
64 oCube->GetTextEdgesProperty( )->SetLineWidth( 1 );
65 oCube->GetTextEdgesProperty( )->SetDiffuse( 0 );
66 oCube->GetTextEdgesProperty( )->SetAmbient( 1 );
67 oCube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
68 oCube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
69 oCube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
70 oCube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
71 oCube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
72 oCube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
73 oCube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
74 oCube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
75 oCube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
76 oCube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
77 oCube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
78 oCube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
79 oCube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
81 vtkSmartPointer< vtkAxesActor > oAxes =
82 vtkSmartPointer< vtkAxesActor >::New( );
83 oAxes->AxisLabelsOff( );
84 oAxes->SetShaftTypeToCylinder( );
85 oAxes->SetTotalLength( 2.5, 2.5, 2.5 );
87 vtkSmartPointer< vtkPropAssembly > oActors =
88 vtkSmartPointer< vtkPropAssembly >::New( );
89 oActors->AddPart( oCube );
90 oActors->AddPart( oAxes );
92 this->m_3DOrientationWidget =
93 vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
94 this->m_3DOrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
95 this->m_3DOrientationWidget->SetOrientationMarker( oActors );
96 this->m_3DOrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
98 // Add actors, widgets, stuff, ...
99 this->m_3DOrientationWidget->
100 SetInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
101 this->m_3DOrientationWidget->SetEnabled( 1 );
102 this->m_3DOrientationWidget->InteractiveOff( );
104 // Qt signals <-> slots
105 IDMS_QT_ACTION( ReloadPlugins );
106 IDMS_QT_ACTION( OpenInputImage );
107 IDMS_QT_ACTION( OpenSegmentedImage );
109 this->m_UI->actionNavigation, SIGNAL( triggered( ) ),
110 this, SLOT( _triggered_actionSwitchMode( ) )
113 this->m_UI->actionSegmentationInteractiveDeformation,
114 SIGNAL( triggered( ) ),
115 this, SLOT( _triggered_actionSwitchMode( ) )
118 // Historic configuration
119 this->m_LastOpenedFile = ".";
121 // Start: load all disponible plugins
122 this->_triggered_actionReloadPlugins( );
125 // -------------------------------------------------------------------------
129 // // Close all connections
130 // this->m_Plugins.UnloadAll( );
133 // delete this->m_UI;
134 // // delete this->m_MPR;
135 // if( this->m_ActiveParameters != NULL )
137 // this->m_ActiveParameters->close( );
138 // delete this->m_ActiveParameters;
141 // if( this->m_ActivePlugin != NULL ) delete this->m_ActivePlugin;
142 // if( this->m_InputImage != NULL ) delete this->m_InputImage;
143 // if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage;
146 // -------------------------------------------------------------------------
148 _LoadApplicationPreferences( )
150 // this->m_ApplicationPreferences.clear( );
151 // std::ifstream in( this->m_ApplicationPreferencesFile.c_str( ) );
155 // std::getline( in, line );
156 // while( !( in.eof( ) ) )
158 // long pos = line.find_last_of( "=" );
159 // std::string key = line.substr( 0, pos );
160 // std::string value = line.substr( pos + 1 );
162 // std::remove_if( key.begin( ), key.end( ), isspace ), key.end( )
165 // std::remove_if( value.begin( ), value.end( ), isspace ), value.end( )
167 // this->m_ApplicationPreferences[ key ] = value;
168 // std::getline( in, line );
174 // this->m_ApplicationPreferences[ "data_dimensions" ] = "3";
175 // this->m_ApplicationPreferences[ "input_image_type" ] = "short";
176 // this->m_ApplicationPreferences[ "segmented_image_type" ] = "uchar";
177 // this->m_ApplicationPreferences[ "mesh_type" ] = "double";
183 // -------------------------------------------------------------------------
185 TPluginImage* MainWnd::
186 _LoadImage( const std::string& image_type, const std::string& image_dim )
188 // // Show dialog and check if it was accepted
189 // QFileDialog dialog( this );
190 // dialog.setFileMode( QFileDialog::ExistingFiles );
191 // dialog.setDirectory( tr( this->m_LastOpenedFile.c_str( ) ) );
192 // dialog.setNameFilter(
193 // tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
195 // dialog.setDefaultSuffix( tr( "mhd" ) );
196 // if( !( dialog.exec( ) ) )
199 // TPluginImage* ret = NULL;
200 // unsigned int nFiles = dialog.selectedFiles( ).size( );
203 // if( this->m_BaseClasses[ "ImageReader" ] == "" )
205 // QMessageBox::critical(
207 // tr( "No plugin to read a single image file found!" ),
208 // tr( "No plugin to read a single image file found!" )
214 // std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
215 // this->m_LastOpenedFile = fname;
218 // dynamic_cast< TPlugin* >(
219 // this->m_Plugins.CreateObject( this->m_BaseClasses[ "ImageReader" ] )
222 // TParameters reader_params = reader->GetDefaultParameters( );
223 // reader_params[ "FileName" ].second = fname;
224 // reader_params[ "PixelType" ].second = image_type;
225 // reader_params[ "ImageDimension" ].second = image_dim;
226 // reader_params[ "IsColorImage" ].second = "0";
227 // reader->SetParameters( reader_params );
228 // std::string err = reader->Update( );
232 // ret = dynamic_cast< TPluginImage* >( reader->GetOutput( 0 ) );
233 // reader->DisconnectOutputs( );
236 // QMessageBox::critical(
238 // tr( "Error reading single image" ),
239 // tr( err.c_str( ) )
243 // else if( nFiles > 1 )
246 // if( this->m_ImageSeriesReaderClassName == "" )
248 // QMessageBox::critical(
250 // tr( "No plugin to read an image series found!" ),
251 // tr( "No plugin to read an image series found!" )
256 // std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
257 // this->m_LastOpenedFile = fname;
264 // -------------------------------------------------------------------------
266 _UpdateEnabledFlags( )
268 // bool img = ( this->m_InputImage != NULL );
269 // this->m_UI->menuSegmentInputImage->setEnabled( img );
270 // this->m_UI->actionOpenSegmentedImage->setEnabled( img );
271 // this->m_UI->m_3DVTK->setEnabled( img );
272 // this->m_UI->m_XPlaneVTK->setEnabled( img );
273 // this->m_UI->m_YPlaneVTK->setEnabled( img );
274 // this->m_UI->m_ZPlaneVTK->setEnabled( img );
275 // this->m_UI->m_AuxVTK->setEnabled( img );
277 // bool seg = ( this->m_SegmentedImage != NULL );
278 // this->m_UI->menuFilterSegmentedImage->setEnabled( seg );
279 // this->m_UI->menuExtractMesh->setEnabled( seg );
280 // this->m_UI->menuProcessMesh->setEnabled( seg );
281 // this->m_UI->actionOpenMesh->setEnabled( seg );
283 // this->m_UI->actionNavigation->setEnabled( img && seg );
284 // this->m_UI->actionSegmentationInteractiveDeformation->
285 // setEnabled( img && seg );
288 // -------------------------------------------------------------------------
290 _triggered_actionReloadPlugins( )
292 // if( !( this->_LoadPlugins( ) ) )
294 // QMessageBox::critical(
296 // tr( "Could not load plugins from given file." ),
297 // tr( "Could not load plugins from given file." )
301 // this->_UpdateEnabledFlags( );
304 // -------------------------------------------------------------------------
306 _triggered_actionOpenInputImage( )
308 // if( this->m_InputImage != NULL )
309 // delete this->m_InputImage;
310 // this->m_InputImage =
312 // this->m_ApplicationPreferences[ "input_image_type" ],
313 // this->m_ApplicationPreferences[ "data_dimensions" ]
315 // if( this->m_InputImage != NULL )
317 // // this->m_MPR->SetImage( this->m_InputImage->GetVTKImageData( ) );
319 // // Update activations
320 // this->_UpdateEnabledFlags( );
321 // this->m_UI->actionNavigation->setChecked( true );
322 // this->_triggered_actionSwitchMode( );
327 // -------------------------------------------------------------------------
329 _triggered_actionOpenSegmentedImage( )
331 // if( this->m_SegmentedImage != NULL )
332 // delete this->m_SegmentedImage;
333 // this->m_SegmentedImage =
335 // this->m_ApplicationPreferences[ "segmented_image_type" ],
336 // this->m_ApplicationPreferences[ "data_dimensions" ]
338 // if( this->m_SegmentedImage != NULL )
341 // this->m_MPR->SetSegmentation(
342 // this->m_SegmentedImage->GetVTKImageData( )
346 // cpPlugins::Interface::Image* img =
347 // dynamic_cast< cpPlugins::Interface::Image* >( this->m_SegmentedImage );
348 // this->m_ImageActors->SetSegmentation( img->GetVTKImageData( ) );
353 // this->m_MPR->Render( 0 );
354 // this->m_MPR->Render( 1 );
355 // this->m_MPR->Render( 2 );
357 // this->_UpdateEnabledFlags( );
362 // -------------------------------------------------------------------------
364 _triggered_actionSwitchMode( )
366 // QAction* snd = dynamic_cast< QAction* >( this->sender( ) );
367 // if( snd == this->m_UI->actionNavigation )
369 // this->m_UI->actionSegmentationInteractiveDeformation->setChecked(
370 // !( this->m_UI->actionNavigation->isChecked( ) )
373 // else if( snd == this->m_UI->actionSegmentationInteractiveDeformation )
375 // this->m_UI->actionNavigation->setChecked(
376 // !( this->m_UI->actionSegmentationInteractiveDeformation->isChecked( ) )
381 // this->m_UI->actionNavigation->setChecked( true );
382 // this->m_UI->actionSegmentationInteractiveDeformation->setChecked( false );
387 // if( this->m_UI->aNavigation->isChecked( ) )
389 // this->m_XStyle->SetModeToNavigation( );
390 // this->m_YStyle->SetModeToNavigation( );
391 // this->m_ZStyle->SetModeToNavigation( );
392 // this->m_ImageActors->HideRegion( 0 );
393 // this->m_ImageActors->HideRegion( 1 );
394 // this->m_ImageActors->HideRegion( 2 );
395 // this->m_3DRenderer->RemoveActor(
396 // this->m_ImageActors->GetCursorActor( )
398 // this->m_3DRenderer->RemoveActor(
399 // this->m_ImageActors->GetRegionActor( )
401 // this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
403 // else if( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) )
405 // this->m_XStyle->SetModeToDeformation( );
406 // this->m_YStyle->SetModeToDeformation( );
407 // this->m_ZStyle->SetModeToDeformation( );
408 // this->m_ImageActors->ShowRegion( 0 );
409 // this->m_ImageActors->ShowRegion( 1 );
410 // this->m_ImageActors->ShowRegion( 2 );
411 // this->m_3DRenderer->AddActor(
412 // this->m_ImageActors->GetCursorActor( )
414 // this->m_3DRenderer->AddActor(
415 // this->m_ImageActors->GetRegionActor( )
417 // this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
423 // -------------------------------------------------------------------------
426 // -------------------------------------------------------------------------
428 _ParametersDialog( TParameters& parameters )
431 QGridLayout gridLayout( &dlg );
432 QVBoxLayout verticalLayout;
435 typedef std::map< std::string, QWidget* > _TWidgets;
437 TParameters::const_iterator pIt = parameters.begin( );
438 for( ; pIt != parameters.end( ); ++pIt )
440 unsigned long pos = pIt->first.find_last_of( ":" );
441 std::string v_name = pIt->first.substr( 0, pos );
442 std::string v_type = pIt->first.substr( pos + 1 );
444 QHBoxLayout* horizontalLayout = new QHBoxLayout( );
445 QLabel* label = new QLabel( &dlg );
446 label->setText( QString( v_name.c_str( ) ) );
447 horizontalLayout->addWidget( label );
448 if( v_type == "real" )
450 QDoubleSpinBox* v_double = new QDoubleSpinBox( &dlg );
451 v_double->setDecimals( 3 );
452 v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
453 v_double->setMaximum( std::numeric_limits< double >::max( ) );
454 v_double->setValue( std::atof( pIt->second.c_str( ) ) );
455 horizontalLayout->addWidget( v_double );
456 widgets[ pIt->first ] = v_double;
458 else if( v_type == "atomic_real" )
460 if( v_name == "MeshType" )
462 QLabel* info = new QLabel( &dlg );
463 if( typeid( TScalar ) == typeid( float ) )
464 info->setText( QString( "float" ) );
465 else if( typeid( TScalar ) == typeid( double ) )
466 info->setText( QString( "double" ) );
467 horizontalLayout->addWidget( info );
468 widgets[ pIt->first ] = info;
473 verticalLayout.addLayout( horizontalLayout );
476 gridLayout.addLayout( &verticalLayout, 0, 0, 1, 1 );
479 QDialogButtonBox buttonBox( &dlg );
480 buttonBox.setOrientation( Qt::Horizontal );
481 buttonBox.setStandardButtons(
482 QDialogButtonBox::Cancel | QDialogButtonBox::Ok
484 gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 );
486 &buttonBox, SIGNAL( accepted( ) ),
487 &dlg, SLOT( accept( ) )
490 &buttonBox, SIGNAL( rejected( ) ),
491 &dlg, SLOT( reject( ) )
493 QMetaObject::connectSlotsByName( &dlg );
496 if( dlg.exec( ) == QDialog::Accepted )
498 _TWidgets::const_iterator wIt = widgets.begin( );
499 for( ; wIt != widgets.end( ); ++wIt )
501 unsigned long pos = wIt->first.find_last_of( ":" );
502 std::string v_name = wIt->first.substr( 0, pos );
503 std::string v_type = wIt->first.substr( pos + 1 );
504 std::stringstream sstr;
505 if( v_type == "real" )
507 QDoubleSpinBox* v_double =
508 dynamic_cast< QDoubleSpinBox* >( wIt->second );
509 if( v_double != NULL )
510 sstr << v_double->value( );
512 else if( v_type == "atomic_real" )
514 if( v_name == "MeshType" )
516 QLabel* info = dynamic_cast< QLabel* >( wIt->second );
518 sstr << info->text( ).toStdString( );
523 parameters[ wIt->first ] = sstr.str( );
531 // -------------------------------------------------------------------------
533 triggered_aFilterSegmentedImage( )
536 if( this->m_Segmentation.IsNull( ) )
538 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
541 std::string filter_name = action->text( ).toStdString( );
544 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
548 TParameters parameters = filter->GetDefaultParameters( );
549 if( !( this->_ParametersDialog( parameters ) ) )
551 filter->SetInput( this->m_Segmentation );
552 filter->SetParameters( parameters );
553 std::string result = filter->Update( );
555 // Get modified segmentation
556 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
557 if( this->m_Mesh.IsNotNull( ) )
559 this->m_Mesh->DisconnectPipeline( );
562 // Ok, it seems to have runned fine
566 // -------------------------------------------------------------------------
568 triggered_aSegmentedImageToMesh( )
571 if( this->m_Segmentation.IsNull( ) )
573 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
576 std::string filter_name = action->text( ).toStdString( );
579 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
583 TParameters parameters = filter->GetDefaultParameters( );
584 if( !( this->_ParametersDialog( parameters ) ) )
586 filter->SetInput( this->m_Segmentation );
587 filter->SetParameters( parameters );
588 std::string result = filter->Update( );
591 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
592 if( this->m_Mesh.IsNotNull( ) )
594 this->m_Mesh->DisconnectPipeline( );
598 // Ok, it seems to have runned fine
603 // -------------------------------------------------------------------------
606 _SliceMesh( int axis )
608 TCutter* cutter = NULL;
609 if( axis == 2 ) cutter = this->m_ZCutter;
614 vtkPlane* vplane = this->m_ImageActors->GetSlicePlane( axis );
615 double vorigin[ 3 ], vnormal[ 3 ];
616 vplane->GetOrigin( vorigin );
617 vplane->GetNormal( vnormal );
619 TCutter::TVector corigin, cnormal;
620 corigin[ 0 ] = TScalar( vorigin[ 0 ] );
621 corigin[ 1 ] = TScalar( vorigin[ 1 ] );
622 corigin[ 2 ] = TScalar( vorigin[ 2 ] );
623 cnormal[ 0 ] = TScalar( vnormal[ 0 ] );
624 cnormal[ 1 ] = TScalar( vnormal[ 1 ] );
625 cnormal[ 2 ] = TScalar( vnormal[ 2 ] );
627 cutter->SetPlanePoint( corigin );
628 cutter->SetPlaneNormal( cnormal );
632 // -------------------------------------------------------------------------
636 long unsigned int eventId,
637 void* clientData, void* callData
640 if( clientData == NULL || callData == NULL )
642 MainWnd* wnd = reinterpret_cast< MainWnd* >( clientData );
643 int axis = *( reinterpret_cast< int* >( callData ) );
646 if( eventId == idms::InteractorStyleImage::SliceEvent )
647 wnd->_SliceMesh( axis );
650 // -------------------------------------------------------------------------
652 triggered_aLoadImage( )
654 if( this->_LoadImage< TImage >( this->m_Image ) )
656 // Connect image to VTK
657 this->m_VTKImage->SetInput( this->m_Image );
658 this->m_VTKImage->Update( );
659 this->m_ImageActors->Configure(
660 this->m_VTKImage->GetOutput( ),
661 this->m_UI->m_XPlaneVTK->GetInteractor( ),
662 this->m_UI->m_YPlaneVTK->GetInteractor( ),
663 this->m_UI->m_ZPlaneVTK->GetInteractor( )
665 this->m_ImageActors->
666 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
669 this->m_3DRenderer->AddActor(
670 this->m_ImageActors->GetImageOutlineActor( )
672 this->m_3DRenderer->AddActor(
673 this->m_ImageActors->GetXBoundsActor( )
675 this->m_3DRenderer->AddActor(
676 this->m_ImageActors->GetYBoundsActor( )
678 this->m_3DRenderer->AddActor(
679 this->m_ImageActors->GetZBoundsActor( )
683 this->m_3DRenderer->ResetCamera( );
684 this->m_ImageActors->ResetCameras( );
687 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
688 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
689 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
690 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
693 this->m_UI->aLoadSegmentedImage->setEnabled( true );
694 this->m_UI->aSegmentImage->setEnabled( true );
695 this->m_UI->m_3DVTK->setEnabled( true );
696 this->m_UI->m_XPlaneVTK->setEnabled( true );
697 this->m_UI->m_YPlaneVTK->setEnabled( true );
698 this->m_UI->m_ZPlaneVTK->setEnabled( true );
703 // -------------------------------------------------------------------------
705 triggered_aLoadSegmentedImage( )
707 if( this->m_Mesh.IsNotNull( ) )
709 QMessageBox::critical(
711 tr( "Mesh already loaded!" ),
712 tr( "Mesh already loaded!" )
718 if( this->_LoadImage< TImage >( this->m_Segmentation ) )
720 // Compute segmentation values
721 itk::MinimumMaximumImageCalculator< TImage >::Pointer minmax =
722 itk::MinimumMaximumImageCalculator< TImage >::New( );
723 minmax->SetImage( this->m_Segmentation );
725 TPixel min_v = minmax->GetMinimum( );
726 TPixel max_v = minmax->GetMaximum( );
727 double thr = double( max_v + min_v ) / double( 2 );
729 typedef itk::Image< TScalar, Dimension > _TScalarImage;
731 itk::BinaryMinMaxCurvatureFlowImageFilter< TImage, _TScalarImage >
733 typedef _TFilter::TimeStepType _TTimeStep;
734 typedef _TFilter::RadiusValueType _TRadius;
736 _TFilter::Pointer filter = _TFilter::New( );
737 filter->SetInput( this->m_Segmentation );
738 filter->SetTimeStep( _TTimeStep( 0.0625 ) );
739 filter->SetNumberOfIterations( 10 );
740 filter->SetStencilRadius( _TRadius( 3 ) );
741 filter->SetThreshold( thr );
744 itk::ImageFileWriter< _TScalarImage >::Pointer w =
745 itk::ImageFileWriter< _TScalarImage >::New( );
746 w->SetInput( filter->GetOutput( ) );
747 w->SetFileName( "no_noise.mhd" );
752 itk::LaplacianRecursiveGaussianImageFilter< TImage, _TScalarImage >
754 _TFilter::Pointer filter = _TFilter::New( );
755 filter->SetInput( this->m_Segmentation );
756 filter->SetSigma( 3 ); // in spacing units
757 filter->SetNormalizeAcrossScale( false );
759 typedef itk::ThresholdImageFilter< _TScalarImage > _TThreshold;
760 _TThreshold::Pointer threshold = _TThreshold::New( );
761 threshold->SetInput( filter->GetOutput( ) );
762 threshold->ThresholdAbove( TScalar( 0 ) );
763 threshold->InPlaceOff( );
764 threshold->Update( );
766 itk::MinimumMaximumImageCalculator< _TScalarImage >::Pointer t_minmax =
767 itk::MinimumMaximumImageCalculator< _TScalarImage >::New( );
768 t_minmax->SetImage( threshold->GetOutput( ) );
769 t_minmax->Compute( );
770 TScalar min_t = t_minmax->GetMinimum( );
772 std::cout << min_t << " " << t_minmax->GetMaximum( ) << std::endl;
774 itk::SubtractImageFilter< _TScalarImage >::Pointer subtract =
775 itk::SubtractImageFilter< _TScalarImage >::New( );
776 subtract->SetInput1( threshold->GetOutput( ) );
777 subtract->SetConstant2( min_t );
779 itk::ImageFileWriter< _TScalarImage >::Pointer w =
780 itk::ImageFileWriter< _TScalarImage >::New( );
781 w->SetInput( subtract->GetOutput( ) );
782 w->SetFileName( "no_noise_laplace_2.mhd" );
786 // Pass segmentation to VTK
787 this->m_VTKSegmentation = TVTKImage::New( );
788 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
789 this->m_VTKSegmentation->Update( );
791 // Use VTK's marching cubes (it is smoother)
792 vtkSmartPointer< vtkImageMarchingCubes > segmentation_mc =
793 vtkSmartPointer< vtkImageMarchingCubes >::New( );
794 segmentation_mc->SetInputData( this->m_VTKSegmentation->GetOutput( ) );
795 segmentation_mc->SetValue( 0, thr );
796 segmentation_mc->Update( );
798 // Go back to ITK world
799 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > _TVTKPDataToMesh;
800 _TVTKPDataToMesh::Pointer itk_mc = _TVTKPDataToMesh::New( );
801 itk_mc->SetInput( segmentation_mc->GetOutput( ) );
803 this->m_Mesh = itk_mc->GetOutput( );
804 this->m_Mesh->DisconnectPipeline( );
806 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
807 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
809 this->m_MeshMapper->SetInputData( this->m_Mesh );
810 this->m_MeshActor->SetMapper( this->m_MeshMapper );
811 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
812 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
813 this->m_3DRenderer->AddActor( this->m_MeshActor );
814 this->m_3DRenderer->ResetCamera( );
815 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
817 unsigned int reduction = 20;
819 typedef TImage::SpacingType::ValueType _TValue;
822 // Compute downsize parameters
823 TImage::SizeType o_size =
824 segmentation->GetLargestPossibleRegion( ).GetSize( );
825 TImage::SpacingType o_spac = segmentation->GetSpacing( );
826 _TValue min_spac = std::numeric_limits< _TValue >::max( );
827 for( unsigned int d = 0; d < Dimension; ++d )
828 min_spac = ( o_spac[ d ] < min_spac )? o_spac[ d ]: min_spac;
829 min_spac *= _TValue( reduction );
830 TImage::SpacingType n_spac( min_spac );
831 TImage::SizeType n_size;
832 for( unsigned int d = 0; d < Dimension; ++d )
833 n_size[ d ] = ( unsigned long )(
834 _TValue( o_size[ d ] ) * o_spac[ d ] / min_spac
838 typedef itk::Image< TScalar, Dimension > _TScalarImage;
839 typedef itk::IdentityTransform< TScalar, Dimension > _TTransform;
841 itk::LinearInterpolateImageFunction< TImage, TScalar >
844 itk::ResampleImageFilter< TImage, _TScalarImage, TScalar, TScalar >
846 _TResample::Pointer resample = _TResample::New( );
847 resample->SetInput( segmentation );
848 resample->SetSize( n_size );
849 resample->SetOutputDirection( segmentation->GetDirection( ) );
850 resample->SetOutputOrigin( segmentation->GetOrigin( ) );
851 resample->SetOutputSpacing( n_spac );
852 resample->SetTransform( _TTransform::New( ) );
853 resample->SetInterpolator( _TInterpolator::New( ) );
854 resample->UpdateLargestPossibleRegion( );
858 itk::SignedDanielssonDistanceMapImageFilter< _TScalarImage, _TScalarImage >
860 _TDanielsson::Pointer danielsson = _TDanielsson::New( );
861 danielsson->SetInput( resample->GetOutput( ) );
862 danielsson->Update( );
864 // Go back to ITK world
865 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > TVTKPDataToMesh;
866 TVTKPDataToMesh::Pointer itk_mc = TVTKPDataToMesh::New( );
867 itk_mc->SetInput( danielsson_mc->GetOutput( ) );
869 this->m_Mesh = itk_mc->GetOutput( );
870 this->m_Mesh->DisconnectPipeline( );
872 this->m_ZCutter = TCutter::New( );
873 this->m_ZCutter->SetInput( this->m_Mesh );
875 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
876 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
878 this->m_MeshMapper->SetInputData( this->m_Mesh );
879 this->m_MeshActor->SetMapper( this->m_MeshMapper );
880 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
881 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
882 this->m_3DRenderer->AddActor( this->m_MeshActor );
883 this->m_3DRenderer->ResetCamera( );
884 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );