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 )
28 : QMainWindow( parent ),
29 m_UI( new Ui::MainWnd ),
31 m_SegmentedImage( NULL )
33 this->m_UI->setupUi( this );
35 // Configuration files
36 this->m_ApplicationPreferencesFile = "idms.config";
37 this->m_PluginsConfigurationFile = "idms.plugins";
38 this->_LoadApplicationPreferences( );
40 // Create and associate renderers
41 this->m_3DRenderer = vtkSmartPointer< vtkRenderer >::New( );
42 this->m_XPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( );
43 this->m_YPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( );
44 this->m_ZPlaneRenderer = vtkSmartPointer< vtkRenderer >::New( );
45 this->m_AuxRenderer = vtkSmartPointer< vtkRenderer >::New( );
46 this->m_3DRenderer->SetBackground( 0.2, 0.2, 0.2 );
47 this->m_XPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 );
48 this->m_YPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 );
49 this->m_ZPlaneRenderer->SetBackground( 0.1, 0.3, 0.8 );
50 this->m_AuxRenderer->SetBackground( 0.1, 0.3, 0.8 );
51 this->m_UI->m_3DVTK->GetRenderWindow( )->
52 AddRenderer( this->m_3DRenderer );
53 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->
54 AddRenderer( this->m_XPlaneRenderer );
55 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->
56 AddRenderer( this->m_YPlaneRenderer );
57 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->
58 AddRenderer( this->m_ZPlaneRenderer );
59 this->m_UI->m_AuxVTK->GetRenderWindow( )->
60 AddRenderer( this->m_AuxRenderer );
62 // Configure MPR actors
63 this->m_ImageActors = vtkSmartPointer< idms::VolumeActors >::New( );
66 this->m_XStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( );
67 this->m_YStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( );
68 this->m_ZStyle = vtkSmartPointer< idms::InteractorStyleImage >::New( );
69 this->m_XStyle->Configure( this->m_ImageActors, 0 );
70 this->m_YStyle->Configure( this->m_ImageActors, 1 );
71 this->m_ZStyle->Configure( this->m_ImageActors, 2 );
72 this->m_UI->m_XPlaneVTK->GetInteractor( )->
73 SetInteractorStyle( this->m_XStyle );
74 this->m_UI->m_YPlaneVTK->GetInteractor( )->
75 SetInteractorStyle( this->m_YStyle );
76 this->m_UI->m_ZPlaneVTK->GetInteractor( )->
77 SetInteractorStyle( this->m_ZStyle );
80 vtkSmartPointer< vtkAnnotatedCubeActor > oCube =
81 vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
82 oCube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
83 oCube->GetTextEdgesProperty( )->SetLineWidth( 1 );
84 oCube->GetTextEdgesProperty( )->SetDiffuse( 0 );
85 oCube->GetTextEdgesProperty( )->SetAmbient( 1 );
86 oCube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
87 oCube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
88 oCube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
89 oCube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
90 oCube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
91 oCube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
92 oCube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
93 oCube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
94 oCube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
95 oCube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
96 oCube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
97 oCube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
98 oCube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
100 vtkSmartPointer< vtkAxesActor > oAxes =
101 vtkSmartPointer< vtkAxesActor >::New( );
102 oAxes->AxisLabelsOff( );
103 oAxes->SetShaftTypeToCylinder( );
104 oAxes->SetTotalLength( 2.5, 2.5, 2.5 );
106 vtkSmartPointer< vtkPropAssembly > oActors =
107 vtkSmartPointer< vtkPropAssembly >::New( );
108 oActors->AddPart( oCube );
109 oActors->AddPart( oAxes );
111 this->m_3DOrientationWidget =
112 vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
113 this->m_3DOrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
114 this->m_3DOrientationWidget->SetOrientationMarker( oActors );
115 this->m_3DOrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
117 // Add actors, widgets, stuff, ...
118 this->m_3DOrientationWidget->
119 SetInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
120 this->m_3DOrientationWidget->SetEnabled( 1 );
121 this->m_3DOrientationWidget->InteractiveOff( );
123 // Qt signals <-> slots
124 IDMS_QT_ACTION( ReloadPlugins );
125 IDMS_QT_ACTION( OpenInputImage );
126 IDMS_QT_ACTION( OpenSegmentedImage );
128 this->m_UI->actionNavigation, SIGNAL( triggered( ) ),
129 this, SLOT( _triggered_actionSwitchMode( ) )
132 this->m_UI->actionSegmentationInteractiveDeformation,
133 SIGNAL( triggered( ) ),
134 this, SLOT( _triggered_actionSwitchMode( ) )
137 // Historic configuration
138 this->m_LastOpenedFile = ".";
140 // Start: load all disponible plugins
141 this->_triggered_actionReloadPlugins( );
144 // -------------------------------------------------------------------------
148 // Close all connections
149 this->m_Plugins.UnloadAll( );
153 if( this->m_InputImage != NULL ) delete this->m_InputImage;
154 if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage;
157 // -------------------------------------------------------------------------
159 _LoadApplicationPreferences( )
161 this->m_ApplicationPreferences.clear( );
162 std::ifstream in( this->m_ApplicationPreferencesFile.c_str( ) );
166 std::getline( in, line );
167 while( !( in.eof( ) ) )
169 long pos = line.find_last_of( "=" );
170 std::string key = line.substr( 0, pos );
171 std::string value = line.substr( pos + 1 );
173 std::remove_if( key.begin( ), key.end( ), isspace ), key.end( )
176 std::remove_if( value.begin( ), value.end( ), isspace ), value.end( )
178 this->m_ApplicationPreferences[ key ] = value;
179 std::getline( in, line );
185 this->m_ApplicationPreferences[ "data_dimensions" ] = "3";
186 this->m_ApplicationPreferences[ "input_image_type" ] = "short";
187 this->m_ApplicationPreferences[ "segmented_image_type" ] = "uchar";
188 this->m_ApplicationPreferences[ "mesh_type" ] = "double";
194 // -------------------------------------------------------------------------
196 TPluginData* MainWnd::
197 _LoadImage( const std::string& image_type, const std::string& image_dim )
200 // Show dialog and check if it was accepted
201 QFileDialog dialog( this );
202 dialog.setFileMode( QFileDialog::ExistingFiles );
203 dialog.setDirectory( tr( this->m_LastOpenedFile.c_str( ) ) );
204 dialog.setNameFilter(
205 tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
207 dialog.setDefaultSuffix( tr( "mhd" ) );
208 if( !( dialog.exec( ) ) )
211 TPluginData* ret = NULL;
212 unsigned int nFiles = dialog.selectedFiles( ).size( );
215 if( this->m_ImageReaderClassName == "" )
217 QMessageBox::critical(
219 tr( "No plugin to read a single image file found!" ),
220 tr( "No plugin to read a single image file found!" )
226 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
227 this->m_LastOpenedFile = fname;
230 dynamic_cast< TPlugin* >(
231 this->m_Plugins.CreateObject( this->m_ImageReaderClassName )
234 TParameters reader_params = reader->GetDefaultParameters( );
235 reader_params[ "FileName" ].second = fname;
236 reader_params[ "PixelType" ].second = image_type;
237 reader_params[ "ImageDimension" ].second = image_dim;
238 reader_params[ "IsColorImage" ].second = "0";
239 reader->SetParameters( reader_params );
240 std::string err = reader->Update( );
244 ret = reader->GetOutput( 0 );
245 reader->DisconnectOutputs( );
248 QMessageBox::critical(
250 tr( "Error reading single image" ),
256 else if( nFiles > 1 )
258 if( this->m_ImageSeriesReaderClassName == "" )
260 QMessageBox::critical(
262 tr( "No plugin to read an image series found!" ),
263 tr( "No plugin to read an image series found!" )
268 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
269 this->m_LastOpenedFile = fname;
277 // -------------------------------------------------------------------------
279 _UpdateEnabledFlags( )
281 bool img = ( this->m_InputImage != NULL );
282 this->m_UI->menuSegmentInputImage->setEnabled( img );
283 this->m_UI->actionOpenSegmentedImage->setEnabled( img );
284 this->m_UI->m_3DVTK->setEnabled( img );
285 this->m_UI->m_XPlaneVTK->setEnabled( img );
286 this->m_UI->m_YPlaneVTK->setEnabled( img );
287 this->m_UI->m_ZPlaneVTK->setEnabled( img );
288 this->m_UI->m_AuxVTK->setEnabled( img );
291 bool seg = this->m_Segmentation.IsNotNull( );
292 this->m_UI->menuFilterSegmentedImage->setEnabled( seg );
293 this->m_UI->menuExtractMesh->setEnabled( seg );
294 this->m_UI->actionOpenMesh->setEnabled( seg );
296 this->m_UI->actionNavigation->setEnabled( img && seg );
297 this->m_UI->actionSegmentationInteractiveDeformation->
298 setEnabled( img && seg );
302 // -------------------------------------------------------------------------
304 _triggered_actionReloadPlugins( )
306 if( this->_LoadPlugins( ) )
308 this->_UpdateEnabledFlags( );
312 QMessageBox::critical(
314 tr( "Could not load plugins from given file." ),
315 tr( "Could not load plugins from given file." )
320 this->m_Plugins.UnloadAll( );
322 this->m_ImageReaderClassName = "";
323 this->m_ImageSeriesReaderClassName = "";
324 this->m_ImageWriterClassName = "";
326 std::ifstream in( this->m_PluginsConfigurationFile.c_str( ) );
330 std::getline( in, plugin );
331 while( !( in.eof( ) ) )
333 if( this->m_Plugins.Load( plugin ) )
335 TPluginsInterface::TClassesIterator cIt =
336 this->m_Plugins.GetClasses( ).begin( );
337 TPluginsInterface::TClassesIterator end_cIt =
338 this->m_Plugins.GetClasses( ).end( );
339 for( ; cIt != end_cIt; ++cIt )
341 std::string c_name = cIt->first;
342 c_name = c_name.substr( c_name.find_last_of( ":" ) + 1 );
343 if( c_name == "ImageReader" )
345 this->m_ImageReaderClassName = cIt->first;
347 else if( c_name == "ImageSeriesReader" )
349 this->m_ImageSeriesReaderClassName = cIt->first;
351 else if( c_name == "ImageWriter" )
353 this->m_ImageWriterClassName = cIt->first;
361 TFilterPlugins::TClassesIterator cIt =
362 this->m_Plugins.BeginClasses( );
363 for( ; cIt != this->m_Plugins.EndClasses( ); ++cIt )
365 TFilterObject* filter =
366 this->m_Plugins.CreateObject( cIt->first );
369 std::string cat = filter->GetCategory( );
370 std::string catType = cat.substr( cat.find_last_of( ":" ) );
371 if( catType == ":BinaryImageToBinaryImageFilter" )
373 QAction* action = this->m_UI->menuFilterSegmentedImage->
374 addAction( QString( cIt->first.c_str( ) ) );
376 action, SIGNAL( triggered( ) ),
377 this, SLOT( triggered_aFilterSegmentedImage( ) )
380 else if( catType == ":ImageToMeshFilter" )
382 QAction* action = this->m_UI->menuExtractMesh->
383 addAction( QString( cIt->first.c_str( ) ) );
385 action, SIGNAL( triggered( ) ),
386 this, SLOT( triggered_aSegmentedImageToMesh( ) )
395 QMessageBox::warning(
397 tr( "Ignoring plugin" ),
398 tr( plugin.c_str( ) )
402 std::getline( in, plugin );
408 QMessageBox::critical(
410 tr( "No plugins file loaded!" ),
411 tr( this->m_PluginsConfigurationFile.c_str( ) )
417 if( this->m_ImageReaderClassName == "" )
419 QMessageBox::critical(
421 tr( "No ImageReader found in plugins!" ),
422 tr( this->m_PluginsConfigurationFile.c_str( ) )
427 if( this->m_ImageWriterClassName == "" )
429 QMessageBox::critical(
431 tr( "No ImageWriter found in plugins!" ),
432 tr( this->m_PluginsConfigurationFile.c_str( ) )
436 this->_UpdateEnabledFlags( );
440 // -------------------------------------------------------------------------
442 _triggered_actionOpenInputImage( )
444 if( this->m_InputImage != NULL )
445 delete this->m_InputImage;
448 this->m_ApplicationPreferences[ "input_image_type" ],
449 this->m_ApplicationPreferences[ "data_dimensions" ]
451 if( this->m_InputImage != NULL )
453 cpPlugins::Interface::Image* img =
454 dynamic_cast< cpPlugins::Interface::Image* >( this->m_InputImage );
455 this->m_ImageActors->Configure(
456 img->GetVTKImageData( ),
457 this->m_UI->m_XPlaneVTK->GetInteractor( ),
458 this->m_UI->m_YPlaneVTK->GetInteractor( ),
459 this->m_UI->m_ZPlaneVTK->GetInteractor( )
461 this->m_ImageActors->
462 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
465 this->m_3DRenderer->AddActor(
466 this->m_ImageActors->GetImageOutlineActor( )
468 this->m_3DRenderer->AddActor(
469 this->m_ImageActors->GetXBoundsActor( )
471 this->m_3DRenderer->AddActor(
472 this->m_ImageActors->GetYBoundsActor( )
474 this->m_3DRenderer->AddActor(
475 this->m_ImageActors->GetZBoundsActor( )
479 this->m_3DRenderer->ResetCamera( );
480 this->m_ImageActors->ResetCameras( );
483 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
484 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
485 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
486 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
488 // Update activations
489 this->_UpdateEnabledFlags( );
490 this->m_UI->actionNavigation->setChecked( true );
491 this->_triggered_actionSwitchMode( );
496 // -------------------------------------------------------------------------
498 _triggered_actionOpenSegmentedImage( )
500 if( this->m_SegmentedImage != NULL )
501 delete this->m_SegmentedImage;
502 this->m_SegmentedImage =
504 this->m_ApplicationPreferences[ "segmented_image_type" ],
505 this->m_ApplicationPreferences[ "data_dimensions" ]
507 if( this->m_SegmentedImage != NULL )
509 cpPlugins::Interface::Image* img =
510 dynamic_cast< cpPlugins::Interface::Image* >( this->m_SegmentedImage );
511 this->m_ImageActors->SetSegmentation( img->GetVTKImageData( ) );
514 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
515 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
516 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
517 this->_UpdateEnabledFlags( );
522 // -------------------------------------------------------------------------
524 _triggered_actionSwitchMode( )
526 QAction* snd = dynamic_cast< QAction* >( this->sender( ) );
527 if( snd == this->m_UI->actionNavigation )
529 this->m_UI->actionSegmentationInteractiveDeformation->setChecked(
530 !( this->m_UI->actionNavigation->isChecked( ) )
533 else if( snd == this->m_UI->actionSegmentationInteractiveDeformation )
535 this->m_UI->actionNavigation->setChecked(
536 !( this->m_UI->actionSegmentationInteractiveDeformation->isChecked( ) )
541 this->m_UI->actionNavigation->setChecked( true );
542 this->m_UI->actionSegmentationInteractiveDeformation->setChecked( false );
547 if( this->m_UI->aNavigation->isChecked( ) )
549 this->m_XStyle->SetModeToNavigation( );
550 this->m_YStyle->SetModeToNavigation( );
551 this->m_ZStyle->SetModeToNavigation( );
552 this->m_ImageActors->HideRegion( 0 );
553 this->m_ImageActors->HideRegion( 1 );
554 this->m_ImageActors->HideRegion( 2 );
555 this->m_3DRenderer->RemoveActor(
556 this->m_ImageActors->GetCursorActor( )
558 this->m_3DRenderer->RemoveActor(
559 this->m_ImageActors->GetRegionActor( )
561 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
563 else if( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) )
565 this->m_XStyle->SetModeToDeformation( );
566 this->m_YStyle->SetModeToDeformation( );
567 this->m_ZStyle->SetModeToDeformation( );
568 this->m_ImageActors->ShowRegion( 0 );
569 this->m_ImageActors->ShowRegion( 1 );
570 this->m_ImageActors->ShowRegion( 2 );
571 this->m_3DRenderer->AddActor(
572 this->m_ImageActors->GetCursorActor( )
574 this->m_3DRenderer->AddActor(
575 this->m_ImageActors->GetRegionActor( )
577 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
583 // -------------------------------------------------------------------------
586 // -------------------------------------------------------------------------
588 _ParametersDialog( TParameters& parameters )
591 QGridLayout gridLayout( &dlg );
592 QVBoxLayout verticalLayout;
595 typedef std::map< std::string, QWidget* > _TWidgets;
597 TParameters::const_iterator pIt = parameters.begin( );
598 for( ; pIt != parameters.end( ); ++pIt )
600 unsigned long pos = pIt->first.find_last_of( ":" );
601 std::string v_name = pIt->first.substr( 0, pos );
602 std::string v_type = pIt->first.substr( pos + 1 );
604 QHBoxLayout* horizontalLayout = new QHBoxLayout( );
605 QLabel* label = new QLabel( &dlg );
606 label->setText( QString( v_name.c_str( ) ) );
607 horizontalLayout->addWidget( label );
608 if( v_type == "real" )
610 QDoubleSpinBox* v_double = new QDoubleSpinBox( &dlg );
611 v_double->setDecimals( 3 );
612 v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
613 v_double->setMaximum( std::numeric_limits< double >::max( ) );
614 v_double->setValue( std::atof( pIt->second.c_str( ) ) );
615 horizontalLayout->addWidget( v_double );
616 widgets[ pIt->first ] = v_double;
618 else if( v_type == "atomic_real" )
620 if( v_name == "MeshType" )
622 QLabel* info = new QLabel( &dlg );
623 if( typeid( TScalar ) == typeid( float ) )
624 info->setText( QString( "float" ) );
625 else if( typeid( TScalar ) == typeid( double ) )
626 info->setText( QString( "double" ) );
627 horizontalLayout->addWidget( info );
628 widgets[ pIt->first ] = info;
633 verticalLayout.addLayout( horizontalLayout );
636 gridLayout.addLayout( &verticalLayout, 0, 0, 1, 1 );
639 QDialogButtonBox buttonBox( &dlg );
640 buttonBox.setOrientation( Qt::Horizontal );
641 buttonBox.setStandardButtons(
642 QDialogButtonBox::Cancel | QDialogButtonBox::Ok
644 gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 );
646 &buttonBox, SIGNAL( accepted( ) ),
647 &dlg, SLOT( accept( ) )
650 &buttonBox, SIGNAL( rejected( ) ),
651 &dlg, SLOT( reject( ) )
653 QMetaObject::connectSlotsByName( &dlg );
656 if( dlg.exec( ) == QDialog::Accepted )
658 _TWidgets::const_iterator wIt = widgets.begin( );
659 for( ; wIt != widgets.end( ); ++wIt )
661 unsigned long pos = wIt->first.find_last_of( ":" );
662 std::string v_name = wIt->first.substr( 0, pos );
663 std::string v_type = wIt->first.substr( pos + 1 );
664 std::stringstream sstr;
665 if( v_type == "real" )
667 QDoubleSpinBox* v_double =
668 dynamic_cast< QDoubleSpinBox* >( wIt->second );
669 if( v_double != NULL )
670 sstr << v_double->value( );
672 else if( v_type == "atomic_real" )
674 if( v_name == "MeshType" )
676 QLabel* info = dynamic_cast< QLabel* >( wIt->second );
678 sstr << info->text( ).toStdString( );
683 parameters[ wIt->first ] = sstr.str( );
691 // -------------------------------------------------------------------------
694 _LoadImage( typename I::Pointer& image )
697 QFileDialog::getOpenFileNames(
699 tr( "Open an image" ),
700 tr( this->m_LastOpenedFile.c_str( ) ),
701 tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
703 if( qList.size( ) == 0 )
707 QStringList::Iterator fIt = qList.begin( );
708 if( qList.size( ) == 1 )
710 // Read a single image
711 std::string fn = fIt->toStdString( );
712 this->m_LastOpenedFile = fn;
714 typename itk::ImageFileReader< I >::Pointer reader =
715 itk::ImageFileReader< I >::New( );
716 reader->SetFileName( fn );
721 catch( itk::ExceptionObject& err )
723 QMessageBox::critical(
725 tr( "Error opening single image!" ),
726 tr( err.GetDescription( ) )
731 image = reader->GetOutput( );
732 image->DisconnectPipeline( );
734 else if( qList.size( ) > 1 )
736 typedef std::set< std::string > _TOrderedStringList;
739 _TOrderedStringList filenames;
740 for( ; fIt != qList.end( ); ++fIt )
741 filenames.insert( fIt->toStdString( ) );
742 typename itk::ImageSeriesReader< I >::Pointer reader =
743 itk::ImageSeriesReader< I >::New( );
744 reader->SetImageIO( itk::GDCMImageIO::New( ) );
745 _TOrderedStringList::const_iterator oIt = filenames.begin( );
746 for( ; oIt != filenames.end( ); ++oIt )
748 reader->AddFileName( *oIt );
749 this->m_LastOpenedFile = *oIt;
756 catch( itk::ExceptionObject& err )
758 QMessageBox::critical(
760 tr( "Error opening image series!" ),
761 tr( err.GetDescription( ) )
766 image = reader->GetOutput( );
767 image->DisconnectPipeline( );
773 // -------------------------------------------------------------------------
775 triggered_aReloadPlugins( )
779 // -------------------------------------------------------------------------
781 triggered_aOpenInputImage( )
783 if( this->_LoadImage< TImage >( this->m_Image ) )
785 // Connect image to VTK
786 this->m_VTKImage = TVTKImage::New( );
787 this->m_VTKImage->SetInput( this->m_Image );
788 this->m_VTKImage->Update( );
790 this->m_ImageActors->Configure(
791 this->m_VTKImage->GetOutput( ),
792 this->m_UI->m_XPlaneVTK->GetInteractor( ),
793 this->m_UI->m_YPlaneVTK->GetInteractor( ),
794 this->m_UI->m_ZPlaneVTK->GetInteractor( )
796 this->m_ImageActors->
797 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
800 this->m_3DRenderer->AddActor(
801 this->m_ImageActors->GetImageOutlineActor( )
803 this->m_3DRenderer->AddActor(
804 this->m_ImageActors->GetXBoundsActor( )
806 this->m_3DRenderer->AddActor(
807 this->m_ImageActors->GetYBoundsActor( )
809 this->m_3DRenderer->AddActor(
810 this->m_ImageActors->GetZBoundsActor( )
814 this->m_3DRenderer->ResetCamera( );
815 this->m_ImageActors->ResetCameras( );
818 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
819 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
820 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
821 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
822 this->_UpdateEnabledFlags( );
823 this->m_UI->aNavigation->setChecked( true );
824 this->triggered_aSwitchMode( );
829 // -------------------------------------------------------------------------
831 triggered_aOpenSegmentedImage( )
833 if( this->_LoadImage< TImage >( this->m_Segmentation ) )
835 // Connect image to VTK
836 this->m_VTKSegmentation = TVTKImage::New( );
837 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
838 this->m_VTKSegmentation->Update( );
840 this->m_ImageActors->SetSegmentation(
841 this->m_VTKSegmentation->GetOutput( )
845 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
846 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
847 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
848 this->_UpdateEnabledFlags( );
853 // -------------------------------------------------------------------------
855 triggered_aFilterSegmentedImage( )
858 if( this->m_Segmentation.IsNull( ) )
860 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
863 std::string filter_name = action->text( ).toStdString( );
866 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
870 TParameters parameters = filter->GetDefaultParameters( );
871 if( !( this->_ParametersDialog( parameters ) ) )
873 filter->SetInput( this->m_Segmentation );
874 filter->SetParameters( parameters );
875 std::string result = filter->Update( );
877 // Get modified segmentation
878 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
879 if( this->m_Mesh.IsNotNull( ) )
881 this->m_Mesh->DisconnectPipeline( );
884 // Ok, it seems to have runned fine
888 // -------------------------------------------------------------------------
890 triggered_aSegmentedImageToMesh( )
893 if( this->m_Segmentation.IsNull( ) )
895 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
898 std::string filter_name = action->text( ).toStdString( );
901 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
905 TParameters parameters = filter->GetDefaultParameters( );
906 if( !( this->_ParametersDialog( parameters ) ) )
908 filter->SetInput( this->m_Segmentation );
909 filter->SetParameters( parameters );
910 std::string result = filter->Update( );
913 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
914 if( this->m_Mesh.IsNotNull( ) )
916 this->m_Mesh->DisconnectPipeline( );
920 // Ok, it seems to have runned fine
925 // -------------------------------------------------------------------------
928 _SliceMesh( int axis )
930 TCutter* cutter = NULL;
931 if( axis == 2 ) cutter = this->m_ZCutter;
936 vtkPlane* vplane = this->m_ImageActors->GetSlicePlane( axis );
937 double vorigin[ 3 ], vnormal[ 3 ];
938 vplane->GetOrigin( vorigin );
939 vplane->GetNormal( vnormal );
941 TCutter::TVector corigin, cnormal;
942 corigin[ 0 ] = TScalar( vorigin[ 0 ] );
943 corigin[ 1 ] = TScalar( vorigin[ 1 ] );
944 corigin[ 2 ] = TScalar( vorigin[ 2 ] );
945 cnormal[ 0 ] = TScalar( vnormal[ 0 ] );
946 cnormal[ 1 ] = TScalar( vnormal[ 1 ] );
947 cnormal[ 2 ] = TScalar( vnormal[ 2 ] );
949 cutter->SetPlanePoint( corigin );
950 cutter->SetPlaneNormal( cnormal );
954 // -------------------------------------------------------------------------
958 long unsigned int eventId,
959 void* clientData, void* callData
962 if( clientData == NULL || callData == NULL )
964 MainWnd* wnd = reinterpret_cast< MainWnd* >( clientData );
965 int axis = *( reinterpret_cast< int* >( callData ) );
968 if( eventId == idms::InteractorStyleImage::SliceEvent )
969 wnd->_SliceMesh( axis );
972 // -------------------------------------------------------------------------
974 triggered_aLoadImage( )
976 if( this->_LoadImage< TImage >( this->m_Image ) )
978 // Connect image to VTK
979 this->m_VTKImage->SetInput( this->m_Image );
980 this->m_VTKImage->Update( );
981 this->m_ImageActors->Configure(
982 this->m_VTKImage->GetOutput( ),
983 this->m_UI->m_XPlaneVTK->GetInteractor( ),
984 this->m_UI->m_YPlaneVTK->GetInteractor( ),
985 this->m_UI->m_ZPlaneVTK->GetInteractor( )
987 this->m_ImageActors->
988 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
991 this->m_3DRenderer->AddActor(
992 this->m_ImageActors->GetImageOutlineActor( )
994 this->m_3DRenderer->AddActor(
995 this->m_ImageActors->GetXBoundsActor( )
997 this->m_3DRenderer->AddActor(
998 this->m_ImageActors->GetYBoundsActor( )
1000 this->m_3DRenderer->AddActor(
1001 this->m_ImageActors->GetZBoundsActor( )
1004 // Reset all cameras
1005 this->m_3DRenderer->ResetCamera( );
1006 this->m_ImageActors->ResetCameras( );
1009 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
1010 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
1011 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
1012 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
1014 // Activate controls
1015 this->m_UI->aLoadSegmentedImage->setEnabled( true );
1016 this->m_UI->aSegmentImage->setEnabled( true );
1017 this->m_UI->m_3DVTK->setEnabled( true );
1018 this->m_UI->m_XPlaneVTK->setEnabled( true );
1019 this->m_UI->m_YPlaneVTK->setEnabled( true );
1020 this->m_UI->m_ZPlaneVTK->setEnabled( true );
1025 // -------------------------------------------------------------------------
1027 triggered_aLoadSegmentedImage( )
1029 if( this->m_Mesh.IsNotNull( ) )
1031 QMessageBox::critical(
1033 tr( "Mesh already loaded!" ),
1034 tr( "Mesh already loaded!" )
1040 if( this->_LoadImage< TImage >( this->m_Segmentation ) )
1042 // Compute segmentation values
1043 itk::MinimumMaximumImageCalculator< TImage >::Pointer minmax =
1044 itk::MinimumMaximumImageCalculator< TImage >::New( );
1045 minmax->SetImage( this->m_Segmentation );
1047 TPixel min_v = minmax->GetMinimum( );
1048 TPixel max_v = minmax->GetMaximum( );
1049 double thr = double( max_v + min_v ) / double( 2 );
1051 typedef itk::Image< TScalar, Dimension > _TScalarImage;
1053 itk::BinaryMinMaxCurvatureFlowImageFilter< TImage, _TScalarImage >
1055 typedef _TFilter::TimeStepType _TTimeStep;
1056 typedef _TFilter::RadiusValueType _TRadius;
1058 _TFilter::Pointer filter = _TFilter::New( );
1059 filter->SetInput( this->m_Segmentation );
1060 filter->SetTimeStep( _TTimeStep( 0.0625 ) );
1061 filter->SetNumberOfIterations( 10 );
1062 filter->SetStencilRadius( _TRadius( 3 ) );
1063 filter->SetThreshold( thr );
1066 itk::ImageFileWriter< _TScalarImage >::Pointer w =
1067 itk::ImageFileWriter< _TScalarImage >::New( );
1068 w->SetInput( filter->GetOutput( ) );
1069 w->SetFileName( "no_noise.mhd" );
1074 itk::LaplacianRecursiveGaussianImageFilter< TImage, _TScalarImage >
1076 _TFilter::Pointer filter = _TFilter::New( );
1077 filter->SetInput( this->m_Segmentation );
1078 filter->SetSigma( 3 ); // in spacing units
1079 filter->SetNormalizeAcrossScale( false );
1081 typedef itk::ThresholdImageFilter< _TScalarImage > _TThreshold;
1082 _TThreshold::Pointer threshold = _TThreshold::New( );
1083 threshold->SetInput( filter->GetOutput( ) );
1084 threshold->ThresholdAbove( TScalar( 0 ) );
1085 threshold->InPlaceOff( );
1086 threshold->Update( );
1088 itk::MinimumMaximumImageCalculator< _TScalarImage >::Pointer t_minmax =
1089 itk::MinimumMaximumImageCalculator< _TScalarImage >::New( );
1090 t_minmax->SetImage( threshold->GetOutput( ) );
1091 t_minmax->Compute( );
1092 TScalar min_t = t_minmax->GetMinimum( );
1094 std::cout << min_t << " " << t_minmax->GetMaximum( ) << std::endl;
1096 itk::SubtractImageFilter< _TScalarImage >::Pointer subtract =
1097 itk::SubtractImageFilter< _TScalarImage >::New( );
1098 subtract->SetInput1( threshold->GetOutput( ) );
1099 subtract->SetConstant2( min_t );
1101 itk::ImageFileWriter< _TScalarImage >::Pointer w =
1102 itk::ImageFileWriter< _TScalarImage >::New( );
1103 w->SetInput( subtract->GetOutput( ) );
1104 w->SetFileName( "no_noise_laplace_2.mhd" );
1108 // Pass segmentation to VTK
1109 this->m_VTKSegmentation = TVTKImage::New( );
1110 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
1111 this->m_VTKSegmentation->Update( );
1113 // Use VTK's marching cubes (it is smoother)
1114 vtkSmartPointer< vtkImageMarchingCubes > segmentation_mc =
1115 vtkSmartPointer< vtkImageMarchingCubes >::New( );
1116 segmentation_mc->SetInputData( this->m_VTKSegmentation->GetOutput( ) );
1117 segmentation_mc->SetValue( 0, thr );
1118 segmentation_mc->Update( );
1120 // Go back to ITK world
1121 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > _TVTKPDataToMesh;
1122 _TVTKPDataToMesh::Pointer itk_mc = _TVTKPDataToMesh::New( );
1123 itk_mc->SetInput( segmentation_mc->GetOutput( ) );
1125 this->m_Mesh = itk_mc->GetOutput( );
1126 this->m_Mesh->DisconnectPipeline( );
1128 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
1129 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
1131 this->m_MeshMapper->SetInputData( this->m_Mesh );
1132 this->m_MeshActor->SetMapper( this->m_MeshMapper );
1133 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
1134 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
1135 this->m_3DRenderer->AddActor( this->m_MeshActor );
1136 this->m_3DRenderer->ResetCamera( );
1137 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
1139 unsigned int reduction = 20;
1141 typedef TImage::SpacingType::ValueType _TValue;
1144 // Compute downsize parameters
1145 TImage::SizeType o_size =
1146 segmentation->GetLargestPossibleRegion( ).GetSize( );
1147 TImage::SpacingType o_spac = segmentation->GetSpacing( );
1148 _TValue min_spac = std::numeric_limits< _TValue >::max( );
1149 for( unsigned int d = 0; d < Dimension; ++d )
1150 min_spac = ( o_spac[ d ] < min_spac )? o_spac[ d ]: min_spac;
1151 min_spac *= _TValue( reduction );
1152 TImage::SpacingType n_spac( min_spac );
1153 TImage::SizeType n_size;
1154 for( unsigned int d = 0; d < Dimension; ++d )
1155 n_size[ d ] = ( unsigned long )(
1156 _TValue( o_size[ d ] ) * o_spac[ d ] / min_spac
1160 typedef itk::Image< TScalar, Dimension > _TScalarImage;
1161 typedef itk::IdentityTransform< TScalar, Dimension > _TTransform;
1163 itk::LinearInterpolateImageFunction< TImage, TScalar >
1166 itk::ResampleImageFilter< TImage, _TScalarImage, TScalar, TScalar >
1168 _TResample::Pointer resample = _TResample::New( );
1169 resample->SetInput( segmentation );
1170 resample->SetSize( n_size );
1171 resample->SetOutputDirection( segmentation->GetDirection( ) );
1172 resample->SetOutputOrigin( segmentation->GetOrigin( ) );
1173 resample->SetOutputSpacing( n_spac );
1174 resample->SetTransform( _TTransform::New( ) );
1175 resample->SetInterpolator( _TInterpolator::New( ) );
1176 resample->UpdateLargestPossibleRegion( );
1180 itk::SignedDanielssonDistanceMapImageFilter< _TScalarImage, _TScalarImage >
1182 _TDanielsson::Pointer danielsson = _TDanielsson::New( );
1183 danielsson->SetInput( resample->GetOutput( ) );
1184 danielsson->Update( );
1186 // Go back to ITK world
1187 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > TVTKPDataToMesh;
1188 TVTKPDataToMesh::Pointer itk_mc = TVTKPDataToMesh::New( );
1189 itk_mc->SetInput( danielsson_mc->GetOutput( ) );
1191 this->m_Mesh = itk_mc->GetOutput( );
1192 this->m_Mesh->DisconnectPipeline( );
1194 this->m_ZCutter = TCutter::New( );
1195 this->m_ZCutter->SetInput( this->m_Mesh );
1197 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
1198 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
1200 this->m_MeshMapper->SetInputData( this->m_Mesh );
1201 this->m_MeshActor->SetMapper( this->m_MeshMapper );
1202 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
1203 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
1204 this->m_3DRenderer->AddActor( this->m_MeshActor );
1205 this->m_3DRenderer->ResetCamera( );
1206 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );