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 // -------------------------------------------------------------------------
149 if( this->m_InputImage != NULL ) delete this->m_InputImage;
150 if( this->m_SegmentedImage != NULL ) delete this->m_SegmentedImage;
153 // -------------------------------------------------------------------------
155 _LoadApplicationPreferences( )
157 this->m_ApplicationPreferences.clear( );
158 std::ifstream in( this->m_ApplicationPreferencesFile.c_str( ) );
162 std::getline( in, line );
163 while( !( in.eof( ) ) )
165 long pos = line.find_last_of( "=" );
166 std::string key = line.substr( 0, pos );
167 std::string value = line.substr( pos + 1 );
169 std::remove_if( key.begin( ), key.end( ), isspace ), key.end( )
172 std::remove_if( value.begin( ), value.end( ), isspace ), value.end( )
174 this->m_ApplicationPreferences[ key ] = value;
175 std::getline( in, line );
181 this->m_ApplicationPreferences[ "data_dimensions" ] = "3";
182 this->m_ApplicationPreferences[ "input_image_type" ] = "short";
183 this->m_ApplicationPreferences[ "segmented_image_type" ] = "uchar";
184 this->m_ApplicationPreferences[ "mesh_type" ] = "double";
190 // -------------------------------------------------------------------------
192 TPluginData* MainWnd::
193 _LoadImage( const std::string& image_type, const std::string& image_dim )
195 // Show dialog and check if it was accepted
196 QFileDialog dialog( this );
197 dialog.setFileMode( QFileDialog::ExistingFiles );
198 dialog.setDirectory( tr( this->m_LastOpenedFile.c_str( ) ) );
199 dialog.setNameFilter(
200 tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
202 dialog.setDefaultSuffix( tr( "mhd" ) );
203 if( !( dialog.exec( ) ) )
206 TPluginData* ret = NULL;
207 unsigned int nFiles = dialog.selectedFiles( ).size( );
210 if( this->m_ImageReaderClassName == "" )
212 QMessageBox::critical(
214 tr( "No plugin to read a single image file found!" ),
215 tr( "No plugin to read a single image file found!" )
221 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
222 this->m_LastOpenedFile = fname;
225 dynamic_cast< TPlugin* >(
226 this->m_Plugins.CreateObject( this->m_ImageReaderClassName )
229 TParameters reader_params = reader->GetDefaultParameters( );
230 reader_params[ "FileName" ].second = fname;
231 reader_params[ "PixelType" ].second = image_type;
232 reader_params[ "ImageDimension" ].second = image_dim;
233 reader_params[ "IsColorImage" ].second = "0";
234 reader->SetParameters( reader_params );
235 std::string err = reader->Update( );
239 ret = reader->GetOutput( 0 );
240 reader->DisconnectOutputs( );
243 QMessageBox::critical(
245 tr( "Error reading single image" ),
251 else if( nFiles > 1 )
253 if( this->m_ImageSeriesReaderClassName == "" )
255 QMessageBox::critical(
257 tr( "No plugin to read an image series found!" ),
258 tr( "No plugin to read an image series found!" )
265 std::string fname = dialog.selectedFiles( ).at( 0 ).toStdString( );
266 this->m_LastOpenedFile = fname;
274 // -------------------------------------------------------------------------
276 _UpdateEnabledFlags( )
278 bool img = ( this->m_InputImage != NULL );
279 this->m_UI->menuSegmentInputImage->setEnabled( img );
280 this->m_UI->actionOpenSegmentedImage->setEnabled( img );
281 this->m_UI->m_3DVTK->setEnabled( img );
282 this->m_UI->m_XPlaneVTK->setEnabled( img );
283 this->m_UI->m_YPlaneVTK->setEnabled( img );
284 this->m_UI->m_ZPlaneVTK->setEnabled( img );
285 this->m_UI->m_AuxVTK->setEnabled( img );
288 bool seg = this->m_Segmentation.IsNotNull( );
289 this->m_UI->menuFilterSegmentedImage->setEnabled( seg );
290 this->m_UI->menuExtractMesh->setEnabled( seg );
291 this->m_UI->actionOpenMesh->setEnabled( seg );
293 this->m_UI->actionNavigation->setEnabled( img && seg );
294 this->m_UI->actionSegmentationInteractiveDeformation->
295 setEnabled( img && seg );
299 // -------------------------------------------------------------------------
301 _triggered_actionReloadPlugins( )
303 this->m_Plugins.UnloadAll( );
305 this->m_ImageReaderClassName = "";
306 this->m_ImageSeriesReaderClassName = "";
307 this->m_ImageWriterClassName = "";
309 std::ifstream in( this->m_PluginsConfigurationFile.c_str( ) );
313 std::getline( in, plugin );
314 while( !( in.eof( ) ) )
316 if( this->m_Plugins.Load( plugin ) )
318 TPluginsInterface::TClassesIterator cIt =
319 this->m_Plugins.GetClasses( ).begin( );
320 TPluginsInterface::TClassesIterator end_cIt =
321 this->m_Plugins.GetClasses( ).end( );
322 for( ; cIt != end_cIt; ++cIt )
324 std::string c_name = cIt->first;
325 c_name = c_name.substr( c_name.find_last_of( ":" ) + 1 );
326 if( c_name == "ImageReader" )
328 this->m_ImageReaderClassName = cIt->first;
330 else if( c_name == "ImageWriter" )
332 this->m_ImageWriterClassName = cIt->first;
341 TFilterPlugins::TClassesIterator cIt =
342 this->m_Plugins.BeginClasses( );
343 for( ; cIt != this->m_Plugins.EndClasses( ); ++cIt )
345 TFilterObject* filter =
346 this->m_Plugins.CreateObject( cIt->first );
349 std::string cat = filter->GetCategory( );
350 std::string catType = cat.substr( cat.find_last_of( ":" ) );
351 if( catType == ":BinaryImageToBinaryImageFilter" )
353 QAction* action = this->m_UI->menuFilterSegmentedImage->
354 addAction( QString( cIt->first.c_str( ) ) );
356 action, SIGNAL( triggered( ) ),
357 this, SLOT( triggered_aFilterSegmentedImage( ) )
360 else if( catType == ":ImageToMeshFilter" )
362 QAction* action = this->m_UI->menuExtractMesh->
363 addAction( QString( cIt->first.c_str( ) ) );
365 action, SIGNAL( triggered( ) ),
366 this, SLOT( triggered_aSegmentedImageToMesh( ) )
376 QMessageBox::warning(
378 tr( "Ignoring plugin" ),
379 tr( plugin.c_str( ) )
383 std::getline( in, plugin );
389 QMessageBox::critical(
391 tr( "No plugins file loaded!" ),
392 tr( this->m_PluginsConfigurationFile.c_str( ) )
398 if( this->m_ImageReaderClassName == "" )
400 QMessageBox::critical(
402 tr( "No ImageReader found in plugins!" ),
403 tr( this->m_PluginsConfigurationFile.c_str( ) )
408 if( this->m_ImageWriterClassName == "" )
410 QMessageBox::critical(
412 tr( "No ImageWriter found in plugins!" ),
413 tr( this->m_PluginsConfigurationFile.c_str( ) )
417 this->_UpdateEnabledFlags( );
420 // -------------------------------------------------------------------------
422 _triggered_actionOpenInputImage( )
424 if( this->m_InputImage != NULL )
425 delete this->m_InputImage;
428 this->m_ApplicationPreferences[ "input_image_type" ],
429 this->m_ApplicationPreferences[ "data_dimensions" ]
431 if( this->m_InputImage != NULL )
433 cpPlugins::Interface::Image* img =
434 dynamic_cast< cpPlugins::Interface::Image* >( this->m_InputImage );
435 this->m_ImageActors->Configure(
436 img->GetVTKImageData( ),
437 this->m_UI->m_XPlaneVTK->GetInteractor( ),
438 this->m_UI->m_YPlaneVTK->GetInteractor( ),
439 this->m_UI->m_ZPlaneVTK->GetInteractor( )
441 this->m_ImageActors->
442 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
445 this->m_3DRenderer->AddActor(
446 this->m_ImageActors->GetImageOutlineActor( )
448 this->m_3DRenderer->AddActor(
449 this->m_ImageActors->GetXBoundsActor( )
451 this->m_3DRenderer->AddActor(
452 this->m_ImageActors->GetYBoundsActor( )
454 this->m_3DRenderer->AddActor(
455 this->m_ImageActors->GetZBoundsActor( )
459 this->m_3DRenderer->ResetCamera( );
460 this->m_ImageActors->ResetCameras( );
463 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
464 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
465 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
466 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
468 // Update activations
469 this->_UpdateEnabledFlags( );
470 this->m_UI->actionNavigation->setChecked( true );
471 this->_triggered_actionSwitchMode( );
476 // -------------------------------------------------------------------------
478 _triggered_actionOpenSegmentedImage( )
480 if( this->m_SegmentedImage != NULL )
481 delete this->m_SegmentedImage;
482 this->m_SegmentedImage =
484 this->m_ApplicationPreferences[ "segmented_image_type" ],
485 this->m_ApplicationPreferences[ "data_dimensions" ]
487 if( this->m_SegmentedImage != NULL )
489 cpPlugins::Interface::Image* img =
490 dynamic_cast< cpPlugins::Interface::Image* >( this->m_SegmentedImage );
491 this->m_ImageActors->SetSegmentation( img->GetVTKImageData( ) );
494 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
495 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
496 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
497 this->_UpdateEnabledFlags( );
500 this->m_ImageActors->Configure(
501 img->GetVTKImageData( ),
502 this->m_UI->m_XPlaneVTK->GetInteractor( ),
503 this->m_UI->m_YPlaneVTK->GetInteractor( ),
504 this->m_UI->m_ZPlaneVTK->GetInteractor( )
506 this->m_ImageActors->
507 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
510 this->m_3DRenderer->AddActor(
511 this->m_ImageActors->GetImageOutlineActor( )
513 this->m_3DRenderer->AddActor(
514 this->m_ImageActors->GetXBoundsActor( )
516 this->m_3DRenderer->AddActor(
517 this->m_ImageActors->GetYBoundsActor( )
519 this->m_3DRenderer->AddActor(
520 this->m_ImageActors->GetZBoundsActor( )
524 this->m_3DRenderer->ResetCamera( );
525 this->m_ImageActors->ResetCameras( );
528 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
529 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
530 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
531 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
533 // Update activations
534 this->_UpdateEnabledFlags( );
535 this->m_UI->actionNavigation->setChecked( true );
536 this->_triggered_actionSwitchMode( );
542 // -------------------------------------------------------------------------
544 _triggered_actionSwitchMode( )
546 QAction* snd = dynamic_cast< QAction* >( this->sender( ) );
547 if( snd == this->m_UI->actionNavigation )
549 this->m_UI->actionSegmentationInteractiveDeformation->setChecked(
550 !( this->m_UI->actionNavigation->isChecked( ) )
553 else if( snd == this->m_UI->actionSegmentationInteractiveDeformation )
555 this->m_UI->actionNavigation->setChecked(
556 !( this->m_UI->actionSegmentationInteractiveDeformation->isChecked( ) )
561 this->m_UI->actionNavigation->setChecked( true );
562 this->m_UI->actionSegmentationInteractiveDeformation->setChecked( false );
567 if( this->m_UI->aNavigation->isChecked( ) )
569 this->m_XStyle->SetModeToNavigation( );
570 this->m_YStyle->SetModeToNavigation( );
571 this->m_ZStyle->SetModeToNavigation( );
572 this->m_ImageActors->HideRegion( 0 );
573 this->m_ImageActors->HideRegion( 1 );
574 this->m_ImageActors->HideRegion( 2 );
575 this->m_3DRenderer->RemoveActor(
576 this->m_ImageActors->GetCursorActor( )
578 this->m_3DRenderer->RemoveActor(
579 this->m_ImageActors->GetRegionActor( )
581 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
583 else if( this->m_UI->aSegmentationInteractiveDeformation->isChecked( ) )
585 this->m_XStyle->SetModeToDeformation( );
586 this->m_YStyle->SetModeToDeformation( );
587 this->m_ZStyle->SetModeToDeformation( );
588 this->m_ImageActors->ShowRegion( 0 );
589 this->m_ImageActors->ShowRegion( 1 );
590 this->m_ImageActors->ShowRegion( 2 );
591 this->m_3DRenderer->AddActor(
592 this->m_ImageActors->GetCursorActor( )
594 this->m_3DRenderer->AddActor(
595 this->m_ImageActors->GetRegionActor( )
597 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
603 // -------------------------------------------------------------------------
606 // -------------------------------------------------------------------------
608 _ParametersDialog( TParameters& parameters )
611 QGridLayout gridLayout( &dlg );
612 QVBoxLayout verticalLayout;
615 typedef std::map< std::string, QWidget* > _TWidgets;
617 TParameters::const_iterator pIt = parameters.begin( );
618 for( ; pIt != parameters.end( ); ++pIt )
620 unsigned long pos = pIt->first.find_last_of( ":" );
621 std::string v_name = pIt->first.substr( 0, pos );
622 std::string v_type = pIt->first.substr( pos + 1 );
624 QHBoxLayout* horizontalLayout = new QHBoxLayout( );
625 QLabel* label = new QLabel( &dlg );
626 label->setText( QString( v_name.c_str( ) ) );
627 horizontalLayout->addWidget( label );
628 if( v_type == "real" )
630 QDoubleSpinBox* v_double = new QDoubleSpinBox( &dlg );
631 v_double->setDecimals( 3 );
632 v_double->setMinimum( -( std::numeric_limits< double >::max( ) ) );
633 v_double->setMaximum( std::numeric_limits< double >::max( ) );
634 v_double->setValue( std::atof( pIt->second.c_str( ) ) );
635 horizontalLayout->addWidget( v_double );
636 widgets[ pIt->first ] = v_double;
638 else if( v_type == "atomic_real" )
640 if( v_name == "MeshType" )
642 QLabel* info = new QLabel( &dlg );
643 if( typeid( TScalar ) == typeid( float ) )
644 info->setText( QString( "float" ) );
645 else if( typeid( TScalar ) == typeid( double ) )
646 info->setText( QString( "double" ) );
647 horizontalLayout->addWidget( info );
648 widgets[ pIt->first ] = info;
653 verticalLayout.addLayout( horizontalLayout );
656 gridLayout.addLayout( &verticalLayout, 0, 0, 1, 1 );
659 QDialogButtonBox buttonBox( &dlg );
660 buttonBox.setOrientation( Qt::Horizontal );
661 buttonBox.setStandardButtons(
662 QDialogButtonBox::Cancel | QDialogButtonBox::Ok
664 gridLayout.addWidget( &buttonBox, 1, 0, 1, 1 );
666 &buttonBox, SIGNAL( accepted( ) ),
667 &dlg, SLOT( accept( ) )
670 &buttonBox, SIGNAL( rejected( ) ),
671 &dlg, SLOT( reject( ) )
673 QMetaObject::connectSlotsByName( &dlg );
676 if( dlg.exec( ) == QDialog::Accepted )
678 _TWidgets::const_iterator wIt = widgets.begin( );
679 for( ; wIt != widgets.end( ); ++wIt )
681 unsigned long pos = wIt->first.find_last_of( ":" );
682 std::string v_name = wIt->first.substr( 0, pos );
683 std::string v_type = wIt->first.substr( pos + 1 );
684 std::stringstream sstr;
685 if( v_type == "real" )
687 QDoubleSpinBox* v_double =
688 dynamic_cast< QDoubleSpinBox* >( wIt->second );
689 if( v_double != NULL )
690 sstr << v_double->value( );
692 else if( v_type == "atomic_real" )
694 if( v_name == "MeshType" )
696 QLabel* info = dynamic_cast< QLabel* >( wIt->second );
698 sstr << info->text( ).toStdString( );
703 parameters[ wIt->first ] = sstr.str( );
711 // -------------------------------------------------------------------------
714 _LoadImage( typename I::Pointer& image )
717 QFileDialog::getOpenFileNames(
719 tr( "Open an image" ),
720 tr( this->m_LastOpenedFile.c_str( ) ),
721 tr( "Medical image files (*.mhd *.bin *.dcm);;All files (*)" )
723 if( qList.size( ) == 0 )
727 QStringList::Iterator fIt = qList.begin( );
728 if( qList.size( ) == 1 )
730 // Read a single image
731 std::string fn = fIt->toStdString( );
732 this->m_LastOpenedFile = fn;
734 typename itk::ImageFileReader< I >::Pointer reader =
735 itk::ImageFileReader< I >::New( );
736 reader->SetFileName( fn );
741 catch( itk::ExceptionObject& err )
743 QMessageBox::critical(
745 tr( "Error opening single image!" ),
746 tr( err.GetDescription( ) )
751 image = reader->GetOutput( );
752 image->DisconnectPipeline( );
754 else if( qList.size( ) > 1 )
756 typedef std::set< std::string > _TOrderedStringList;
759 _TOrderedStringList filenames;
760 for( ; fIt != qList.end( ); ++fIt )
761 filenames.insert( fIt->toStdString( ) );
762 typename itk::ImageSeriesReader< I >::Pointer reader =
763 itk::ImageSeriesReader< I >::New( );
764 reader->SetImageIO( itk::GDCMImageIO::New( ) );
765 _TOrderedStringList::const_iterator oIt = filenames.begin( );
766 for( ; oIt != filenames.end( ); ++oIt )
768 reader->AddFileName( *oIt );
769 this->m_LastOpenedFile = *oIt;
776 catch( itk::ExceptionObject& err )
778 QMessageBox::critical(
780 tr( "Error opening image series!" ),
781 tr( err.GetDescription( ) )
786 image = reader->GetOutput( );
787 image->DisconnectPipeline( );
793 // -------------------------------------------------------------------------
795 triggered_aReloadPlugins( )
799 // -------------------------------------------------------------------------
801 triggered_aOpenInputImage( )
803 if( this->_LoadImage< TImage >( this->m_Image ) )
805 // Connect image to VTK
806 this->m_VTKImage = TVTKImage::New( );
807 this->m_VTKImage->SetInput( this->m_Image );
808 this->m_VTKImage->Update( );
810 this->m_ImageActors->Configure(
811 this->m_VTKImage->GetOutput( ),
812 this->m_UI->m_XPlaneVTK->GetInteractor( ),
813 this->m_UI->m_YPlaneVTK->GetInteractor( ),
814 this->m_UI->m_ZPlaneVTK->GetInteractor( )
816 this->m_ImageActors->
817 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
820 this->m_3DRenderer->AddActor(
821 this->m_ImageActors->GetImageOutlineActor( )
823 this->m_3DRenderer->AddActor(
824 this->m_ImageActors->GetXBoundsActor( )
826 this->m_3DRenderer->AddActor(
827 this->m_ImageActors->GetYBoundsActor( )
829 this->m_3DRenderer->AddActor(
830 this->m_ImageActors->GetZBoundsActor( )
834 this->m_3DRenderer->ResetCamera( );
835 this->m_ImageActors->ResetCameras( );
838 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
839 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
840 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
841 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
842 this->_UpdateEnabledFlags( );
843 this->m_UI->aNavigation->setChecked( true );
844 this->triggered_aSwitchMode( );
849 // -------------------------------------------------------------------------
851 triggered_aOpenSegmentedImage( )
853 if( this->_LoadImage< TImage >( this->m_Segmentation ) )
855 // Connect image to VTK
856 this->m_VTKSegmentation = TVTKImage::New( );
857 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
858 this->m_VTKSegmentation->Update( );
860 this->m_ImageActors->SetSegmentation(
861 this->m_VTKSegmentation->GetOutput( )
865 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
866 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
867 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
868 this->_UpdateEnabledFlags( );
873 // -------------------------------------------------------------------------
875 triggered_aFilterSegmentedImage( )
878 if( this->m_Segmentation.IsNull( ) )
880 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
883 std::string filter_name = action->text( ).toStdString( );
886 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
890 TParameters parameters = filter->GetDefaultParameters( );
891 if( !( this->_ParametersDialog( parameters ) ) )
893 filter->SetInput( this->m_Segmentation );
894 filter->SetParameters( parameters );
895 std::string result = filter->Update( );
897 // Get modified segmentation
898 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
899 if( this->m_Mesh.IsNotNull( ) )
901 this->m_Mesh->DisconnectPipeline( );
904 // Ok, it seems to have runned fine
908 // -------------------------------------------------------------------------
910 triggered_aSegmentedImageToMesh( )
913 if( this->m_Segmentation.IsNull( ) )
915 QAction* action = dynamic_cast< QAction* >( this->sender( ) );
918 std::string filter_name = action->text( ).toStdString( );
921 TFilterObject* filter = this->m_Plugins.CreateObject( filter_name );
925 TParameters parameters = filter->GetDefaultParameters( );
926 if( !( this->_ParametersDialog( parameters ) ) )
928 filter->SetInput( this->m_Segmentation );
929 filter->SetParameters( parameters );
930 std::string result = filter->Update( );
933 this->m_Mesh = filter->GetCastedOutput< TMesh >( );
934 if( this->m_Mesh.IsNotNull( ) )
936 this->m_Mesh->DisconnectPipeline( );
940 // Ok, it seems to have runned fine
945 // -------------------------------------------------------------------------
948 _SliceMesh( int axis )
950 TCutter* cutter = NULL;
951 if( axis == 2 ) cutter = this->m_ZCutter;
956 vtkPlane* vplane = this->m_ImageActors->GetSlicePlane( axis );
957 double vorigin[ 3 ], vnormal[ 3 ];
958 vplane->GetOrigin( vorigin );
959 vplane->GetNormal( vnormal );
961 TCutter::TVector corigin, cnormal;
962 corigin[ 0 ] = TScalar( vorigin[ 0 ] );
963 corigin[ 1 ] = TScalar( vorigin[ 1 ] );
964 corigin[ 2 ] = TScalar( vorigin[ 2 ] );
965 cnormal[ 0 ] = TScalar( vnormal[ 0 ] );
966 cnormal[ 1 ] = TScalar( vnormal[ 1 ] );
967 cnormal[ 2 ] = TScalar( vnormal[ 2 ] );
969 cutter->SetPlanePoint( corigin );
970 cutter->SetPlaneNormal( cnormal );
974 // -------------------------------------------------------------------------
978 long unsigned int eventId,
979 void* clientData, void* callData
982 if( clientData == NULL || callData == NULL )
984 MainWnd* wnd = reinterpret_cast< MainWnd* >( clientData );
985 int axis = *( reinterpret_cast< int* >( callData ) );
988 if( eventId == idms::InteractorStyleImage::SliceEvent )
989 wnd->_SliceMesh( axis );
992 // -------------------------------------------------------------------------
994 triggered_aLoadImage( )
996 if( this->_LoadImage< TImage >( this->m_Image ) )
998 // Connect image to VTK
999 this->m_VTKImage->SetInput( this->m_Image );
1000 this->m_VTKImage->Update( );
1001 this->m_ImageActors->Configure(
1002 this->m_VTKImage->GetOutput( ),
1003 this->m_UI->m_XPlaneVTK->GetInteractor( ),
1004 this->m_UI->m_YPlaneVTK->GetInteractor( ),
1005 this->m_UI->m_ZPlaneVTK->GetInteractor( )
1007 this->m_ImageActors->
1008 AddAuxiliaryInteractor( this->m_UI->m_3DVTK->GetInteractor( ) );
1011 this->m_3DRenderer->AddActor(
1012 this->m_ImageActors->GetImageOutlineActor( )
1014 this->m_3DRenderer->AddActor(
1015 this->m_ImageActors->GetXBoundsActor( )
1017 this->m_3DRenderer->AddActor(
1018 this->m_ImageActors->GetYBoundsActor( )
1020 this->m_3DRenderer->AddActor(
1021 this->m_ImageActors->GetZBoundsActor( )
1024 // Reset all cameras
1025 this->m_3DRenderer->ResetCamera( );
1026 this->m_ImageActors->ResetCameras( );
1029 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
1030 this->m_UI->m_XPlaneVTK->GetRenderWindow( )->Render( );
1031 this->m_UI->m_YPlaneVTK->GetRenderWindow( )->Render( );
1032 this->m_UI->m_ZPlaneVTK->GetRenderWindow( )->Render( );
1034 // Activate controls
1035 this->m_UI->aLoadSegmentedImage->setEnabled( true );
1036 this->m_UI->aSegmentImage->setEnabled( true );
1037 this->m_UI->m_3DVTK->setEnabled( true );
1038 this->m_UI->m_XPlaneVTK->setEnabled( true );
1039 this->m_UI->m_YPlaneVTK->setEnabled( true );
1040 this->m_UI->m_ZPlaneVTK->setEnabled( true );
1045 // -------------------------------------------------------------------------
1047 triggered_aLoadSegmentedImage( )
1049 if( this->m_Mesh.IsNotNull( ) )
1051 QMessageBox::critical(
1053 tr( "Mesh already loaded!" ),
1054 tr( "Mesh already loaded!" )
1060 if( this->_LoadImage< TImage >( this->m_Segmentation ) )
1062 // Compute segmentation values
1063 itk::MinimumMaximumImageCalculator< TImage >::Pointer minmax =
1064 itk::MinimumMaximumImageCalculator< TImage >::New( );
1065 minmax->SetImage( this->m_Segmentation );
1067 TPixel min_v = minmax->GetMinimum( );
1068 TPixel max_v = minmax->GetMaximum( );
1069 double thr = double( max_v + min_v ) / double( 2 );
1071 typedef itk::Image< TScalar, Dimension > _TScalarImage;
1073 itk::BinaryMinMaxCurvatureFlowImageFilter< TImage, _TScalarImage >
1075 typedef _TFilter::TimeStepType _TTimeStep;
1076 typedef _TFilter::RadiusValueType _TRadius;
1078 _TFilter::Pointer filter = _TFilter::New( );
1079 filter->SetInput( this->m_Segmentation );
1080 filter->SetTimeStep( _TTimeStep( 0.0625 ) );
1081 filter->SetNumberOfIterations( 10 );
1082 filter->SetStencilRadius( _TRadius( 3 ) );
1083 filter->SetThreshold( thr );
1086 itk::ImageFileWriter< _TScalarImage >::Pointer w =
1087 itk::ImageFileWriter< _TScalarImage >::New( );
1088 w->SetInput( filter->GetOutput( ) );
1089 w->SetFileName( "no_noise.mhd" );
1094 itk::LaplacianRecursiveGaussianImageFilter< TImage, _TScalarImage >
1096 _TFilter::Pointer filter = _TFilter::New( );
1097 filter->SetInput( this->m_Segmentation );
1098 filter->SetSigma( 3 ); // in spacing units
1099 filter->SetNormalizeAcrossScale( false );
1101 typedef itk::ThresholdImageFilter< _TScalarImage > _TThreshold;
1102 _TThreshold::Pointer threshold = _TThreshold::New( );
1103 threshold->SetInput( filter->GetOutput( ) );
1104 threshold->ThresholdAbove( TScalar( 0 ) );
1105 threshold->InPlaceOff( );
1106 threshold->Update( );
1108 itk::MinimumMaximumImageCalculator< _TScalarImage >::Pointer t_minmax =
1109 itk::MinimumMaximumImageCalculator< _TScalarImage >::New( );
1110 t_minmax->SetImage( threshold->GetOutput( ) );
1111 t_minmax->Compute( );
1112 TScalar min_t = t_minmax->GetMinimum( );
1114 std::cout << min_t << " " << t_minmax->GetMaximum( ) << std::endl;
1116 itk::SubtractImageFilter< _TScalarImage >::Pointer subtract =
1117 itk::SubtractImageFilter< _TScalarImage >::New( );
1118 subtract->SetInput1( threshold->GetOutput( ) );
1119 subtract->SetConstant2( min_t );
1121 itk::ImageFileWriter< _TScalarImage >::Pointer w =
1122 itk::ImageFileWriter< _TScalarImage >::New( );
1123 w->SetInput( subtract->GetOutput( ) );
1124 w->SetFileName( "no_noise_laplace_2.mhd" );
1128 // Pass segmentation to VTK
1129 this->m_VTKSegmentation = TVTKImage::New( );
1130 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
1131 this->m_VTKSegmentation->Update( );
1133 // Use VTK's marching cubes (it is smoother)
1134 vtkSmartPointer< vtkImageMarchingCubes > segmentation_mc =
1135 vtkSmartPointer< vtkImageMarchingCubes >::New( );
1136 segmentation_mc->SetInputData( this->m_VTKSegmentation->GetOutput( ) );
1137 segmentation_mc->SetValue( 0, thr );
1138 segmentation_mc->Update( );
1140 // Go back to ITK world
1141 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > _TVTKPDataToMesh;
1142 _TVTKPDataToMesh::Pointer itk_mc = _TVTKPDataToMesh::New( );
1143 itk_mc->SetInput( segmentation_mc->GetOutput( ) );
1145 this->m_Mesh = itk_mc->GetOutput( );
1146 this->m_Mesh->DisconnectPipeline( );
1148 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
1149 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
1151 this->m_MeshMapper->SetInputData( this->m_Mesh );
1152 this->m_MeshActor->SetMapper( this->m_MeshMapper );
1153 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
1154 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
1155 this->m_3DRenderer->AddActor( this->m_MeshActor );
1156 this->m_3DRenderer->ResetCamera( );
1157 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );
1159 unsigned int reduction = 20;
1161 typedef TImage::SpacingType::ValueType _TValue;
1164 // Compute downsize parameters
1165 TImage::SizeType o_size =
1166 segmentation->GetLargestPossibleRegion( ).GetSize( );
1167 TImage::SpacingType o_spac = segmentation->GetSpacing( );
1168 _TValue min_spac = std::numeric_limits< _TValue >::max( );
1169 for( unsigned int d = 0; d < Dimension; ++d )
1170 min_spac = ( o_spac[ d ] < min_spac )? o_spac[ d ]: min_spac;
1171 min_spac *= _TValue( reduction );
1172 TImage::SpacingType n_spac( min_spac );
1173 TImage::SizeType n_size;
1174 for( unsigned int d = 0; d < Dimension; ++d )
1175 n_size[ d ] = ( unsigned long )(
1176 _TValue( o_size[ d ] ) * o_spac[ d ] / min_spac
1180 typedef itk::Image< TScalar, Dimension > _TScalarImage;
1181 typedef itk::IdentityTransform< TScalar, Dimension > _TTransform;
1183 itk::LinearInterpolateImageFunction< TImage, TScalar >
1186 itk::ResampleImageFilter< TImage, _TScalarImage, TScalar, TScalar >
1188 _TResample::Pointer resample = _TResample::New( );
1189 resample->SetInput( segmentation );
1190 resample->SetSize( n_size );
1191 resample->SetOutputDirection( segmentation->GetDirection( ) );
1192 resample->SetOutputOrigin( segmentation->GetOrigin( ) );
1193 resample->SetOutputSpacing( n_spac );
1194 resample->SetTransform( _TTransform::New( ) );
1195 resample->SetInterpolator( _TInterpolator::New( ) );
1196 resample->UpdateLargestPossibleRegion( );
1200 itk::SignedDanielssonDistanceMapImageFilter< _TScalarImage, _TScalarImage >
1202 _TDanielsson::Pointer danielsson = _TDanielsson::New( );
1203 danielsson->SetInput( resample->GetOutput( ) );
1204 danielsson->Update( );
1206 // Go back to ITK world
1207 typedef cpm::VTK::PolyDataToMeshFilter< TTriangulation > TVTKPDataToMesh;
1208 TVTKPDataToMesh::Pointer itk_mc = TVTKPDataToMesh::New( );
1209 itk_mc->SetInput( danielsson_mc->GetOutput( ) );
1211 this->m_Mesh = itk_mc->GetOutput( );
1212 this->m_Mesh->DisconnectPipeline( );
1214 this->m_ZCutter = TCutter::New( );
1215 this->m_ZCutter->SetInput( this->m_Mesh );
1217 this->m_MeshMapper = vtkSmartPointer< TTriangulationMapper >::New( );
1218 this->m_MeshActor = vtkSmartPointer< vtkActor >::New( );
1220 this->m_MeshMapper->SetInputData( this->m_Mesh );
1221 this->m_MeshActor->SetMapper( this->m_MeshMapper );
1222 this->m_MeshActor->GetProperty( )->SetColor( 1, 1, 0 );
1223 this->m_MeshActor->GetProperty( )->SetRepresentationToWireframe( );
1224 this->m_3DRenderer->AddActor( this->m_MeshActor );
1225 this->m_3DRenderer->ResetCamera( );
1226 this->m_UI->m_3DVTK->GetRenderWindow( )->Render( );