-#include <iostream>
+// =========================================================================
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// =========================================================================
+
+#include "CTArteries.h"
+#include "ui_CTArteries.h"
+#include "ui_Parameters.h"
+#include "FileDialog.h"
+
+#include <set>
+
+#include <itkImageFileReader.h>
+#include <itkImageSeriesReader.h>
+
+#include <vtkMarchingCubes.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+
+#include <QtGui>
+
+#include <ivq/ITK/CPRImageFilter.h>
+#include <ivq/VTK/ImageViewer.h>
+#include <ivq/VTK/MPRViewers.h>
+#include <ivq/VTK/PolyDataActor.h>
+#include <ivq/VTK/SeedWidgetOverImageActor.h>
+#include <ivq/Qt/DicomSeriesSelectorDialog.h>
+#include <ivq/Qt/RendererWidget.h>
+
+#include "algorithms/RandomWalkSegmentation.h"
+
+// -------------------------------------------------------------------------
+#define QT_ACTION_CONN( x ) \
+ this->connect( \
+ this->m_UI->a##x, SIGNAL( triggered( ) ), this, SLOT( _s##x( ) ) \
+ )
+
+// -------------------------------------------------------------------------
+CTArteries::
+CTArteries( int argc, char* argv[], QWidget* parent )
+ : Superclass( parent ),
+ m_UI( new Ui::CTArteries ),
+ m_UIParameters( new Ui::Parameters )
+{
+ this->m_UI->setupUi( this );
+ this->m_DlgParameters = new QDialog( );
+ this->m_UIParameters->setupUi( this->m_DlgParameters );
+
+ // Connect signals with slots
+ QT_ACTION_CONN( Open );
+ QT_ACTION_CONN( Config );
+ QT_ACTION_CONN( Process );
+}
+
+// -------------------------------------------------------------------------
+CTArteries::
+~CTArteries( )
+{
+ delete this->m_UI;
+ delete this->m_UIParameters;
+ delete this->m_DlgParameters;
+}
+
+// -------------------------------------------------------------------------
+template< class _TStrings >
+void CTArteries::
+_openImage( const _TStrings& fnames )
+{
+ // Create appropriate reader
+ itk::ImageSource< TImage >::Pointer reader;
+ if( fnames.size( ) == 1 )
+ {
+ itk::ImageFileReader< TImage >::Pointer r =
+ itk::ImageFileReader< TImage >::New( );
+ r->SetFileName( *( fnames.begin( ) ) );
+ reader = r;
+ }
+ else if( fnames.size( ) > 1 )
+ {
+ itk::ImageSeriesReader< TImage >::Pointer r =
+ itk::ImageSeriesReader< TImage >::New( );
+ typename _TStrings::const_iterator i;
+ for( i = fnames.begin( ); i != fnames.end( ); ++i )
+ r->AddFileName( *i );
+ reader = r;
+
+ } // fi
+
+ // Execute reader
+ if( reader.IsNull( ) )
+ return;
+ try
+ {
+ reader->Update( );
+ this->m_Image = reader->GetOutput( );
+ this->m_Image->DisconnectPipeline( );
+ }
+ catch( std::exception& err )
+ {
+ this->m_Image = NULL;
+ QMessageBox::critical( this, "Error opening image", err.what( ) );
+
+ } // yrt
+ this->_showInputImage( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_openDicom( const std::string& dirname )
+{
+ ivq::Qt::DicomSeriesSelectorDialog dlg( this );
+ dlg.setStartDir( dirname );
+ if( dlg.exec( ) == QDialog::Accepted )
+ this->_openImage( *( dlg.selectedFilenames( ) ) );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_showInputImage( )
+{
+ if( this->m_Image.IsNotNull( ) )
+ {
+ this->m_VTKImage = TVTKImage::New( );
+ this->m_VTKImage->SetInput( this->m_Image );
+ this->m_VTKImage->Update( );
+
+ ivq::VTK::MPRViewers* viewers = this->m_UI->MPR->GetViewers( );
+ viewers->SetInputData( this->m_VTKImage->GetOutput( ) );
+ viewers->SetColorWindow( 1000 );
+ viewers->SetColorLevel( 100 );
+
+ ivq::VTK::ImageViewer* view = viewers->GetView( 2 );
+ this->m_Seeds =
+ vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor >::New( );
+ this->m_Seeds->SetActor( view->GetImageActor( ) );
+ this->m_Seeds->SetInteractor( view->GetRenderWindow( )->GetInteractor( ) );
+
+ viewers->Render( );
+ viewers->ResetCameras( );
+ this->m_Seeds->EnabledOn( );
+ viewers->Render( );
+ }
+ else
+ {
+ this->m_VTKImage = NULL;
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_process( )
+{
+ // Get seeds
+ typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds;
+ if( this->m_Image.IsNull( ) || this->m_Seeds.GetPointer( ) == NULL )
+ {
+ QMessageBox::critical( this, "Error processing", "No valid input image." );
+ return;
+
+ } // fi
+ std::vector< TImage::PointType > seeds;
+ for( _TSeeds::value_type sValue: this->m_Seeds->GetSeeds( ) )
+ {
+ for( unsigned int i = 0; i < sValue.second.size( ); i += 3 )
+ {
+ TImage::PointType pnt;
+ pnt[ 0 ] = sValue.second[ i + 0 ];
+ pnt[ 1 ] = sValue.second[ i + 1 ];
+ pnt[ 2 ] = sValue.second[ i + 2 ];
+ seeds.push_back( pnt );
+
+ } // rof
+
+ } // rof
+ if( seeds.size( ) < 2 )
+ {
+ QMessageBox::critical( this, "Error processing", "Not enough seeds." );
+ return;
+
+ } // fi
+
+ // Create algorithm
+ typedef RandomWalkSegmentation< TImage, TScalarImage > _TSegmentation;
+ _TSegmentation::Pointer seg = _TSegmentation::New( );
+ seg->SetInput( this->m_Image );
+ seg->SetBeta( this->m_UIParameters->Beta->value( ) );
+ seg->SetSigma( this->m_UIParameters->Sigma->value( ) );
+ seg->SetRadius( this->m_UIParameters->Radius->value( ) );
+ seg->SetStartSeed( seeds[ 0 ] );
+ seg->SetEndSeed( seeds[ 1 ] );
+ for( TImage::PointType seed: seeds )
+ seg->AddSeed( seed );
+ try
+ {
+ seg->Update( );
+ }
+ catch( std::exception& err )
+ {
+ QMessageBox::critical(
+ this,
+ QMessageBox::tr( "Error reading image" ),
+ QMessageBox::tr( err.what( ) )
+ );
+ return;
+
+ } // yrt
+ this->m_Seeds->EnabledOff( );
+
+ this->m_Segmentation = seg->GetOutput( );
+ this->m_Axis = seg->GetOutputAxis( );
+ this->m_Segmentation->DisconnectPipeline( );
+ this->m_Axis->DisconnectPipeline( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_showProcessResults( )
+{
+ if( this->m_Segmentation.IsNull( ) || this->m_Axis.IsNull( ) )
+ return;
+
+ this->m_VTKSegmentation = TVTKScalarImage::New( );
+ this->m_VTKSegmentation->SetInput( this->m_Segmentation );
+ this->m_VTKSegmentation->Update( );
+
+ // Show surface
+ vtkImageData* seg = this->m_VTKSegmentation->GetOutput( );
+ double r[ 2 ];
+ seg->GetScalarRange( r );
+ vtkSmartPointer< vtkMarchingCubes > mc =
+ vtkSmartPointer< vtkMarchingCubes >::New( );
+ mc->SetInputData( seg );
+ mc->SetValue( 0, 0 );
+ mc->Update( );
+ this->m_Surface = vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
+ this->m_Surface->SetInputConnection( mc->GetOutputPort( ) );
+ this->m_Surface->Update( );
+
+ // Prepare curve
+ this->m_Curve = TCurve::New( );
+ for( unsigned int i = 0; i < this->m_Axis->GetSize( ); ++i )
+ this->m_Curve->AddPoint( this->m_Axis->GetPoint( i ) );
+ this->m_Curve->Smooth( 2 );
+
+ // Show all data
+ vtkRenderer* renderer =
+ this->m_UI->MPR->GetRendererWidget( )->GetRenderer( );
+ renderer->AddViewProp( this->m_Surface->GetActor( ) );
+ renderer->Render( );
+ renderer->ResetCamera( );
+ this->m_UI->MPR->GetRendererWidget( )->GetRenderWindow( )->Render( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sOpen( )
+{
+ FileDialog dlg( this );
+ dlg.setNameFilter(
+ "Medical images (*.mhd *.dcm);;Other images (*.png *.jpg *.bmp);;\
+All files (*)"
+ );
+ if( dlg.exec( ) == QDialog::Accepted )
+ {
+ std::set< std::string > filenames, dirnames;
+ QStringList names = dlg.selectedFiles( );
+ for( QString name: names )
+ {
+ QFileInfo info( name );
+ if( info.isDir( ) )
+ dirnames.insert( name.toStdString( ) );
+ else
+ filenames.insert( name.toStdString( ) );
+
+ } // rof
+
+ if( dirnames.size( ) == 1 && filenames.size( ) == 0 )
+ this->_openDicom( *( dirnames.begin( ) ) );
+ else if( dirnames.size( ) == 0 && filenames.size( ) > 0 )
+ this->_openImage( filenames );
+ else
+ QMessageBox::critical(
+ this,
+ "Error opening image",
+ "Directory - files mixed up, don't know what to do."
+ );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sConfig( )
+{
+ this->m_DlgParameters->exec( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sProcess( )
+{
+ this->_process( );
+ this->_showProcessResults( );
+}
+
+// -------------------------------------------------------------------------
+#include <QApplication>
+
int main( int argc, char* argv[] )
{
- std::cout << "hola" << std::endl;
- return( 0 );
+ QApplication a( argc, argv );
+ CTArteries w( argc, argv );
+ w.show( );
+ return( a.exec( ) );
}
// eof - $RCSfile$