+#include <ctime>
#include <iostream>
#include <limits>
#include <set>
#include <itkImage.h>
#include <itkImageFileReader.h>
+#include <itkImageFileWriter.h>
#include <itkImageToVTKImageFilter.h>
#include <vtkImageActor.h>
+#include <vtkImageMarchingCubes.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
typedef itk::ImageToVTKImageFilter< TImage > TVTKImage;
typedef itk::ImageFileReader< TImage > TImageReader;
+typedef itk::ImageFileWriter< TImage > TImageWriter;
typedef
fpa::Image::RegionGrowWithMultipleThresholds< TImage >
// -------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
- if( argc < 5 )
+ if( argc < 6 )
{
std::cerr
<< "Usage: " << argv[ 0 ]
- << " input_image thr_0 thr_1 step" << std::endl;
+ << " input_image thr_0 thr_1 step output_image"
+ << " visual_debug"
+ << std::endl;
return( 1 );
} // fi
TPixel thr_0 = TPixel( std::atof( argv[ 2 ] ) );
TPixel thr_1 = TPixel( std::atof( argv[ 3 ] ) );
unsigned int step = std::atoi( argv[ 4 ] );
+ std::string output_image_fn = argv[ 5 ];
+ bool visual_debug = false;
+ if( argc > 6 )
+ visual_debug = ( std::atoi( argv[ 6 ] ) == 1 );
// Read image
TImageReader::Pointer input_image_reader = TImageReader::New( );
TImage::IndexType seed_idx;
input_image->TransformPhysicalPointToIndex( seed_pnt, seed_idx );
- // Configure observer
- TObserver::Pointer obs = TObserver::New( );
- obs->SetImage( input_image, view.GetWindow( ) );
-
// Configure algorithm
TFrontAlgorithm::Pointer algorithm = TFrontAlgorithm::New( );
algorithm->AddThresholds( thr_0, thr_1, step );
algorithm->AddSeed( seed_idx, 0 );
- algorithm->AddObserver( itk::AnyEvent( ), obs );
- algorithm->ThrowEventsOn( );
algorithm->SetInput( input_image );
algorithm->SetNeighborhoodOrder( 1 );
algorithm->SetDifferenceThreshold( double( 3 ) );
+
+ if( visual_debug )
+ {
+ // Configure observer
+ TObserver::Pointer obs = TObserver::New( );
+ obs->SetImage( input_image, view.GetWindow( ) );
+ algorithm->AddObserver( itk::AnyEvent( ), obs );
+ algorithm->ThrowEventsOn( );
+ }
+ else
+ algorithm->ThrowEventsOff( );
+
+ std::clock_t start = std::clock( );
algorithm->Update( );
+ std::clock_t end = std::clock( );
+ double seconds = double( end - start ) / double( CLOCKS_PER_SEC );
+ std::cout << "Execution time = " << seconds << std::endl;
+
+ // Show result
+ TVTKImage::Pointer output_image_vtk = TVTKImage::New( );
+ output_image_vtk->SetInput( algorithm->GetOutput( ) );
+ output_image_vtk->Update( );
+
+ vtkSmartPointer< vtkImageMarchingCubes > mc =
+ vtkSmartPointer< vtkImageMarchingCubes >::New( );
+ mc->SetInputData( output_image_vtk->GetOutput( ) );
+ mc->SetValue(
+ 0,
+ double( algorithm->GetInsideValue( ) ) * double( 0.95 )
+ );
+ mc->Update( );
// Let some interaction and close program
+ view.AddPolyData( mc->GetOutput( ), 0.1, 0.6, 0.8, 0.5 );
view.Start( );
+
+ // Write resulting image
+ TImageWriter::Pointer output_image_writer = TImageWriter::New( );
+ output_image_writer->SetInput( algorithm->GetOutput( ) );
+ output_image_writer->SetFileName( output_image_fn );
+ try
+ {
+ output_image_writer->Update( );
+ }
+ catch( itk::ExceptionObject& err )
+ {
+ std::cerr << "Error caught: " << err << std::endl;
+ return( 1 );
+
+ } // yrt
return( 0 );
}
this->_InitializeQueue( );
this->_Loop( );
this->_AfterMainLoop( );
+ this->InvokeEvent( TEndEvent( ) );
}
// -------------------------------------------------------------------------
} // fi
} // elihw
- this->InvokeEvent( TEndEvent( ) );
this->_AfterLoop( );
}
itkNewMacro( Self );
itkTypeMacro( RegionGrowWithMultipleThresholds, RegionGrow );
+ itkGetConstMacro( InsideValue, TPixel );
+ itkGetConstMacro( OutsideValue, TPixel );
itkGetConstMacro( DifferenceThreshold, double );
+
+ itkSetMacro( InsideValue, TPixel );
+ itkSetMacro( OutsideValue, TPixel );
itkSetMacro( DifferenceThreshold, double );
public:
protected:
TThresholds m_Thresholds;
+ TPixel m_InsideValue;
+ TPixel m_OutsideValue;
double m_DifferenceThreshold;
THistogram m_Histogram;
unsigned long m_TotalCount;
#define __FPA__IMAGE__REGIONGROWWITHMULTIPLETHRESHOLDS__HXX__
#include <limits>
+#include <itkBinaryThresholdImageFilter.h>
#include <itkConstNeighborhoodIterator.h>
// -------------------------------------------------------------------------
fpa::Image::RegionGrowWithMultipleThresholds< I >::
RegionGrowWithMultipleThresholds( )
: Superclass( ),
+ m_InsideValue( TPixel( 1 ) ),
+ m_OutsideValue( TPixel( 0 ) ),
m_DifferenceThreshold( double( 3 ) ),
m_TotalCount( 0 ),
m_LastDiff( double( 0 ) ),
void fpa::Image::RegionGrowWithMultipleThresholds< I >::
_AfterMainLoop( )
{
+ typedef itk::BinaryThresholdImageFilter< I, I > _TBinFilter;
+
+ // Binarize, inplace, the grown region
+ if( this->m_Histogram.size( ) > 1 )
+ {
+ typename _TBinFilter::Pointer bin = _TBinFilter::New( );
+ bin->SetInput( this->GetOutput( ) );
+ bin->SetInsideValue( this->m_InsideValue );
+ bin->SetOutsideValue( this->m_OutsideValue );
+ bin->InPlaceOn( );
+ if( this->m_StopForced )
+ bin->SetUpperThreshold( this->m_StopThreshold );
+ else
+ bin->SetUpperThreshold( this->m_Histogram.rbegin( )->first );
+ bin->GraftOutput( this->GetOutput( ) );
+ bin->Update( );
+ this->GraftOutput( bin->GetOutput( ) );
+
+ } // fi
+
this->Superclass::_AfterMainLoop( );
}
{
vtkRenderer* ren =
this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
- // TODO: ren->RemoveActor( this->m_PolyDataActor );
+ ren->RemoveActor( this->m_PolyDataActor );
this->Render( );
} // fi
// -------------------------------------------------------------------------
void fpa::VTK::ImageMPR::
-AddPolyData( vtkPolyData* pd, double r, double g, double b )
+AddPolyData( vtkPolyData* pd, double r, double g, double b, double opacity )
{
unsigned int i = this->m_PolyDatas.size( );
this->m_Actors.push_back( vtkSmartPointer< vtkActor >::New( ) );
this->m_Mappers[ i ]->SetInputData( pd );
+ this->m_Mappers[ i ]->ScalarVisibilityOff( );
this->m_Actors[ i ]->SetMapper( this->m_Mappers[ i ] );
this->m_Actors[ i ]->GetProperty( )->SetColor( r, g, b );
+ this->m_Actors[ i ]->GetProperty( )->SetOpacity( opacity );
this->m_Renderer->AddActor( this->m_Actors[ i ] );
}
void SetBackground( double r, double g, double b );
void SetSize( unsigned int w, unsigned int h );
- void AddPolyData( vtkPolyData* pd, double r, double g, double b );
+ void AddPolyData(
+ vtkPolyData* pd,
+ double r, double g, double b, double opacity = double( 1 )
+ );
unsigned int GetNumberOfSeeds( ) const;
void GetSeed( int n, double* s ) const;