]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Mon, 23 Oct 2017 03:06:20 +0000 (22:06 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Mon, 23 Oct 2017 03:06:20 +0000 (22:06 -0500)
appli/CTArteries/CTArteries.cxx
appli/CTArteries/CTArteries.h
appli/CTArteries/CTArteries.ui

index 54b8aeb8908f73f6cb2e223aa2abf02a9b6e145a..282f66f604521007519297d82e640ace3a739a00 100644 (file)
@@ -122,6 +122,10 @@ CTArteries( int argc, char* argv[], QWidget* parent )
   QT_ACTION_CONN( Open );
   QT_ACTION_CONN( Config );
   QT_ACTION_CONN( Process );
+  QT_ACTION_CONN( MarkReference );
+  QT_ACTION_CONN( MarkStenosis );
+  QT_ACTION_CONN( SaveResults );
+  QT_ACTION_CONN( UpdateContour );
 
   // Load log
   if( argc == 3 )
@@ -378,11 +382,17 @@ _prepareQuantification( )
       for( auto eIt = edge->BeginGeomLnext( ); eIt != edge->EndGeomLnext( ); ++eIt )
         points.push_back( mesh->GetPoint( *eIt ) );
 
-    } // fi
+      TFourier f( points.begin( ), points.end( ), 6 );
+      f.SetOrderingToCounterClockWise( );
+      this->m_Fourier.push_back( f );
+    }
+    else
+    {
+      TFourier f( 6 );
+      f[ 1 ] = 0.1;
+      this->m_Fourier.push_back( f );
 
-    TFourier f( points.begin( ), points.end( ), 6 );
-    f.SetOrderingToCounterClockWise( );
-    this->m_Fourier.push_back( f );
+    } // fi
 
     vtkSmartPointer< ivq::VTK::PolyDataActor > actor =
       vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
@@ -468,6 +478,9 @@ _prepareQuantification( )
 
   this->m_UI->Plot->rescaleAxes( );
   this->m_UI->Plot->replot( );
+  this->m_StenosisText = new QCPItemText( this->m_UI->Plot );
+  this->m_StenosisText->setText( "Stenosis: NaN" );
+  this->m_UI->Plot->replot( );
 }
 
 // -------------------------------------------------------------------------
@@ -534,6 +547,64 @@ _showProcessResults( )
   slice_view->Render( );
 
   this->_prepareQuantification( );
+  this->m_StenosisSlice = -1;
+  this->m_ReferenceSlice = -1;
+  this->m_StenosisLine = NULL;
+  this->m_ReferenceLine = NULL;
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_showStenosis( )
+{
+  if( this->m_StenosisSlice >= 0 )
+  {
+    if( this->m_StenosisLine == NULL )
+      this->m_StenosisLine = new QCPItemLine( this->m_UI->Plot );
+    this->m_StenosisLine->start->setCoords( this->m_StenosisSlice, 0 );
+    this->m_StenosisLine->end->setCoords(
+      this->m_StenosisSlice,
+      this->m_UI->Plot->yAxis->range( ).size( )
+      );
+    this->m_UI->Plot->replot( );
+
+  } // fi
+  if( this->m_ReferenceSlice >= 0 )
+  {
+    if( this->m_ReferenceLine == NULL )
+      this->m_ReferenceLine = new QCPItemLine( this->m_UI->Plot );
+    this->m_ReferenceLine->start->setCoords( this->m_ReferenceSlice, 0 );
+    this->m_ReferenceLine->end->setCoords(
+      this->m_ReferenceSlice,
+      this->m_UI->Plot->yAxis->range( ).size( )
+      );
+    this->m_UI->Plot->replot( );
+
+  } // fi
+  if( this->m_StenosisSlice < 0 || this->m_ReferenceSlice < 0 )
+    return;
+
+  double sa, sb, st, sp;
+  this->m_Fourier[ this->m_StenosisSlice ].GetEllipse( 1, sa, sb, st, sp );
+  double sarea = this->m_Fourier[ this->m_StenosisSlice ].GetArea( );
+  double ra, rb, rt, rp;
+  this->m_Fourier[ this->m_ReferenceSlice ].GetEllipse( 1, ra, rb, rt, rp );
+  double rarea = this->m_Fourier[ this->m_ReferenceSlice ].GetArea( );
+  double qmin = 100.0 * ( 1.0 - ( sb / rb ) );
+  double qmax = 100.0 * ( 1.0 - ( sa / ra ) );
+  double qarea = 100.0 * ( 1.0 - ( sarea / rarea ) );
+
+  std::stringstream s;
+  s << "Stenosis: " << std::endl
+    << qmin << "% (min diameter)" << std::endl
+    << qmax << "% (max diameter)" << std::endl
+    << qarea << "% (area)";
+  this->m_StenosisText->setText( s.str( ).c_str( ) );
+  this->m_StenosisText->position->setCoords(
+    ( this->m_ReferenceSlice + this->m_StenosisSlice ) * 0.5,
+    this->m_UI->Plot->yAxis->range( ).center( )
+    );
+  this->m_UI->Plot->replot( );
 }
 
 // -------------------------------------------------------------------------
@@ -628,6 +699,125 @@ _sProcess( )
   this->_showProcessResults( );
 }
 
+// -------------------------------------------------------------------------
+void CTArteries::
+_sMarkReference( )
+{
+  if( this->m_Fourier.size( ) == 0 )
+    return;
+  ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
+  this->m_ReferenceSlice = slice_view->GetImageActor( )->GetSliceNumber( );
+  this->_showStenosis( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sMarkStenosis( )
+{
+  if( this->m_Fourier.size( ) == 0 )
+    return;
+  ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
+  this->m_StenosisSlice = slice_view->GetImageActor( )->GetSliceNumber( );
+  this->_showStenosis( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sSaveResults( )
+{
+  std::string fname =
+    QFileDialog::getSaveFileName(
+      this,
+      "Select one or more files to open",
+      ".",
+      "CSV files (*.csv);;All files (*)"
+      ).toStdString( );
+  if( fname == "" )
+    return;
+
+  std::ofstream out( fname.c_str( ) );
+  out << "slice;min_diameter;max_diameter;area" << std::endl;
+  for( unsigned int i = 0; i < this->m_Fourier.size( ); ++i )
+  {
+    double a, b, t, p;
+    this->m_Fourier[ i ].GetEllipse( 1, a, b, t, p );
+    double area = this->m_Fourier[ i ].GetArea( );
+    out << i << ";" << b << ";" << a << ";" << area << std::endl;
+
+  } // rof
+  out << "############################" << std::endl;
+  typedef ivq::VTK::SeedWidgetOverImageActor::TSeeds _TSeeds;
+  const _TSeeds& seeds = this->m_Seeds->GetSeeds( );
+  for( _TSeeds::value_type seed: seeds )
+  {
+    for( unsigned int i = 0; i < seed.second.size( ); i += 3 )
+    {
+      out
+        << seed.second[ i + 0 ] << " "
+        << seed.second[ i + 1 ] << " "
+        << seed.second[ i + 2 ] << std::endl;
+
+    } // rof
+
+  } // rof
+  out << "############################" << std::endl;
+  out.close( );
+}
+
+// -------------------------------------------------------------------------
+void CTArteries::
+_sUpdateContour( )
+{
+  if( this->m_ContourActor == NULL )
+    return;
+  vtkSmartPointer< vtkPolyData > new_pd =
+    vtkSmartPointer< vtkPolyData >::New( );
+  this->m_Spline->GetPolyData( new_pd );
+
+  ivq::VTK::ImageViewer* slice_view = this->m_UI->Slice->GetViewer( );
+  ivq::VTK::ImageActor* slice_actor = slice_view->GetImageActor( );
+  this->m_ContoursActors[ slice_actor->GetSliceNumber( ) ]->
+    SetInputData( new_pd );
+  slice_view->Render( );
+
+
+  typedef itk::QuadEdgeMesh< double, 2 > _TQEMesh;
+  typedef _TQEMesh::PointType _T2DPoint;
+  typedef std::vector< _T2DPoint > _T2DPoints;
+  _T2DPoints points;
+  _TQEMesh::Pointer mesh = _TQEMesh::New( );
+  for( unsigned int i = 0; i < new_pd->GetNumberOfPoints( ); ++i )
+  {
+    _T2DPoint pnt;
+    double p[ 3 ];
+    new_pd->GetPoint( i, p );
+    pnt[ 0 ] = p[ 0 ];
+    pnt[ 1 ] = p[ 1 ];
+    mesh->AddPoint( pnt );
+
+  } // rof
+  vtkCellArray* lines = new_pd->GetLines( );
+  lines->InitTraversal( );
+  vtkIdType* ids = new vtkIdType[ 2 ];
+  vtkIdType npts;
+  while( lines->GetNextCell( npts, ids ) != 0 )
+    mesh->AddEdge( ids[ 0 ], ids[ 1 ] );
+  delete ids;
+  _TQEMesh::QEPrimal* edge = mesh->GetEdge( );
+  if( edge != NULL )
+  {
+    mesh->AddFace( edge );
+    edge = mesh->GetEdge( );
+    for( auto eIt = edge->BeginGeomLnext( ); eIt != edge->EndGeomLnext( ); ++eIt )
+      points.push_back( mesh->GetPoint( *eIt ) );
+
+    TFourier f( points.begin( ), points.end( ), 6 );
+    f.SetOrderingToCounterClockWise( );
+    this->m_Fourier[ slice_actor->GetSliceNumber( ) ] = f;
+
+  } // fi
+}
+
 // -------------------------------------------------------------------------
 template< class _TImagePtr, class _TVTKImagePtr, class _TCurvePtr >
 void CTArteries::
index 90d9e09987e5e0d1ee4731a0ebf433299e9e230f..0fd1b45c32ebfbe1da6e13a4c14062b8e2da4ccc 100644 (file)
@@ -20,6 +20,8 @@
 class vtkPolyData;
 class vtkSplineWidget;
 class QDialog;
+class QCPItemLine;
+class QCPItemText;
 namespace Ui
 {
   class CTArteries;
@@ -75,6 +77,7 @@ protected:
   void _process( const std::vector< TImage::PointType >& seeds );
   void _prepareQuantification( );
   void _showProcessResults( );
+  void _showStenosis( );
 
   void _ExecuteLog( const std::string& fname );
 
@@ -82,6 +85,10 @@ protected slots:
   void _sOpen( );
   void _sConfig( );
   void _sProcess( );
+  void _sMarkReference( );
+  void _sMarkStenosis( );
+  void _sSaveResults( );
+  void _sUpdateContour( );
 
 private:
   template< class _TImagePtr, class _TVTKImagePtr, class _TCurvePtr >
@@ -124,6 +131,13 @@ private:
   vtkSmartPointer< ivq::VTK::SeedWidgetOverImageActor > m_Seeds;
   vtkSmartPointer< vtkSplineWidget > m_Spline;
 
+  // References
+  int m_StenosisSlice;
+  int m_ReferenceSlice;
+  QCPItemLine* m_StenosisLine;
+  QCPItemLine* m_ReferenceLine;
+  QCPItemText* m_StenosisText;
+
   friend class ContourCallback;
 };
 
index 5bbd8840c0ea8b5ce8ae0e34de8e6faadcd9e054..3af923a26cb3776359eeba80fb39dbde783c2f44 100644 (file)
@@ -44,7 +44,7 @@
      <x>0</x>
      <y>0</y>
      <width>800</width>
-     <height>20</height>
+     <height>17</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -52,6 +52,7 @@
      <string>File</string>
     </property>
     <addaction name="aOpen"/>
+    <addaction name="aSaveResults"/>
     <addaction name="separator"/>
     <addaction name="aExit"/>
    </widget>
@@ -70,6 +71,9 @@
    </attribute>
    <addaction name="aProcess"/>
    <addaction name="aConfig"/>
+   <addaction name="aMarkReference"/>
+   <addaction name="aMarkStenosis"/>
+   <addaction name="aUpdateContour"/>
   </widget>
   <action name="aOpen">
    <property name="text">
     <string>Config</string>
    </property>
   </action>
+  <action name="aMarkReference">
+   <property name="text">
+    <string>Mark reference</string>
+   </property>
+  </action>
+  <action name="aMarkStenosis">
+   <property name="text">
+    <string>Mark stenosis</string>
+   </property>
+  </action>
+  <action name="aSaveResults">
+   <property name="text">
+    <string>Save</string>
+   </property>
+  </action>
+  <action name="aUpdateContour">
+   <property name="text">
+    <string>Update contour</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>