1 // =========================================================================
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // =========================================================================
5 #include "CTArteries.h"
6 #include "ui_CTArteries.h"
7 #include "ui_Parameters.h"
8 #include "FileDialog.h"
12 #include <itkImageFileReader.h>
13 #include <itkImageSeriesReader.h>
14 #include <itkQuadEdgeMesh.h>
16 #include <vtkMarchingCubes.h>
17 #include <vtkMarchingSquares.h>
18 #include <vtkPolyDataConnectivityFilter.h>
19 #include <vtkPolyDataMapper.h>
20 #include <vtkProperty.h>
21 #include <vtkRenderer.h>
22 #include <vtkRenderWindow.h>
23 #include <vtkSplineWidget.h>
27 #include <ivq/ITK/CPRImageFilter.h>
28 #include <ivq/VTK/ImageActor.h>
29 #include <ivq/VTK/ImageToFourierSeriesFilter.h>
30 #include <ivq/VTK/ImageViewer.h>
31 #include <ivq/VTK/MPRViewers.h>
32 #include <ivq/VTK/PolyDataActor.h>
33 #include <ivq/VTK/SeedWidgetOverImageActor.h>
34 #include <ivq/Qt/DicomSeriesSelectorDialog.h>
35 #include <ivq/Qt/RendererWidget.h>
37 #include "algorithms/RandomWalkSegmentation.h"
39 // -------------------------------------------------------------------------
40 #define QT_ACTION_CONN( x ) \
42 this->m_UI->a##x, SIGNAL( triggered( ) ), this, SLOT( _s##x( ) ) \
45 // -------------------------------------------------------------------------
50 static ContourCallback* New( )
52 return( new ContourCallback( ) );
55 vtkObject* caller, unsigned long eId, void* data
58 ivq::VTK::ImageActor* actor =
59 ivq::VTK::ImageActor::SafeDownCast( caller );
60 if( eId == vtkCommand::InteractionEvent && actor != NULL )
62 ivq::VTK::ImageViewer* viewer = this->Window->m_UI->Slice->GetViewer( );
63 if( this->Window->m_ContourActor != NULL )
64 viewer->GetRenderer( )->RemoveViewProp( this->Window->m_ContourActor->GetActor( ) );
67 actor->GetActorBounds( abnds );
68 unsigned int nSlice = actor->GetSliceNumber( );
69 for( unsigned int i = 0; i < 16; ++i )
71 double w = double( 6.28 ) * double( i ) / double( 16 );
72 CTArteries::TFourier::TPoint v = this->Window->m_Fourier[ nSlice ]( w );
73 this->Window->m_Spline->SetHandlePosition(
74 i, v[ 0 ], v[ 1 ], abnds[ 4 ]
78 this->Window->m_Spline->SetProjectionPosition(
80 actor->GetBounds( )[ 4 ] +
81 actor->GetBounds( )[ 5 ]
86 this->Window->m_ContourActor =
87 this->Window->m_ContoursActors[ actor->GetSliceNumber( ) ];
88 viewer->GetRenderer( )->AddViewProp( this->Window->m_ContourActor->GetActor( ) );
99 virtual ~ContourCallback( )
104 // Purposely not implemented
105 ContourCallback( const ContourCallback& other );
106 ContourCallback& operator=( const ContourCallback& other );
111 // -------------------------------------------------------------------------
113 CTArteries( int argc, char* argv[], QWidget* parent )
114 : Superclass( parent ),
115 m_UI( new Ui::CTArteries ),
116 m_UIParameters( new Ui::Parameters )
118 this->m_UI->setupUi( this );
119 this->m_DlgParameters = new QDialog( );
120 this->m_UIParameters->setupUi( this->m_DlgParameters );
122 // Connect signals with slots
123 QT_ACTION_CONN( Open );
124 QT_ACTION_CONN( Config );
125 QT_ACTION_CONN( Process );
126 QT_ACTION_CONN( MarkReference );
127 QT_ACTION_CONN( MarkStenosis );
128 QT_ACTION_CONN( SaveResults );
129 QT_ACTION_CONN( UpdateContour );
134 std::string cmd( argv[ 1 ] );
135 std::string fname( argv[ 2 ] );
137 this->_ExecuteLog( fname );
142 // -------------------------------------------------------------------------
147 delete this->m_UIParameters;
148 delete this->m_DlgParameters;
151 // -------------------------------------------------------------------------
152 template< class _TStrings >
154 _openImage( const _TStrings& fnames )
157 std::ofstream str_log( "CTArteries.log" );
158 str_log << fnames.size( ) << std::endl;
159 for( const std::string& s: fnames )
160 str_log << s << std::endl;
163 // Create appropriate reader
164 itk::ImageSource< TImage >::Pointer reader;
165 if( fnames.size( ) == 1 )
167 itk::ImageFileReader< TImage >::Pointer r =
168 itk::ImageFileReader< TImage >::New( );
169 r->SetFileName( *( fnames.begin( ) ) );
172 else if( fnames.size( ) > 1 )
174 itk::ImageSeriesReader< TImage >::Pointer r =
175 itk::ImageSeriesReader< TImage >::New( );
176 typename _TStrings::const_iterator i;
177 for( i = fnames.begin( ); i != fnames.end( ); ++i )
178 r->AddFileName( *i );
184 if( reader.IsNull( ) )
189 this->m_Image = reader->GetOutput( );
190 this->m_Image->DisconnectPipeline( );
192 catch( std::exception& err )
194 this->m_Image = NULL;
195 QMessageBox::critical( this, "Error opening image", err.what( ) );
198 this->_showInputImage( );
201 // -------------------------------------------------------------------------
203 _openDicom( const std::string& dirname )
205 ivq::Qt::DicomSeriesSelectorDialog dlg( this );
206 dlg.setStartDir( dirname );
207 if( dlg.exec( ) == QDialog::Accepted )
208 this->_openImage( *( dlg.selectedFilenames( ) ) );
211 // -------------------------------------------------------------------------
215 if( this->m_Image.IsNotNull( ) )
217 this->m_VTKImage = TVTKImage::New( );
218 this->m_VTKImage->SetInput( this->m_Image );
219 this->m_VTKImage->Update( );
221 ivq::VTK::MPRViewers* viewers = this->m_UI->MPR->GetViewers( );
222 viewers->SetInputData( this->m_VTKImage->GetOutput( ) );
223 viewers->SetColorWindow( 1000 );
224 viewers->SetColorLevel( 100 );
226 ivq::VTK::ImageViewer* view = viewers->GetView( 2 );
228 vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor >::New( );
229 this->m_Seeds->SetActor( view->GetImageActor( ) );
230 this->m_Seeds->SetInteractor( view->GetRenderWindow( )->GetInteractor( ) );
233 viewers->ResetCameras( );
234 this->m_Seeds->EnabledOn( );
239 this->m_VTKImage = NULL;
244 // -------------------------------------------------------------------------
246 _process( const std::vector< TImage::PointType >& seeds )
249 std::ofstream str_log( "CTArteries.log", std::ios_base::app );
250 str_log << this->m_UIParameters->Beta->value( ) << std::endl;
251 str_log << this->m_UIParameters->Sigma->value( ) << std::endl;
252 str_log << this->m_UIParameters->Radius->value( ) << std::endl;
253 str_log << seeds.size( ) << std::endl;
254 for( TImage::PointType seed: seeds )
255 str_log << seed << std::endl;
259 typedef RandomWalkSegmentation< TImage, TScalarImage > _TSegmentation;
260 _TSegmentation::Pointer seg = _TSegmentation::New( );
261 seg->SetInput( this->m_Image );
262 seg->SetBeta( this->m_UIParameters->Beta->value( ) );
263 seg->SetSigma( this->m_UIParameters->Sigma->value( ) );
264 seg->SetRadius( this->m_UIParameters->Radius->value( ) );
265 seg->SetStartSeed( seeds[ 0 ] );
266 seg->SetEndSeed( seeds[ 1 ] );
267 for( TImage::PointType seed: seeds )
268 seg->AddSeed( seed );
275 catch( std::exception& err )
277 QMessageBox::critical(
279 QMessageBox::tr( "Error reading image" ),
280 QMessageBox::tr( err.what( ) )
285 this->m_Seeds->EnabledOff( );
287 this->m_Segmentation = seg->GetOutput( );
288 this->m_Axis = seg->GetOutputAxis( );
289 this->m_Segmentation->DisconnectPipeline( );
290 this->m_Axis->DisconnectPipeline( );
293 // -------------------------------------------------------------------------
295 _prepareQuantification( )
297 this->m_Contours.clear( );
298 this->m_ContoursActors.clear( );
299 this->m_Fourier.clear( );
301 TImage::RegionType ext_region = this->m_CPRImage->GetRequestedRegion( );
302 for( long z = 0; z < ext_region.GetSize( )[ 2 ]; ++z )
304 TImage::IndexType slc_idx = ext_region.GetIndex( );
305 TImage::SizeType slc_size = ext_region.GetSize( );
308 TImage::RegionType slc_region;
309 slc_region.SetIndex( slc_idx );
310 slc_region.SetSize( slc_size );
312 typedef itk::RegionOfInterestImageFilter< TScalarImage, TScalarImage > _TROI;
313 _TROI::Pointer roi = _TROI::New( );
314 roi->SetInput( this->m_CPRSegmentation );
315 roi->SetRegionOfInterest( slc_region );
317 typedef TScalarImage _TScalarSlice;
319 typedef itk::ImageToVTKImageFilter< _TScalarSlice > _TVTKScalarSlice;
320 _TVTKScalarSlice::Pointer vtk_slice = _TVTKScalarSlice::New( );
321 vtk_slice->SetInput( roi->GetOutput( ) );
322 vtk_slice->Update( );
324 typedef ivq::VTK::ImageToFourierSeriesFilter< TFourier > _TFourierFilter;
325 vtkSmartPointer< _TFourierFilter > fFilter =
326 vtkSmartPointer< _TFourierFilter >::New( );
327 fFilter->SetInputData( vtk_slice->GetOutput( ) );
328 fFilter->SetContourValue( 0 );
329 fFilter->SetNumberOfHarmonics( 6 );
332 this->m_Fourier.push_back( fFilter->GetOutput( ) );
335 vtkSmartPointer< ivq::VTK::PolyDataActor > actor =
336 vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
337 actor->SetInputData( cnt );
338 actor->GetMapper( )->ScalarVisibilityOff( );
340 actor->GetProperty( )->SetColor( 1, 0, 0 );
341 actor->GetProperty( )->SetLineWidth( 2 );
342 this->m_ContoursActors.push_back( actor );
347 ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
348 vtkSmartPointer< ContourCallback > cbk =
349 vtkSmartPointer< ContourCallback >::New( );
351 slice_view->GetImageActor( )->AddObserver( vtkCommand::InteractionEvent, cbk );
352 this->m_ContourActor = NULL;
354 this->m_Spline = vtkSmartPointer< vtkSplineWidget >::New( );
355 this->m_Spline->SetCurrentRenderer( slice_view->GetRenderer( ) );
356 this->m_Spline->SetDefaultRenderer( slice_view->GetRenderer( ) );
357 this->m_Spline->SetInputData( slice_view->GetInput( ) );
358 this->m_Spline->SetProp3D( slice_view->GetImageActor( ) );
359 this->m_Spline->SetInteractor( slice_view->GetRenderWindow( )->GetInteractor( ) );
361 slice_view->GetInput( )->GetBounds( bnds );
362 this->m_Spline->PlaceWidget(
363 bnds[ 0 ], bnds[ 1 ],
364 bnds[ 2 ], bnds[ 3 ],
367 this->m_Spline->ProjectToPlaneOn( );
368 this->m_Spline->SetProjectionNormalToZAxes( );
369 this->m_Spline->SetProjectionPosition(
371 slice_view->GetImageActor( )->GetBounds( )[ 4 ] +
372 slice_view->GetImageActor( )->GetBounds( )[ 5 ]
375 this->m_Spline->SetHandleSize( 0.005 );
376 this->m_Spline->ClosedOn( );
377 this->m_Spline->SetNumberOfHandles( 16 );
378 this->m_Spline->EnabledOn( );
380 QVector< double > xdata, dmindata, dmaxdata, areadata;
382 for( unsigned int i = 0; i < this->m_Fourier.size( ); ++i )
385 this->m_Fourier[ i ].GetEllipse( 1, a, b, t, p );
386 TScalar area = this->m_Fourier[ i ].GetArea( );
388 xdata.push_back( double( i ) );
389 dmindata.push_back( b );
390 dmaxdata.push_back( a );
391 areadata.push_back( area );
394 this->m_UI->Plot->addGraph( this->m_UI->Plot->xAxis, this->m_UI->Plot->yAxis );
395 this->m_UI->Plot->graph( 0 )->setPen( QPen( QColor( 255, 0, 0 ) ) );
396 this->m_UI->Plot->graph( 0 )->setName( "Minimum diameter (mm)" );
397 this->m_UI->Plot->graph( 0 )->setData( xdata, dmindata );
399 this->m_UI->Plot->addGraph( this->m_UI->Plot->xAxis, this->m_UI->Plot->yAxis );
400 this->m_UI->Plot->graph( 1 )->setPen( QPen( QColor( 0, 255, 0 ) ) );
401 this->m_UI->Plot->graph( 1 )->setName( "Maximum diameter (mm)" );
402 this->m_UI->Plot->graph( 1 )->setData( xdata, dmaxdata );
404 this->m_UI->Plot->addGraph( this->m_UI->Plot->xAxis, this->m_UI->Plot->yAxis2 );
405 this->m_UI->Plot->graph( 2 )->setPen( QPen( QColor( 0, 0, 255 ) ) );
406 this->m_UI->Plot->graph( 2 )->setName( "Area (mm2)" );
407 this->m_UI->Plot->graph( 2 )->setData( xdata, areadata );
409 this->m_UI->Plot->xAxis->setLabel( "Position" );
410 this->m_UI->Plot->yAxis->setLabel( "Diameters (mm)" );
411 this->m_UI->Plot->yAxis2->setLabel( "Areas (mm2)" );
413 this->m_UI->Plot->legend->setVisible( true );
414 this->m_UI->Plot->xAxis->setVisible( true );
415 this->m_UI->Plot->yAxis->setVisible( true );
416 this->m_UI->Plot->yAxis2->setVisible( true );
418 this->m_UI->Plot->rescaleAxes( );
419 this->m_UI->Plot->replot( );
420 this->m_StenosisText = new QCPItemText( this->m_UI->Plot );
421 this->m_StenosisText->setText( "Stenosis: NaN" );
422 this->m_UI->Plot->replot( );
425 // -------------------------------------------------------------------------
427 _showProcessResults( )
429 if( this->m_Segmentation.IsNull( ) || this->m_Axis.IsNull( ) )
432 this->m_VTKSegmentation = TVTKScalarImage::New( );
433 this->m_VTKSegmentation->SetInput( this->m_Segmentation );
434 this->m_VTKSegmentation->Update( );
437 vtkImageData* seg = this->m_VTKSegmentation->GetOutput( );
439 seg->GetScalarRange( r );
440 vtkSmartPointer< vtkMarchingCubes > mc =
441 vtkSmartPointer< vtkMarchingCubes >::New( );
442 mc->SetInputData( seg );
443 mc->SetValue( 0, 0 );
445 this->m_Surface = vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
446 this->m_Surface->SetInputConnection( mc->GetOutputPort( ) );
447 this->m_Surface->Update( );
450 this->m_Curve = TCurve::New( );
451 for( unsigned int i = 0; i < this->m_Axis->GetSize( ); ++i )
452 this->m_Curve->AddPoint( this->m_Axis->GetPoint( i ) );
453 this->m_Curve->Smooth( 2 );
457 this->m_CPRImage, this->m_VTKCPRImage,
458 this->m_Image, this->m_Curve
461 this->m_CPRSegmentation, this->m_VTKCPRSegmentation,
462 this->m_Segmentation, this->m_Curve
466 vtkRenderer* renderer =
467 this->m_UI->MPR->GetRendererWidget( )->GetRenderer( );
468 renderer->AddViewProp( this->m_Surface->GetActor( ) );
470 renderer->ResetCamera( );
471 this->m_UI->MPR->GetRendererWidget( )->GetRenderWindow( )->Render( );
473 ivq::VTK::ImageViewer* cpr_view = this->m_UI->CPR->GetViewer( );
474 ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
476 cpr_view->SetInputData( this->m_VTKCPRImage->GetOutput( ) );
477 cpr_view->SetColorWindow( 1000 );
478 cpr_view->SetColorLevel( 100 );
479 cpr_view->SetSliceOrientationToXZ( );
482 slice_view->SetInputData( this->m_VTKCPRImage->GetOutput( ) );
483 slice_view->SetColorWindow( 1000 );
484 slice_view->SetColorLevel( 100 );
485 slice_view->SetSliceOrientationToXY( );
486 slice_view->Render( );
488 this->_prepareQuantification( );
489 this->m_StenosisSlice = -1;
490 this->m_ReferenceSlice = -1;
491 this->m_StenosisLine = NULL;
492 this->m_ReferenceLine = NULL;
495 // -------------------------------------------------------------------------
499 if( this->m_StenosisSlice >= 0 )
501 if( this->m_StenosisLine == NULL )
502 this->m_StenosisLine = new QCPItemLine( this->m_UI->Plot );
503 this->m_StenosisLine->start->setCoords( this->m_StenosisSlice, 0 );
504 this->m_StenosisLine->end->setCoords(
505 this->m_StenosisSlice,
506 this->m_UI->Plot->yAxis->range( ).size( )
508 this->m_UI->Plot->replot( );
511 if( this->m_ReferenceSlice >= 0 )
513 if( this->m_ReferenceLine == NULL )
514 this->m_ReferenceLine = new QCPItemLine( this->m_UI->Plot );
515 this->m_ReferenceLine->start->setCoords( this->m_ReferenceSlice, 0 );
516 this->m_ReferenceLine->end->setCoords(
517 this->m_ReferenceSlice,
518 this->m_UI->Plot->yAxis->range( ).size( )
520 this->m_UI->Plot->replot( );
523 if( this->m_StenosisSlice < 0 || this->m_ReferenceSlice < 0 )
526 TScalar sa, sb, st, sp;
527 this->m_Fourier[ this->m_StenosisSlice ].GetEllipse( 1, sa, sb, st, sp );
528 TScalar sarea = this->m_Fourier[ this->m_StenosisSlice ].GetArea( );
529 TScalar ra, rb, rt, rp;
530 this->m_Fourier[ this->m_ReferenceSlice ].GetEllipse( 1, ra, rb, rt, rp );
531 TScalar rarea = this->m_Fourier[ this->m_ReferenceSlice ].GetArea( );
532 double qmin = 100.0 * ( 1.0 - ( sb / rb ) );
533 double qmax = 100.0 * ( 1.0 - ( sa / ra ) );
534 double qarea = 100.0 * ( 1.0 - ( sarea / rarea ) );
537 s << "Stenosis: " << std::endl
538 << qmin << "% (min diameter)" << std::endl
539 << qmax << "% (max diameter)" << std::endl
540 << qarea << "% (area)";
541 this->m_StenosisText->setText( s.str( ).c_str( ) );
542 this->m_StenosisText->position->setCoords(
543 ( this->m_ReferenceSlice + this->m_StenosisSlice ) * 0.5,
544 this->m_UI->Plot->yAxis->range( ).center( )
546 this->m_UI->Plot->replot( );
549 // -------------------------------------------------------------------------
551 _ExecuteLog( const std::string& fname )
553 std::ifstream str_log( fname.c_str( ) );
561 // -------------------------------------------------------------------------
565 FileDialog dlg( this );
567 "Medical images (*.mhd *.dcm);;Other images (*.png *.jpg *.bmp);;\
570 if( dlg.exec( ) == QDialog::Accepted )
572 std::set< std::string > filenames, dirnames;
573 QStringList names = dlg.selectedFiles( );
574 for( QString name: names )
576 QFileInfo info( name );
578 dirnames.insert( name.toStdString( ) );
580 filenames.insert( name.toStdString( ) );
584 if( dirnames.size( ) == 1 && filenames.size( ) == 0 )
585 this->_openDicom( *( dirnames.begin( ) ) );
586 else if( dirnames.size( ) == 0 && filenames.size( ) > 0 )
587 this->_openImage( filenames );
589 QMessageBox::critical(
591 "Error opening image",
592 "Directory - files mixed up, don't know what to do."
598 // -------------------------------------------------------------------------
602 this->m_DlgParameters->exec( );
605 // -------------------------------------------------------------------------
610 typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds;
611 if( this->m_Image.IsNull( ) || this->m_Seeds.GetPointer( ) == NULL )
613 QMessageBox::critical( this, "Error processing", "No valid input image." );
617 std::vector< TImage::PointType > seeds;
618 for( _TSeeds::value_type sValue: this->m_Seeds->GetSeeds( ) )
620 for( unsigned int i = 0; i < sValue.second.size( ); i += 3 )
622 TImage::PointType pnt;
623 pnt[ 0 ] = sValue.second[ i + 0 ];
624 pnt[ 1 ] = sValue.second[ i + 1 ];
625 pnt[ 2 ] = sValue.second[ i + 2 ];
626 seeds.push_back( pnt );
631 if( seeds.size( ) < 2 )
633 QMessageBox::critical( this, "Error processing", "Not enough seeds." );
637 this->_process( seeds );
638 this->_showProcessResults( );
641 // -------------------------------------------------------------------------
645 if( this->m_Fourier.size( ) == 0 )
647 ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
648 this->m_ReferenceSlice = slice_view->GetImageActor( )->GetSliceNumber( );
649 this->_showStenosis( );
652 // -------------------------------------------------------------------------
656 if( this->m_Fourier.size( ) == 0 )
658 ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
659 this->m_StenosisSlice = slice_view->GetImageActor( )->GetSliceNumber( );
660 this->_showStenosis( );
663 // -------------------------------------------------------------------------
668 QFileDialog::getSaveFileName(
670 "Select one or more files to open",
672 "CSV files (*.csv);;All files (*)"
677 std::ofstream out( fname.c_str( ) );
678 out << "slice;min_diameter;max_diameter;area" << std::endl;
679 for( unsigned int i = 0; i < this->m_Fourier.size( ); ++i )
682 this->m_Fourier[ i ].GetEllipse( 1, a, b, t, p );
683 TScalar area = this->m_Fourier[ i ].GetArea( );
684 out << i << ";" << b << ";" << a << ";" << area << std::endl;
687 out << "############################" << std::endl;
688 typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds;
689 const _TSeeds& seeds = this->m_Seeds->GetSeeds( );
690 for( _TSeeds::value_type seed: seeds )
692 for( unsigned int i = 0; i < seed.second.size( ); i += 3 )
695 << seed.second[ i + 0 ] << " "
696 << seed.second[ i + 1 ] << " "
697 << seed.second[ i + 2 ] << std::endl;
702 out << "############################" << std::endl;
706 // -------------------------------------------------------------------------
710 if( this->m_ContourActor == NULL )
712 vtkSmartPointer< vtkPolyData > new_pd =
713 vtkSmartPointer< vtkPolyData >::New( );
714 this->m_Spline->GetPolyData( new_pd );
716 ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
717 ivq::VTK::ImageActor* slice_actor = slice_view->GetImageActor( );
718 this->m_ContoursActors[ slice_actor->GetSliceNumber( ) ]->
719 SetInputData( new_pd );
720 slice_view->Render( );
723 typedef itk::QuadEdgeMesh< double, 2 > _TQEMesh;
724 typedef _TQEMesh::PointType _T2DPoint;
725 typedef std::vector< _T2DPoint > _T2DPoints;
727 _TQEMesh::Pointer mesh = _TQEMesh::New( );
728 for( unsigned int i = 0; i < new_pd->GetNumberOfPoints( ); ++i )
732 new_pd->GetPoint( i, p );
735 mesh->AddPoint( pnt );
738 vtkCellArray* lines = new_pd->GetLines( );
739 lines->InitTraversal( );
740 vtkIdType* ids = new vtkIdType[ 2 ];
742 while( lines->GetNextCell( npts, ids ) != 0 )
743 mesh->AddEdge( ids[ 0 ], ids[ 1 ] );
745 _TQEMesh::QEPrimal* edge = mesh->GetEdge( );
748 mesh->AddFace( edge );
749 edge = mesh->GetEdge( );
750 for( auto eIt = edge->BeginGeomLnext( ); eIt != edge->EndGeomLnext( ); ++eIt )
751 points.push_back( mesh->GetPoint( *eIt ) );
753 TFourier f( points.begin( ), points.end( ), 6 );
754 f.SetOrderingToCounterClockWise( );
755 this->m_Fourier[ slice_actor->GetSliceNumber( ) ] = f;
760 // -------------------------------------------------------------------------
761 template< class _TImagePtr, class _TVTKImagePtr, class _TCurvePtr >
764 _TImagePtr& output, _TVTKImagePtr& vtk_output,
765 const _TImagePtr& input, const _TCurvePtr& curve
768 typedef typename _TImagePtr::ObjectType _TImage;
769 typedef typename _TCurvePtr::ObjectType _TCurve;
770 typedef ivq::ITK::CPRImageFilter< _TImage, _TCurve > _TFilter;
772 typename _TFilter::Pointer cpr = _TFilter::New( );
773 cpr->SetInput( input );
774 cpr->SetInputCurve( curve );
775 cpr->SetSliceRadius( 40 );
777 output = cpr->GetOutput( );
778 output->DisconnectPipeline( );
780 vtk_output = _TVTKImagePtr::ObjectType::New( );
781 vtk_output->SetInput( output );
782 vtk_output->Update( );
785 // -------------------------------------------------------------------------
786 #include <QApplication>
788 int main( int argc, char* argv[] )
790 QApplication a( argc, argv );
791 CTArteries w( argc, argv );