From c1cf87b9287cd0a9fb3ca718ea2c39f014cb4b1b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leonardo=20Fl=C3=B3rez-Valencia?= Date: Fri, 13 Oct 2017 16:03:15 -0500 Subject: [PATCH] ... --- appli/CTBronchi/CMakeLists.txt | 1 + appli/CTBronchi/SliceBySliceRandomWalker.cxx | 112 +++++++++++++++++++ lib/fpa/Common/SliceBySliceRandomWalker.h | 12 +- lib/fpa/Common/SliceBySliceRandomWalker.hxx | 63 ++++------- 4 files changed, 138 insertions(+), 50 deletions(-) create mode 100644 appli/CTBronchi/SliceBySliceRandomWalker.cxx diff --git a/appli/CTBronchi/CMakeLists.txt b/appli/CTBronchi/CMakeLists.txt index c88add4..79a58ad 100644 --- a/appli/CTBronchi/CMakeLists.txt +++ b/appli/CTBronchi/CMakeLists.txt @@ -11,6 +11,7 @@ if(fpa_BUILD_CTBronchi) MoriSegmentation MoriLabelling FastRandomWalker + SliceBySliceRandomWalker ) foreach(_e ${_examples}) BuildApplication( diff --git a/appli/CTBronchi/SliceBySliceRandomWalker.cxx b/appli/CTBronchi/SliceBySliceRandomWalker.cxx new file mode 100644 index 0000000..b67e258 --- /dev/null +++ b/appli/CTBronchi/SliceBySliceRandomWalker.cxx @@ -0,0 +1,112 @@ +// ========================================================================= +// @author Leonardo Florez Valencia +// @email florez-l@javeriana.edu.co +// ========================================================================= + +#include +#include +#include +#include +#include "Functions.h" + +// ------------------------------------------------------------------------- +const unsigned int Dim = 3; +typedef short TPixel; +typedef unsigned char TLabel; +typedef itk::NumericTraits< TPixel >::RealType TScalar; +typedef itk::Image< TPixel, Dim > TImage; +typedef itk::Image< TLabel, Dim > TLabels; +typedef itk::Image< TScalar, Dim > TScalarImage; + +// ------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + typedef TCLAP::ValueArg< std::string > _TStringArg; + typedef TCLAP::ValueArg< TScalar > _TRealArg; + + // Parse input line + _TStringArg in( "i", "input", "Input image", true, "", "file" ); + _TStringArg labels( "l", "labels", "Input labels", true, "", "file" ); + _TStringArg vesselness( "v", "vesselness", "Input vesselness", true, "", "file" ); + _TStringArg out( "o", "output", "Output image", true, "", "file" ); + _TRealArg beta( "b", "beta", "Beta", false, 2.5, "value (2.5)" ); + _TRealArg eps( "e", "epsilon", "Epsilon", false, 1e-5, "value (1e-5)" ); + try + { + TCLAP::CmdLine cmd( "FastRandomWalker", ' ', "1.0.0" ); + cmd.add( eps ); + cmd.add( beta ); + cmd.add( out ); + cmd.add( vesselness ); + cmd.add( labels ); + cmd.add( in ); + cmd.parse( argc, argv ); + } + catch( TCLAP::ArgException& err ) + { + std::cerr + << "===============================" << std::endl + << "Error caught: " << std::endl + << err.error( ) << " " << err.argId( ) << std::endl + << "===============================" << std::endl + << std::endl; + return( 1 ); + + } // yrt + + try + { + // Read input image + TImage::Pointer input_image; + CTBronchi::ReadImage( input_image, in.getValue( ) ); + + // Read input labels + TLabels::Pointer input_labels; + CTBronchi::ReadImage( input_labels, labels.getValue( ) ); + + // Read input vesselness + TScalarImage::Pointer input_vesselness; + CTBronchi::ReadImage( input_vesselness, vesselness.getValue( ) ); + + // Random walk + typedef fpa::Common::SliceBySliceRandomWalker< TImage, TLabels, TScalarImage > TFilter; + TFilter::Pointer filter = TFilter::New( ); + filter->SetInput( input_image ); + filter->SetInputLabels( input_labels ); + filter->SetInputVesselness( input_vesselness ); + + // Prepare weight functor + /* TODO + typedef fpa::Functors::Dijkstra::Image::Gaussian< TImage, TScalar > TWeight; + TWeight::Pointer weight = TWeight::New( ); + weight->SetBeta( beta.getValue( ) ); + weight->SetEpsilon( eps.getValue( ) ); + + // Random walk + typedef fpa::Filters::Image::RandomWalker< TImage, TLabels, TScalar > TFilter; + TFilter::Pointer filter = TFilter::New( ); + filter->SetInputImage( input_image ); + filter->SetInputLabels( input_labels ); + filter->SetWeightFunction( weight ); + double t = CTBronchi::MeasureTime( filter ); + std::cout << "FastRandomWalk executed in " << t << " s" << std::endl; + + // Write result + CTBronchi::WriteImage( filter->GetOutputLabels( ), out.getValue( ) ); + */ + } + catch( std::exception& err ) + { + std::cerr + << "===============================" << std::endl + << "Error caught: " << std::endl + << err.what( ) << std::endl + << "===============================" << std::endl + << std::endl; + return( 1 ); + + } // yrt + return( 0 ); +} + +// eof - $RCSfile$ diff --git a/lib/fpa/Common/SliceBySliceRandomWalker.h b/lib/fpa/Common/SliceBySliceRandomWalker.h index 48f2bed..f16fe64 100644 --- a/lib/fpa/Common/SliceBySliceRandomWalker.h +++ b/lib/fpa/Common/SliceBySliceRandomWalker.h @@ -61,19 +61,11 @@ namespace fpa ); template< class _TBinaryTree, class _TData3D, class _TFusion > - void _GoDown( + void _RandomWalker( _TBinaryTree& binaryTree, const _TData3D& data3D, const _TFusion& fusion, - int numSlices - ); - - template< class _TBinaryTree, class _TData3D, class _TFusion > - void _GoUp( - _TBinaryTree& binaryTree, - const _TData3D& data3D, - const _TFusion& fusion, - int numSlices + bool down ); private: diff --git a/lib/fpa/Common/SliceBySliceRandomWalker.hxx b/lib/fpa/Common/SliceBySliceRandomWalker.hxx index d1fbd9c..1cad2a1 100644 --- a/lib/fpa/Common/SliceBySliceRandomWalker.hxx +++ b/lib/fpa/Common/SliceBySliceRandomWalker.hxx @@ -57,10 +57,7 @@ GenerateData( ) this->m_VesselnessThreshold * this->m_VesselnessMax / TScalar( 100 ); // Composite image - typename TScalarImage::Pointer composite = TScalarImage::New( ); - composite->CopyInformation( vesselness ); - composite->SetBufferedRegion( vesselness->GetBufferedRegion( ) ); - composite->Allocate( ); + typename TScalarImage::Pointer composite; this->_Composite( composite, labels, vesselness ); // Extract slices @@ -90,8 +87,8 @@ GenerateData( ) } // rof // Random walker slice-by-slice - this->_GoDown( binaryTree, data3D, fusion, numSlices ); - this->_GoUp( binaryTree, data3D, fusion, numSlices ); + this->_RandomWalker( binaryTree, data3D, fusion, true ); + this->_RandomWalker( binaryTree, data3D, fusion, false ); // Join results typedef itk::JoinSeriesImageFilter< _TSliceImage, TImage > _TJoin; @@ -121,7 +118,7 @@ _Composite( typename TScalarImage::RegionType region = labels->GetRequestedRegion( ); // Composite image - typename TScalarImage::Pointer composite = TScalarImage::New( ); + composite = TScalarImage::New( ); composite->CopyInformation( vesselness ); composite->SetBufferedRegion( vesselness->GetBufferedRegion( ) ); composite->Allocate( ); @@ -163,11 +160,11 @@ template< class _TImage, class _TLabels, class _TScalarImage > template< class _TBinaryTree, class _TData3D, class _TFusion > void fpa::Common::SliceBySliceRandomWalker< _TImage, _TLabels, _TScalarImage >:: -_GoDown( +_RandomWalker( _TBinaryTree& binaryTree, const _TData3D& data3D, const _TFusion& fusion, - int numSlices + bool down ) { typedef typename _TBinaryTree::value_type _TSliceBinaryPtr; @@ -178,14 +175,16 @@ _GoDown( typedef typename _TSliceFusionPtr::ObjectType _TSliceFusion; typedef typename _TSliceFusion::PixelType _TSliceScalar; - int z = -1; - while( z < numSlices - 2 ) + int numSlices = binaryTree.size( ); + int z = ( down )? -1: numSlices; + int o = ( down )? 1: -1; + while( ( down && z < numSlices - 2 ) || ( !down && z > 1 ) ) { - z++; + z += o; _TSliceBinaryPtr tmp = binaryTree[ z ]; - _TSliceBinaryPtr next = binaryTree[ z + 1 ]; - _TSliceData3DPtr data = data3D[ z + 1 ]; - _TSliceFusionPtr vess = fusion[ z + 1 ]; + _TSliceBinaryPtr next = binaryTree[ z + o ]; + _TSliceData3DPtr data = data3D[ z + o ]; + _TSliceFusionPtr vess = fusion[ z + o ]; typename _TSliceBinary::RegionType region = tmp->GetRequestedRegion( ); // Create seeds and background @@ -245,31 +244,15 @@ _GoDown( rw->SetEdgeFunction( edge ); // Keep maximum - /* TODO - typedef itk::MaximumImageFilter MaxFilterType; - MaxFilterType::Pointer maxFilter = MaxFilterType::New(); - maxFilter->SetInput(0, img2); - maxFilter->SetInput(1, next); - maxFilter->Update(); - - SliceType::Pointer sth = maxFilter->GetOutput(); - ImageAlgorithm::Copy(sth.GetPointer(), binaryTree[z + 1].GetPointer(), sth->GetRequestedRegion(), binaryTree[z + 1]->GetRequestedRegion()); - delete[] probs; - */ - } -} - -// ------------------------------------------------------------------------- -template< class _TImage, class _TLabels, class _TScalarImage > -template< class _TBinaryTree, class _TData3D, class _TFusion > -void -_GoUp( - _TBinaryTree& binaryTree, - const _TData3D& data3D, - const _TFusion& fusion, - int numSlices - ) -{ + typedef itk::MaximumImageFilter< _TSliceBinary > _TMax; + _TMax::Pointer max = _TMax::New(); + max->SetInput( 0, rw->GetOutput( ) ); + max->SetInput( 1, next ); + max->Update( ); + binaryTree[ z + o ] = max->GetOutput( ); + binaryTree[ z + o ]->DisconnectPipeline( ); + + } // elihw } #endif // __fpa__Common__SliceBySliceRandomWalker__hxx__ -- 2.45.1