void ChannelListAttribute::readValueFrom (IStream &is, int size, int version) { while (true) { // // Read name; zero length name means end of channel list // char name[Name::SIZE]; Xdr::read <StreamIO> (is, sizeof (name), name); if (name[0] == 0) break; // // Read Channel struct // int type; int xSampling; int ySampling; Xdr::read <StreamIO> (is, type); Xdr::skip <StreamIO> (is, 4); Xdr::read <StreamIO> (is, xSampling); Xdr::read <StreamIO> (is, ySampling); _value.insert (name, Channel (PixelType (type), xSampling, ySampling)); } }
dng_image * dng_simple_image::Clone () const { AutoPtr<dng_simple_image> result (new dng_simple_image (Bounds (), Planes (), PixelType (), fAllocator)); result->fBuffer.CopyArea (fBuffer, Bounds (), 0, Planes ()); return result.Release (); }
uint32 dng_image::PixelSize () const { return TagTypeSize (PixelType ()); }
int main(int argc, char **argv) { ParametersVectorType initialParameters; std::string outPrefix, bmImageName, initFile, initMeansFile, mrfModelFile; std::string s_minimization = DEFAULT_MRF_ALG; float lambda1, lambda2; ProbabilityPixelType atlas_th, mask_th; unsigned int nClasses, emIterations, mrfIterations; std::vector<std::string> channels, priors, geometricTerm; std::string s_mode = "km+em"; std::string outExt = "nii.gz"; std::vector<double> dataOffsets; std::vector<double> dataFactors; bool useFile = false; bool skipMRF = false; bool usePVE = false; bool doOutputStats,doSegmentsOutput, doOutputMRFMaps, doOutputMRFIterations, doOutputSteps, useExplicitPVE, skipNormalization, skipBias, doBiasOutput, doCorrectedOutput, channelsAreMasked = false; unsigned int userBucketSize = 0; boost::unordered_map<std::string, INIT_MODES> modes_map; modes_map["none"] = NONE; modes_map["km"] = KMEANS; modes_map["em"] = EM; modes_map["km+em"] = KMEANS_EM; boost::unordered_map<std::string, typename MRFFilter::GCOptimizerType::MINIMIZATION_MODES > minimiz_map; minimiz_map["expansion"] = MRFFilter::GCOptimizerType::EXPANSION; minimiz_map["swap"] = MRFFilter::GCOptimizerType::SWAP; bpo::options_description general("General options"); general.add_options() ("help", "show help message") ("out,o",bpo::value < std::string > (&outPrefix), "prefix for output files") ("out-ext", bpo::value< std::string >( &outExt ), "output format, if supported by ITK") ("brain-mask,x",bpo::value < std::string > (&bmImageName),"brain extracted mask") ("channels-masked,M", bpo::bool_switch(&channelsAreMasked), "set this flag if channels are already masked") ("channels,C", bpo::value< std::vector< std::string > >(&channels)->multitoken()->required(),"list of channels for multivariate segmentation") ("class,n", bpo::value<unsigned int>(&nClasses)->default_value(DEFAULT_NCLASSES), "number of tissue-type classes") ("init,I", bpo::value< std::string >(&s_mode), "operation mode for initialization [none,km,em,km+em]") ("init-file,f",bpo::value < std::string > (&initFile),"use file for initialization of tissue-type means & variances") ("init-means",bpo::value < std::string > (&initMeansFile),"use file for initialization of tissue-type means") ("segments,g", bpo::bool_switch(&doSegmentsOutput),"Output a posteriori probability for each class") //("pv", bpo::bool_switch(&useExplicitPVE), "Use explicit PVE Gaussian Model between tissues") ("output-stats", bpo::bool_switch(&doOutputStats),"output classes statistics to CSV file") ("output-steps", bpo::bool_switch(&doOutputSteps), "Output intermediate segmentation steps") ("normalize-off,N", bpo::bool_switch(&skipNormalization), "Do not normalize input's intensity range") ("brain-mask-th,t",bpo::value < ProbabilityPixelType > (&mask_th)->default_value(0.0), "mask probability threshold") ("version,v", "show tool version"); bpo::options_description kmeans_desc("Kmeans options"); kmeans_desc.add_options() ("bucket-size", bpo::value< unsigned int >(&userBucketSize), "bucket size for K-means operation"); bpo::options_description em_desc("Expectation-Maximization options"); em_desc.add_options() ("priors,P", bpo::value< std::vector< std::string > >(&priors)->multitoken(),"add prior to list of atlases for initializing segmentation") ("atlas-threshold",bpo::value < ProbabilityPixelType > (&atlas_th)->default_value(DEFAULT_ATLAS_TH), "threshold for atlases") ("em-iterations", bpo::value<unsigned int>(&emIterations)->default_value(DEFAULT_MAX_ITER), "maximum number of iterations"); bpo::options_description bias_desc("Bias estimator options"); bias_desc.add_options() ("bias-skip", bpo::bool_switch(&skipBias), "Do not estimate Bias field") ("bias-output", bpo::bool_switch(&doBiasOutput), "Output estimated Bias field") ("bias-corrected-output", bpo::bool_switch(&doCorrectedOutput), "Output corrected input images with estimated Bias field"); bpo::options_description mrf_desc( "MRF Segmentation options" ); mrf_desc.add_options() ("mrf-lambda,l", bpo::value<float>(&lambda1)->default_value(DEFAULT_LAMBDA),"Regularization weighting. The higher this value is, the higher smoothing. You may use a value around 0.3-1.0 for typical brain images") ("mrf-minimization,m", bpo::value < std::string > (&s_minimization)->default_value(DEFAULT_MRF_ALG), "Minimization algorithm") ("mrf-energy-model,e",bpo::value < std::string > (&mrfModelFile), "Energy Model matrix, basic Pott's Model used if missing" ) ("mrf-iterations", bpo::value<unsigned int>(&mrfIterations)->default_value(DEFAULT_MRF_ITERATIONS),"MRF re-estimation iterations") ("mrf-skip,S", bpo::bool_switch(&skipMRF),"Skip MRF step") ("mrf-pve", bpo::bool_switch(&usePVE), "Compute PVE classes") ("mrf-external-lambda", bpo::value<float>(&lambda2)->default_value(1.0),"External field energy weighting. The higher this value is, the higher impact from the external field") ("mrf-external-field,E", bpo::value< std::vector< std::string > >(&geometricTerm)->multitoken(),"External field maps that manipulate the dataterm in MRF energy function") ("mrf-output-maps", bpo::bool_switch(&doOutputMRFMaps), "Output GC probabilities and energy maps") ("mrf-output-it", bpo::bool_switch(&doOutputMRFIterations), "Output intermediate segmentation steps"); bpo::options_description all("Usage"); all.add(general).add(kmeans_desc).add(bias_desc).add(em_desc).add(mrf_desc); bpo::variables_map vmap; bpo::store(bpo::command_line_parser(argc, argv).options(all).run(), vmap); if ( vmap.count("version")) { std::cout << "MBIS Segmentation tool. Version " << MBIS_VERSION_MAJOR << "." << MBIS_VERSION_MINOR << "-" << MBIS_RELEASE << "." << std::endl; std::cout << "--------------------------------------------------------"<< std::endl; std::cout << "Copyright (c) 2012, [email protected] (Oscar Esteban)"<< std::endl; std::cout << "with Signal Processing Lab 5, EPFL (LTS5-EPFL)"<< std::endl; std::cout << "and Biomedical Image Technology, UPM (BIT-UPM)"<< std::endl; std::cout << "All rights reserved."<< std::endl; return 0; } if ( vmap.empty() || vmap.count("help")) { std::cout << all << std::endl; return 0; } try { bpo::notify(vmap); } catch (boost::exception_detail::clone_impl< boost::exception_detail::error_info_injector< boost::program_options::required_option> > &err) { std::cout << "Error parsing options:" << err.what() << std::endl; std::cout << std::endl << all << std::endl; return EXIT_FAILURE; } std::cout << std::endl << "Set-up step --------------------------------------------" << std::endl; ProbabilityImagePointer bm; InputVector input; PriorsVector atlas; ClassifiedImageType::Pointer solution; bool useFileMask = vmap.count("brain-mask") && bfs::exists(bmImageName); bool useImplicitMasks = channelsAreMasked && !useFileMask; if( useFileMask ) { ProbabilityImageReader::Pointer r = ProbabilityImageReader::New(); r->SetFileName(bmImageName); r->Update(); try { bm = r->GetOutput(); } catch (...) { std::cout << "Error reading brain mask" << std::endl; return EXIT_FAILURE; } StatisticsImageFilterType::Pointer calc = StatisticsImageFilterType::New(); calc->SetInput(bm); calc->Update(); ProbabilityPixelType max = calc->GetMaximum(); if (max > 1.0 ){ ProbabilityPixelType min = calc->GetMinimum(); IntensityWindowingImageFilterType::Pointer intensityFilter = IntensityWindowingImageFilterType::New(); intensityFilter->SetInput( bm ); intensityFilter->SetWindowMaximum( max ); intensityFilter->SetWindowMinimum( min ); intensityFilter->SetOutputMaximum( 1.0 ); intensityFilter->SetOutputMinimum( 0.0 ); intensityFilter->Update(); bm = intensityFilter->GetOutput(); } std::cout << "\t* Mask: read from file " << bmImageName << "."; if ( mask_th != 0.0 ) { ThresholdImageFilterType::Pointer th = ThresholdImageFilterType::New(); th->SetInput( bm ); th->ThresholdBelow( mask_th ); th->Update(); bm = th->GetOutput(); std::cout << " Mask Threshold = " << mask_th << "."; } std::cout << std::endl; } else { if ( useImplicitMasks ) { std::cout << "\t* Mask: channels are masked." << std::endl; } else { std::cout << "\t* Mask: not requested." << std::endl; } } std::cout << "\t* Inputs normalization is " << ((!skipNormalization)?"ON":"OFF") << std::endl; for (vector<string>::iterator it = channels.begin(); it != channels.end(); it++) { ChannelReader::Pointer r = ChannelReader::New(); r->SetFileName( *it ); ChannelPointer p = r->GetOutput(); r->Update(); ChannelPixelType max = itk::NumericTraits< ChannelPixelType >::max(); ChannelPixelType min = 0.0; ChannelPixelType absMin = 0.0; if ( bm.IsNotNull() ) { ProbabilityPixelType* mBuff = bm->GetBufferPointer(); ChannelPixelType* cBuff = r->GetOutput()->GetBufferPointer(); size_t nPix = bm->GetLargestPossibleRegion().GetNumberOfPixels(); std::vector< ChannelPixelType > sample; for( size_t i = 0; i<nPix; i++ ) { if ( *(mBuff+i) > 0 ) { sample.push_back( *(cBuff+i) ); } } std::sort( sample.begin(), sample.end() ); max = sample[ (size_t) ((sample.size()-1)*0.98) ]; min = sample[ (size_t) ((sample.size()-1)*0.02) ]; absMin = sample[0]; } else { StatisticsChannelFilterType::Pointer calc = StatisticsChannelFilterType::New(); calc->SetInput(p); calc->Update(); max = calc->GetMaximum(); min = calc->GetMinimum(); absMin = min; } if( !skipNormalization ) { double factor = NORM_MAX_INTENSITY / (max - min); double constant = - factor * absMin; if ( factor!= 1 ) { typename MultiplyFilter::Pointer multiplier = MultiplyFilter::New(); multiplier->SetInput( p ); multiplier->SetConstant( factor ); multiplier->Update(); p = multiplier->GetOutput(); } if ( constant!= 0 ) { typename AddConstantFilter::Pointer adder = AddConstantFilter::New(); adder->SetInput( p ); adder->SetConstant( - constant ); adder->Update(); p = adder->GetOutput(); } dataOffsets.push_back( constant ); dataFactors.push_back( factor ); if ( bm.IsNotNull() ) { ChannelImageType::DirectionType dir = bm->GetDirection(); p->SetDirection( dir ); p->SetOrigin( bm->GetOrigin() ); MaskChannelFilterType::Pointer m = MaskChannelFilterType::New(); m->SetInput( p ); m->SetMaskImage( bm ); m->Update(); p = m->GetOutput(); } if( doOutputSteps ) { itk::ImageFileWriter< ChannelImageType >::Pointer wc = itk::ImageFileWriter< ChannelImageType >::New(); wc->SetInput( p ); std::stringstream ss; ss << outPrefix << "_normin_" << input.size() << "." << outExt; wc->SetFileName( ss.str() ); wc->Update(); } } InputComponentConstPointer im; typename ChannelToComponentCaster::Pointer c = ChannelToComponentCaster::New(); c->SetInput(p); c->Update(); im = c->GetOutput(); input.push_back( im ); std::cout << "\t* Channel [" << std::setw(2) << input.size() << "] read: " << (*it) << std::endl; } if ( useImplicitMasks ) { bm = ProbabilityImageType::New(); bm->SetRegions( input[0]->GetLargestPossibleRegion() ); bm->CopyInformation( input[0] ); bm->Allocate(); bm->FillBuffer( 1.0 ); bm->Update(); ProbabilityPixelType* buffer = bm->GetBufferPointer(); size_t numberOfPixels = bm->GetLargestPossibleRegion().GetNumberOfPixels(); for ( size_t i = 0; i < input.size(); i++) { const PixelType* buffer2 = input[i]->GetBufferPointer(); for( size_t offset = 0; offset < numberOfPixels; offset++ ) { if( *( buffer + offset ) > 0.0 ) { *( buffer + offset ) = PixelType ( *( buffer2 + offset ) > 1e-5); } } } if( doOutputSteps ) { itk::ImageFileWriter< ProbabilityImageType >::Pointer wc = itk::ImageFileWriter< ProbabilityImageType >::New(); wc->SetInput( bm ); std::stringstream ss; ss << outPrefix << "_mask." << outExt; wc->SetFileName( ss.str() ); wc->Update(); } } unsigned int init_mode = modes_map[s_mode]; unsigned int nComponents = input.size(); unsigned int nElements = nComponents * (1+nComponents); if( priors.size() > 0 ) { if (init_mode== KMEANS ) init_mode = MANUAL; if (init_mode == KMEANS_EM ) init_mode = EM; for (vector<string>::iterator it = priors.begin(); it != priors.end(); it++) { ProbabilityImageReader::Pointer r = ProbabilityImageReader::New(); r->SetFileName( *it ); ProbabilityImageType::ConstPointer p = r->GetOutput(); r->Update(); StatisticsImageFilterType::Pointer calc = StatisticsImageFilterType::New(); calc->SetInput(p); calc->Update(); ProbabilityPixelType max = calc->GetMaximum(); if (max > 1.0 ){ ProbabilityPixelType min = calc->GetMinimum(); IntensityWindowingImageFilterType::Pointer intensityFilter = IntensityWindowingImageFilterType::New(); intensityFilter->SetInput( p ); intensityFilter->SetWindowMaximum( max ); intensityFilter->SetWindowMinimum( min ); intensityFilter->SetOutputMaximum( 1.0 ); intensityFilter->SetOutputMinimum( 0.0 ); intensityFilter->Update(); p = intensityFilter->GetOutput(); } atlas.push_back(p); std::cout << "\t* Prior [" << std::setw(2) << atlas.size() << "] read: " << (*it) << std::endl; ParameterEstimator::Pointer est = ParameterEstimator::New(); est->SetInputVector( input ); est->SetPrior( p ); if ( bm.IsNotNull() ) { est->SetMaskImage( bm ); } est->Update(); initialParameters.push_back( est->GetOutputParameters() ); } } if ( bfs::exists(initFile)) { if (init_mode== KMEANS ) init_mode = MANUAL; if (init_mode == KMEANS_EM ) init_mode = EM; std::cout << "\t* Parsing tissue parameters file: " << initFile << std::endl; initialParameters = ReadParametersFile(initFile); for ( ParametersVectorType::iterator it = initialParameters.begin(); it!=initialParameters.end(); it++) { size_t n = (*it).size(); if ( n != nElements ) { std::cerr << "Parameters file is incorrect or badly interpreted" << std::endl; } if ( !skipNormalization ) { for( size_t i = 0; i<nComponents; i++ ) { (*it)[i] *= dataFactors[i]; (*it)[i] += dataOffsets[i]; } for( size_t i = nComponents; i<n; i++ ) { (*it)[i] = dataFactors[i%nComponents] * (*it)[i]; } } } useFile = true; std::cout << "\t* Manual Parameters: " << std::endl; for (size_t i = 0; i<initialParameters.size(); i++) std::cout << "\t\t" << initialParameters[i] << std::endl; } if ( bfs::exists(initMeansFile)) { std::cout << "\t* Parsing tissue means file: " << initMeansFile << std::endl; initialParameters = ReadParametersFile( initMeansFile ); for ( ParametersVectorType::iterator it = initialParameters.begin(); it!=initialParameters.end(); it++) { size_t n = (*it).size(); if ( n != nComponents ) { std::cerr << "Means file is incorrect or badly interpreted" << std::endl; } if ( !skipNormalization ) { for( size_t i = 0; i<n; i++ ) { (*it)[i] *= dataFactors[i]; (*it)[i] += dataOffsets[i]; } } } useFile = true; std::cout << "\t* Manual Parameters: " << std::endl; for (size_t i = 0; i<initialParameters.size(); i++) std::cout << "\t\t" << initialParameters[i] << std::endl; } EMFilter::Pointer em_filter; KMeansFilter::Pointer kmeans; if (init_mode == KMEANS || init_mode == KMEANS_EM ) { std::cout << std::endl << "Kmeans step --------------------------------------------" << std::endl; kmeans = KMeansFilter::New(); kmeans->SetInputVector( input ); if ( bm.IsNotNull() ) kmeans->SetMaskImage( bm ); kmeans->SetNumberOfClasses(nClasses); if(vmap.count("bucket-size")) { kmeans->SetUserBucketSize(userBucketSize); } if( useFile ) { kmeans->SetInitialParameters( initialParameters ); } kmeans->Compute(); initialParameters = kmeans->GetOutputParameters(); if (doOutputStats) { stringstream s; s << outPrefix << "_stats_kmeans.csv"; std::ofstream outputCSVfile ( s.str().c_str() ); for ( unsigned int i = 0; i < initialParameters.size(); i++) outputCSVfile << initialParameters[i] << "\n"; outputCSVfile.close(); } kmeans->Update(); } // Check for sanity initial parameters if( initialParameters.size()!=nClasses ) { std::cerr << "Error: initial parameters size (" << initialParameters.size() << ") doesn't match number of classes (" << (int) nClasses << std::endl; } else if ( initialParameters[0].size() != nElements ) { typename MLClassifierFilter::Pointer ml_classifier = MLClassifierFilter::New(); ml_classifier->SetInputVector( input ); if ( bm.IsNotNull() ) ml_classifier->SetMaskImage(bm); ml_classifier->SetParameters( initialParameters ); ml_classifier->Update(); solution = ml_classifier->GetOutput(); if ( doOutputSteps ) { ClassifiedImageWriter::Pointer w = ClassifiedImageWriter::New(); w->SetInput( solution ); w->SetFileName(outPrefix + "_means." + outExt ); w->Update(); } ProbabilityImagePointer unoImage = ProbabilityImageType::New(); unoImage->SetRegions( input[0]->GetLargestPossibleRegion() ); unoImage->CopyInformation( input[0] ); unoImage->Allocate(); unoImage->FillBuffer( 1.0 ); unoImage->Update(); // Initialize Covariance matrix -------------------------------------- ParameterEstimator::Pointer est = ParameterEstimator::New(); est->SetInputVector( input ); typedef itk::LabelImageToLabelMapFilter< ClassifiedImageType > ClassifiedToLabelMapFilter; typedef typename ClassifiedToLabelMapFilter::OutputImageType LabelMap; typedef itk::LabelMapMaskImageFilter< LabelMap, ProbabilityImageType > LabelMapMaskFilter; unsigned int maskOffset = (unsigned int) bm.IsNotNull(); for ( typename ClassifiedImageType::PixelType i = 0 ; i < nClasses ; i++ ) { typename ClassifiedToLabelMapFilter::Pointer lfilter = ClassifiedToLabelMapFilter::New(); lfilter->SetInput( solution ); lfilter->Update(); typename LabelMapMaskFilter::Pointer lmask = LabelMapMaskFilter::New(); lmask->SetInput1( lfilter->GetOutput() ); lmask->SetInput2( unoImage ); lmask->SetLabel( i + maskOffset ); lmask->Update(); est->SetPrior( lmask->GetOutput()); est->Update(); initialParameters[i] = est->GetOutputParameters(); } // End initialize covariance matrix ------------------------------------------- } if (init_mode == EM || init_mode == KMEANS_EM ) { std::cout << std::endl << "E-M Step -----------------------------------------------" << std::endl; em_filter = EMFilter::New(); em_filter->SetMaskImage( bm ); em_filter->SetNumberOfClasses( nClasses ); em_filter->SetMaximumIteration( emIterations ); em_filter->SetMaxBiasEstimationIterations( 5 ); em_filter->SetInputVector( input ); em_filter->SetInitialParameters( initialParameters ); em_filter->SetUseExplicitPVModel( useExplicitPVE ); em_filter->SetUseBiasCorrection( !skipBias ); if ( atlas.size() != 0 ) { em_filter->SetPriors( atlas ); em_filter->SetUsePriorProbabilityImages( true ); } em_filter->Update(); // TODO change to GetModelParameters() initialParameters = em_filter->GetInitialParameters(); solution = em_filter->GetOutput(); if ( doOutputSteps || skipMRF ) { ClassifiedImageWriter::Pointer w = ClassifiedImageWriter::New(); w->SetInput( solution ); w->SetFileName(outPrefix + "_em." + outExt ); w->Update(); } // // Output file with initial stats if switch is true // if (doOutputStats) { stringstream s; s << outPrefix << "_stats_em.csv"; std::ofstream outputCSVfile ( s.str().c_str() ); for ( unsigned int i = 0; i < initialParameters.size(); i++) outputCSVfile << initialParameters[i] << "\n"; outputCSVfile.close(); } if( em_filter->GetUseBiasCorrection() ) { typedef typename EMFilter::EstimatorType::InputVectorImageType VectorImage; typedef typename itk::ImageFileWriter< ChannelImageType > ChannelWriter; typedef itk::VectorIndexSelectionCastImageFilter< VectorImage, ChannelImageType> SelectorType; typename VectorImage::ConstPointer vec = em_filter->GetEstimator()->GetCorrectedInput(); for( int channel = 0; channel< input.size(); channel++ ) { typename SelectorType::Pointer channelSelector = SelectorType::New(); channelSelector->SetInput( vec ); channelSelector->SetIndex( channel ); channelSelector->Update(); channelSelector->GetOutput()->SetRegions( vec->GetRequestedRegion() ); input[channel] = channelSelector->GetOutput(); if ( doCorrectedOutput ) { char name[50]; sprintf(name, "_corrected_ch%02d.%s" , channel, outExt.c_str() ); typename ChannelWriter::Pointer chW = ChannelWriter::New(); chW->SetInput(input[channel]); chW->SetFileName( outPrefix + name ); chW->Update(); } } if( doBiasOutput ) { typedef typename EMFilter::EstimatorType::InputVectorImageType VectorImage; typedef typename itk::ImageFileWriter< ChannelImageType > ChannelWriter; typename VectorImage::ConstPointer bias = em_filter->GetEstimator()->GetCurrentBias(); for( int channel = 0; channel< input.size(); channel++ ) { typename SelectorType::Pointer channelSelector = SelectorType::New(); channelSelector->SetInput( bias ); channelSelector->SetIndex( channel ); channelSelector->Update(); channelSelector->GetOutput()->SetRegions( bias->GetRequestedRegion() ); char name[50]; sprintf(name, "_bias_ch%02d.%s" , channel, outExt.c_str() ); typename ChannelWriter::Pointer chW = ChannelWriter::New(); chW->SetInput(channelSelector->GetOutput()); chW->SetFileName( outPrefix + name ); chW->Update(); } } } } // // MRF Segmentation // if( !skipMRF ) { std::cout << std::endl << "MRF Step -----------------------------------------------" << std::endl; MRFFilter::Pointer mrf = MRFFilter::New(); mrf->SetUseExplicitPVModel( useExplicitPVE ); mrf->SetNumberOfClasses( nClasses ); mrf->SetMaskImage( bm ); mrf->SetInputVector( input ); mrf->SetLambda( lambda1 ); mrf->SetExternalLambda( lambda2 ); mrf->SetUseOutputPriors( doSegmentsOutput ); mrf->SetInitialParameters( initialParameters ); mrf->SetMRFIterations( mrfIterations ); mrf->SetMinimizationMode( minimiz_map[s_minimization] ); mrf->SetOutputPrefix( outPrefix ); if( doOutputMRFIterations ) { typedef itk::SimpleMemberCommand< MRFFilter > ObserverType; ObserverType::Pointer obs = ObserverType::New(); obs->SetCallbackFunction( mrf, &MRFFilter::WriteIteration ); mrf->AddObserver( itk::IterationEvent(), obs ); } if( doOutputMRFMaps ) { typedef itk::SimpleMemberCommand< MRFFilter > ObserverType; ObserverType::Pointer obs = ObserverType::New(); obs->SetCallbackFunction( mrf, &MRFFilter::WriteMaps ); mrf->AddObserver( itk::IterationEvent(), obs ); } if ( doOutputSteps && init_mode == NONE ) { EMFilter::Pointer em_classifier = EMFilter::New(); em_classifier->SetMaskImage( bm ); em_classifier->SetNumberOfClasses( nClasses ); em_classifier->SetInputVector( input ); em_classifier->SetInitialParameters( initialParameters ); em_classifier->SetUseExplicitPVModel( useExplicitPVE ); em_classifier->SetUseOnlyClassify(true); em_classifier->Update(); ClassifiedImageWriter::Pointer w = ClassifiedImageWriter::New(); w->SetInput( em_classifier->GetOutput() ); w->SetFileName(outPrefix + "_mrf_initialization." + outExt ); w->Update(); } if( bfs::exists( mrfModelFile ) ) { std::cout << "\t* Loading Energy Model Matrix: " << mrfModelFile << std::endl; mrf->SetMatrixFile( mrfModelFile ); } for (vector<string>::iterator it = geometricTerm.begin(); it != geometricTerm.end(); it++) { if( bfs::exists(*it) ) { size_t label = (it - geometricTerm.begin()) + 1; ProbabilityImageReader::Pointer r = ProbabilityImageReader::New(); r->SetFileName( *it ); ProbabilityImageType::Pointer p = r->GetOutput(); r->Update(); mrf->SetSpatialEnergyMap(label, p ); std::cout << "\t* Geometrical constraint [" << std::setw(2) << label << "] read: " << (*it) << std::endl; } } mrf->Update(); solution = mrf->GetOutput(); ClassifiedImageWriter::Pointer w2 = ClassifiedImageWriter::New(); w2->SetInput( solution ); w2->SetFileName(outPrefix + "_mrf." + outExt ); w2->Update(); if ( doSegmentsOutput ) { for ( unsigned int i = 1; i<=nClasses; i++ ) { ProbabilityImageWriter::Pointer wProb = ProbabilityImageWriter::New(); wProb->SetInput( mrf->GetPosteriorProbabilityImage(i) ); char name[50]; sprintf(name, "_mrf_seg%02d.%s" , i, outExt.c_str() ); wProb->SetFileName( outPrefix + name ); wProb->Update(); } } if (doOutputStats) { initialParameters = mrf->GetInitialParameters(); stringstream s; s << outPrefix << "_stats_final.csv"; std::ofstream outputCSVfile ( s.str().c_str() ); for ( unsigned int i = 0; i < initialParameters.size(); i++) outputCSVfile << initialParameters[i] << "\n"; outputCSVfile.close(); } } return EXIT_SUCCESS; }