X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=tools%2FclitkBinarizeImageGenericFilter.cxx;h=f94cf1a09206c0404fc2ba004a2195638b9b1cec;hb=543b72e23ad001ac2a7743b9beacf48e2d0054ac;hp=6e5a5f4c409a210e96ce3826ee39bd711c720d2d;hpb=15784e384cd2d74c0ffa4ed54e1d4c0ecfb2a1bd;p=clitk.git diff --git a/tools/clitkBinarizeImageGenericFilter.cxx b/tools/clitkBinarizeImageGenericFilter.cxx index 6e5a5f4..f94cf1a 100644 --- a/tools/clitkBinarizeImageGenericFilter.cxx +++ b/tools/clitkBinarizeImageGenericFilter.cxx @@ -3,7 +3,7 @@ Authors belong to: - University of LYON http://www.universite-lyon.fr/ - - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr This software is distributed WITHOUT ANY WARRANTY; without even @@ -14,7 +14,7 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html -======================================================================-====*/ +===========================================================================**/ #ifndef clitkBinarizeImageGenericFilter_cxx #define clitkBinarizeImageGenericFilter_cxx @@ -29,4 +29,229 @@ #include "clitkBinarizeImageGenericFilter.h" +// itk include +#include "itkBinaryThresholdImageFilter.h" +#include "itkMaskImageFilter.h" +#include "itkMaskNegatedImageFilter.h" + +#include + +namespace clitk +{ + +//-------------------------------------------------------------------- +BinarizeImageGenericFilter::BinarizeImageGenericFilter(): + ImageToImageGenericFilter("BinarizeImage") +{ + InitializeImageType<2>(); + InitializeImageType<3>(); + InitializeImageType<4>(); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void BinarizeImageGenericFilter::InitializeImageType() +{ + ADD_DEFAULT_IMAGE_TYPES(Dim); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void BinarizeImageGenericFilter::SetArgsInfo(const args_info_type & a) +{ + mArgsInfo=a; + if (mArgsInfo.verbose_given) + SetIOVerbose(mArgsInfo.verbose_flag); + if (mArgsInfo.imagetypes_given && mArgsInfo.imagetypes_flag) + this->PrintAvailableImageTypes(); + + if (mArgsInfo.input_given) { + SetInputFilename(mArgsInfo.input_arg); + } + if (mArgsInfo.output_given) { + SetOutputFilename(mArgsInfo.output_arg); + } + if (mArgsInfo.percentage_given) { + SetPercentage(mArgsInfo.percentage_arg); + } +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype +//-------------------------------------------------------------------- +template +void +BinarizeImageGenericFilter::UpdateWithInputImageType() +{ + if (mArgsInfo.percentage_given) + MaskOfIntegratedIntensity(); + else { + // Reading input + typename InputImageType::Pointer input = this->template GetInput(0); + + // Main filter + typedef typename InputImageType::PixelType PixelType; + typedef itk::Image OutputImageType; + + // Filter + typedef itk::BinaryThresholdImageFilter BinaryThresholdImageFilterType; + typename BinaryThresholdImageFilterType::Pointer thresholdFilter=BinaryThresholdImageFilterType::New(); + thresholdFilter->SetInput(input); + thresholdFilter->SetInsideValue(mArgsInfo.fg_arg); + + if (mArgsInfo.lower_given) thresholdFilter->SetLowerThreshold(static_cast(mArgsInfo.lower_arg)); + if (mArgsInfo.upper_given) thresholdFilter->SetUpperThreshold(static_cast(mArgsInfo.upper_arg)); + + /* Three modes : + - FG -> only use FG value for pixel in the Foreground (or Inside), keep input values for outside + - BG -> only use BG value for pixel in the Background (or Outside), keep input values for inside + - both -> use FG and BG (real binary image) + */ + if (mArgsInfo.mode_arg == std::string("both")) { + thresholdFilter->SetOutsideValue(mArgsInfo.bg_arg); + thresholdFilter->Update(); + typename OutputImageType::Pointer outputImage = thresholdFilter->GetOutput(); + this->template SetNextOutput(outputImage); + } else { + typename InputImageType::Pointer outputImage; + thresholdFilter->SetOutsideValue(0); + if (mArgsInfo.mode_arg == std::string("BG")) { + typedef itk::MaskImageFilter maskFilterType; + typename maskFilterType::Pointer maskFilter = maskFilterType::New(); + maskFilter->SetInput1(input); + maskFilter->SetInput2(thresholdFilter->GetOutput()); + maskFilter->SetOutsideValue(mArgsInfo.bg_arg); + maskFilter->Update(); + outputImage = maskFilter->GetOutput(); + } else { + typedef itk::MaskNegatedImageFilter maskFilterType; + typename maskFilterType::Pointer maskFilter = maskFilterType::New(); + maskFilter->SetInput1(input); + maskFilter->SetInput2(thresholdFilter->GetOutput()); + maskFilter->SetOutsideValue(mArgsInfo.fg_arg); + maskFilter->Update(); + outputImage = maskFilter->GetOutput(); + } + // Write/Save results + this->template SetNextOutput(outputImage); + } + } +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +// https://stackoverflow.com/questions/1577475/c-sorting-and-keeping-track-of-indexes +template +std::vector sort_indexes(const std::vector &v) { + + // initialize original index locations + std::vector idx(v.size()); + std::vector > compVector(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + compVector[i].first = v[i]; + compVector[i].second = i; + } + + // sort indexes based on comparing values in v + std::sort(compVector.begin(), compVector.end(), comparator); + for (size_t i = 0; i < v.size(); ++i) { + idx[i] = compVector[i].second; + } + + return idx; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype +//-------------------------------------------------------------------- +template +void +BinarizeImageGenericFilter::MaskOfIntegratedIntensity() +{ + // Main filter + typedef typename InputImageType::PixelType InputPixelType; + typedef itk::Image MaskImageType; + + // Reading input + typename InputImageType::Pointer input = this->template GetInput(0); + + typename MaskImageType::Pointer mask; + mask = MaskImageType::New(); + mask->SetRegions(input->GetLargestPossibleRegion()); + mask->SetOrigin(input->GetOrigin()); + mask->SetSpacing(input->GetSpacing()); + mask->Allocate(); + mask->FillBuffer(0); + + // Get a vector of all values (will be easier to sort) + // And compute total sum of values + std::vector values; + typedef itk::ImageRegionIterator IteratorInputType; + IteratorInputType iter(input, input->GetLargestPossibleRegion()); + iter.GoToBegin(); + double total = 0.0; + while (!iter.IsAtEnd()) { + values.push_back(iter.Get()); + total += iter.Get(); + ++iter; + } + + // Sort (reverse) + std::vector indices = sort_indexes(values); + + // Get max index of pixel to reach xx percent + double current = 0.0; + double max = GetPercentage()/100.0*total; + int i=0; + int n = input->GetLargestPossibleRegion().GetNumberOfPixels(); + std::vector should_keep(values.size());; + std::fill(should_keep.begin(), should_keep.end(), 0); + while (current IteratorMaskType; + IteratorMaskType itm(mask, mask->GetLargestPossibleRegion()); + iter.GoToBegin(); + itm.GoToBegin(); + i = 0; + while (!iter.IsAtEnd()) { + if (should_keep[i]) itm.Set(1); + ++iter; + ++itm; + ++i; + } + + // Verbose option + if (this->m_IOVerbose) + std::cout << "Sum of pixel values : " << total << std::endl + << "Percentage : " << GetPercentage() << "%" << std::endl + << "Number of pixels : " << nb << "/" << n << std::endl + << "Number of pixels : " << nb/n*100.0 << "%" << std::endl; + + // Write/Save results + this->template SetNextOutput(mask); +} +//-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +template +bool comparator ( const std::pair& l, const std::pair& r) + { return l.first > r.first; } +//-------------------------------------------------------------------- + +}//end clitk + #endif //#define clitkBinarizeImageGenericFilter_cxx