// ========================================================================= // @author Leonardo Florez Valencia // @email florez-l@javeriana.edu.co // ========================================================================= #include #include #include #include #include #include // ------------------------------------------------------------------------- const unsigned int Dim = 3; typedef short TPixel; typedef unsigned char TLabel; typedef itk::Image< TPixel, Dim > TImage; typedef itk::Image< TLabel, Dim > TLabels; // ------------------------------------------------------------------------- double MeasureTime( itk::ProcessObject* f ) { std::chrono::time_point< std::chrono::high_resolution_clock > s, e; std::chrono::duration< double > t; s = std::chrono::high_resolution_clock::now( ); f->Update( ); e = std::chrono::high_resolution_clock::now( ); t = e - s; return( t.count( ) ); } // ------------------------------------------------------------------------- template< class _TImagePtr > void ReadImage( _TImagePtr& image, const std::string& fname ) { typedef typename _TImagePtr::ObjectType _TImage; typedef itk::ImageFileReader< _TImage > _TReader; typename _TReader::Pointer reader = _TReader::New( ); reader->SetFileName( fname ); double t = MeasureTime( reader ); std::cout << "Read " << fname << " in " << t << " s" << std::endl; image = reader->GetOutput( ); image->DisconnectPipeline( ); } // ------------------------------------------------------------------------- template< class _TImage > void WriteImage( const _TImage* image, const std::string& fname ) { typedef itk::ImageFileWriter< _TImage > _TWriter; typename _TWriter::Pointer writer = _TWriter::New( ); writer->SetFileName( fname ); writer->SetInput( image ); double t = MeasureTime( writer ); std::cout << "Wrote " << fname << " in " << t << " s" << std::endl; } // ------------------------------------------------------------------------- bool ParseArgs( std::map< std::string, std::string >& args, int argc, char* argv[] ) { std::set< std::string > mandatory; mandatory.insert( "in" ); mandatory.insert( "out" ); mandatory.insert( "seed" ); args[ "minimum_threshold" ] = "-850"; args[ "signal_kernel_size" ] = "20"; args[ "signal_threshold" ] = "100"; args[ "signal_influence" ] = "0.5"; args[ "lower_threshold" ] = "-1024"; args[ "upper_threshold" ] = "0"; args[ "delta_threshold" ] = "1"; int i = 1; while( i < argc ) { std::string cmd = argv[ i ] + 1; if( cmd == "seed" ) { std::stringstream seed; seed << argv[ i + 1 ] << ";" << argv[ i + 2 ] << ";" << argv[ i + 3 ]; args[ cmd ] = seed.str( ); i += 4; } else { args[ cmd ] = argv[ i + 1 ]; i += 2; } // fi } // elihw bool complete = true; for( std::string t: mandatory ) complete &= ( args.find( t ) != args.end( ) ); if( !complete ) { std::cerr << "Usage: " << argv[ 0 ] << std::endl << "\t-in filename" << std::endl << "\t-out filename" << std::endl << "\t-seed x y z" << std::endl << "\t[-out_signal filename]" << std::endl << "\t[-minimum_threshold value]" << std::endl << "\t[-signal_kernel_size value]" << std::endl << "\t[-signal_threshold value]" << std::endl << "\t[-signal_influence value]" << std::endl << "\t[-lower_threshold value]" << std::endl << "\t[-upper_threshold value]" << std::endl << "\t[-delta_threshold value]" << std::endl; return( false ); } // fi return( true ); } // ------------------------------------------------------------------------- int main( int argc, char* argv[] ) { std::map< std::string, std::string > args; try { if( ParseArgs( args, argc, argv ) ) { // Parse seed TImage::PointType seed; char* str = new char[ args[ "seed" ].size( ) + 1 ]; strcpy( str, args[ "seed" ].c_str( ) ); seed[ 0 ] = std::atof( strtok( str, ";" ) ); seed[ 1 ] = std::atof( strtok( NULL, ";" ) ); seed[ 2 ] = std::atof( strtok( NULL, ";" ) ); // Read input image TImage::Pointer input_image; ReadImage( input_image, args[ "in" ] ); // Mori segmentation typedef fpa::Filters::Image::Mori< TImage, TLabels > TMori; TMori::Pointer mori = TMori::New( ); mori->SetInput( input_image ); mori->SetSeed( seed ); mori->SetInsideValue( 1 ); mori->SetOutsideValue( 0 ); mori->SetMinimumThreshold( TPixel( std::atof( args[ "minimum_threshold" ].c_str( ) ) ) ); mori->SetSignalKernelSize( std::atoi( args[ "signal_kernel_size" ].c_str( ) ) ); mori->SetSignalThreshold( std::atof( args[ "signal_threshold" ].c_str( ) ) ); mori->SetSignalInfluence( std::atof( args[ "signal_influence" ].c_str( ) ) ); mori->SetThresholds( TPixel( std::atof( args[ "lower_threshold" ].c_str( ) ) ), TPixel( std::atof( args[ "upper_threshold" ].c_str( ) ) ), TPixel( std::atof( args[ "delta_threshold" ].c_str( ) ) ) ); double t = MeasureTime( mori ); std::cout << "Mori executed in " << t << " s" << std::endl; WriteImage( mori->GetOutput( ), args[ "out" ] ); std::map< std::string, std::string >::const_iterator i = args.find( "out_signal" ); if( i != args.end( ) ) { std::stringstream signal; unsigned long nthr = mori->GetNumberOfEvaluatedThresholds( ); signal << "# nThr = " << nthr << std::endl; signal << "# Opt = " << mori->GetOptimumThreshold( ) << std::endl; for( unsigned long j = 0; j < nthr; ++j ) { typename TMori::TPeak p; double x, y; mori->GetSignalValues( j, x, y, p ); signal << x << " " << y << std::endl; } // rof std::ofstream signals_str( i->second.c_str( ) ); signals_str << signal.str( ); signals_str.close( ); } // fi } else return( 1 ); } catch( std::exception& err ) { std::cerr << "===============================" << std::endl << "Error caught: " << std::endl << err.what( ) << "===============================" << std::endl << std::endl; return( 1 ); } // yrt return( 0 ); } // eof - $RCSfile$