1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef clitkImageStatisticsGenericFilter_txx
19 #define clitkImageStatisticsGenericFilter_txx
21 #include "itkNthElementImageAdaptor.h"
22 #include "itkJoinSeriesImageFilter.h"
24 #include "clitkImageStatisticsGenericFilter.h"
25 #include "clitkCropLikeImageFilter.h"
26 #include "clitkResampleImageWithOptionsFilter.h"
31 //-------------------------------------------------------------------
32 // Update with the number of dimensions
33 //-------------------------------------------------------------------
34 template<unsigned int Dimension, unsigned int Components>
36 ImageStatisticsGenericFilter::UpdateWithDim(std::string PixelType)
38 if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<" with " << Components << " channel(s)..."<<std::endl;
40 if(PixelType == "short"){
41 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
42 UpdateWithDimAndPixelType<Dimension, signed short, Components>();
44 else if(PixelType == "unsigned_short"){
45 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
46 UpdateWithDimAndPixelType<Dimension, unsigned short, Components>();
49 else if (PixelType == "unsigned_char"){
50 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
51 UpdateWithDimAndPixelType<Dimension, unsigned char, Components>();
54 // else if (PixelType == "unsigned_int"){
55 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_int..." << std::endl;
56 // UpdateWithDimAndPixelType<Dimension, unsigned int, Components>();
58 // else if (PixelType == "char"){
59 // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
60 // UpdateWithDimAndPixelType<Dimension, signed char>();
62 else if(PixelType == "double"){
63 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
64 UpdateWithDimAndPixelType<Dimension, double, Components>();
67 if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
68 UpdateWithDimAndPixelType<Dimension, float, Components>();
73 //-------------------------------------------------------------------
74 // Update with the number of dimensions and the pixeltype
75 //-------------------------------------------------------------------
76 template <unsigned int Dimension, class PixelType, unsigned int Components>
78 ImageStatisticsGenericFilter::UpdateWithDimAndPixelType()
82 typedef unsigned char LabelPixelType;
83 typedef itk::Image<itk::Vector<PixelType, Components>, Dimension> InputImageType;
84 typedef itk::Image<LabelPixelType, Dimension> LabelImageType;
87 typedef itk::ImageFileReader<InputImageType> InputReaderType;
88 typename InputReaderType::Pointer reader = InputReaderType::New();
89 reader->SetFileName( m_InputFileName);
91 typename InputImageType::Pointer input= reader->GetOutput();
93 typedef itk::NthElementImageAdaptor<InputImageType, PixelType> InputImageAdaptorType;
94 typedef itk::Image<PixelType, Dimension> OutputImageType;
96 typename InputImageAdaptorType::Pointer input_adaptor = InputImageAdaptorType::New();
97 input_adaptor->SetImage(input);
100 typedef itk::LabelStatisticsImageFilter<InputImageAdaptorType, LabelImageType> StatisticsImageFilterType;
101 typename StatisticsImageFilterType::Pointer statisticsFilter=StatisticsImageFilterType::New();
102 statisticsFilter->SetInput(input_adaptor);
105 typename LabelImageType::Pointer labelImage;
106 if (m_ArgsInfo.mask_given) {
107 int maskDimension, maskComponents;
108 std::string maskPixelType;
109 ReadImageDimensionAndPixelType(m_ArgsInfo.mask_arg, maskDimension, maskPixelType, maskComponents);
111 if (maskDimension == Dimension - 1) {
112 // Due to a limitation of filter itk::LabelStatisticsImageFilter, InputImageType and LabelImageType
113 // must have the same image dimension. However, we want to support label images with Dl = Di - 1,
114 // so we need to replicate the label image as many times as the size along dimension Di.
116 std::cout << "Replicating label image to match input image's dimension... " << std::endl;
118 typedef itk::Image<LabelPixelType, Dimension - 1> ReducedLabelImageType;
119 typedef itk::ImageFileReader<ReducedLabelImageType> LabelImageReaderType;
120 typedef itk::JoinSeriesImageFilter<ReducedLabelImageType, LabelImageType> JoinImageFilterType;
122 typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New();
123 labelImageReader->SetFileName(m_ArgsInfo.mask_arg);
124 labelImageReader->Update();
126 typename JoinImageFilterType::Pointer joinFilter = JoinImageFilterType::New();
127 typename InputImageType::SizeType size = input->GetLargestPossibleRegion().GetSize();
128 for (unsigned int i = 0; i < size[Dimension - 1]; i++)
129 joinFilter->PushBackInput(labelImageReader->GetOutput());
131 joinFilter->Update();
132 labelImage = joinFilter->GetOutput();
135 typedef itk::ImageFileReader<LabelImageType> LabelImageReaderType;
136 typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New();
137 labelImageReader->SetFileName(m_ArgsInfo.mask_arg);
138 labelImageReader->Update();
139 labelImage= labelImageReader->GetOutput();
141 // Check mask sampling/size
142 if (!HaveSameSizeAndSpacing<LabelImageType, InputImageType>(labelImage, input)) {
143 if (m_ArgsInfo.allow_resize_flag) {
144 if (m_ArgsInfo.verbose_flag) {
145 std::cout << "Resize mask image like input" << std::endl;
147 typedef clitk::ResampleImageWithOptionsFilter<LabelImageType> ResamplerType;
148 typename ResamplerType::Pointer resampler = ResamplerType::New();
149 resampler->SetInput(labelImage);
150 resampler->SetOutputSpacing(input->GetSpacing());
152 labelImage = resampler->GetOutput();
154 typename itk::ImageBase<LabelImageType::ImageDimension>::RegionType reg
155 = input->GetLargestPossibleRegion();
156 labelImage = ResizeImageLike<LabelImageType>(labelImage, ®, 0);
159 std::cerr << "Mask image has a different size/spacing than input. Abort" << std::endl;
168 labelImage=LabelImageType::New();
169 labelImage->SetRegions(input->GetLargestPossibleRegion());
170 labelImage->SetOrigin(input->GetOrigin());
171 labelImage->SetSpacing(input->GetSpacing());
172 labelImage->Allocate();
173 labelImage->FillBuffer(m_ArgsInfo.label_arg[0]);
175 statisticsFilter->SetLabelInput(labelImage);
178 typename LabelImageType::PixelType label;
179 unsigned int numberOfLabels;
180 if (m_ArgsInfo.label_given)
181 numberOfLabels=m_ArgsInfo.label_given;
185 unsigned int firstComponent = 0, lastComponent = 0;
186 if (m_ArgsInfo.channel_arg == -1) {
188 lastComponent = Components - 1;
191 firstComponent = m_ArgsInfo.channel_arg;
192 lastComponent = m_ArgsInfo.channel_arg;
195 for (unsigned int c=firstComponent; c<=lastComponent; c++) {
196 if (m_Verbose) std::cout << std::endl << "Processing channel " << c << std::endl;
198 input_adaptor->SelectNthElement(c);
199 input_adaptor->Update();
201 for (unsigned int k=0; k< numberOfLabels; k++) {
202 label=m_ArgsInfo.label_arg[k];
204 std::cout<<std::endl;
205 if (m_Verbose) std::cout<<"-------------"<<std::endl;
206 if (m_Verbose) std::cout<<"| Label: "<<label<<" |"<<std::endl;
207 if (m_Verbose) std::cout<<"-------------"<<std::endl;
210 if (m_ArgsInfo.histogram_given) {
211 statisticsFilter->SetUseHistograms(true);
212 statisticsFilter->SetHistogramParameters(m_ArgsInfo.bins_arg, m_ArgsInfo.lower_arg, m_ArgsInfo.upper_arg);
214 statisticsFilter->Update();
217 if (m_Verbose) std::cout<<"N° of pixels: ";
218 std::cout<<statisticsFilter->GetCount(label)<<std::endl;
220 if (m_Verbose) std::cout<<"Mean: ";
221 std::cout<<statisticsFilter->GetMean(label)<<std::endl;
223 if (m_Verbose) std::cout<<"SD: ";
224 std::cout<<statisticsFilter->GetSigma(label)<<std::endl;
226 if (m_Verbose) std::cout<<"Variance: ";
227 std::cout<<statisticsFilter->GetVariance(label)<<std::endl;
229 if (m_Verbose) std::cout<<"Min: ";
230 std::cout<<statisticsFilter->GetMinimum(label)<<std::endl;
232 if (m_Verbose) std::cout<<"Max: ";
233 std::cout<<statisticsFilter->GetMaximum(label)<<std::endl;
235 if (m_Verbose) std::cout<<"Sum: ";
236 std::cout<<statisticsFilter->GetSum(label)<<std::endl;
238 if (m_Verbose) std::cout<<"Bounding box: ";
240 for(unsigned int i =0; i <statisticsFilter->GetBoundingBox(label).size(); i++)
241 std::cout<<statisticsFilter->GetBoundingBox(label)[i]<<" ";
242 std::cout<<std::endl;
245 if (m_ArgsInfo.histogram_given)
247 if (m_Verbose) std::cout<<"Median: ";
248 std::cout<<statisticsFilter->GetMedian(label)<<std::endl;
250 typename StatisticsImageFilterType::HistogramPointer histogram =statisticsFilter->GetHistogram(label);
253 if (m_Verbose) std::cout<<"Histogram: "<<std::endl;
254 std::cout<<"# MinBin\tMidBin\tMaxBin\tFrequency"<<std::endl;
255 for( int i =0; i <m_ArgsInfo.bins_arg; i++)
256 std::cout<<histogram->GetBinMin(0,i)<<"\t"<<histogram->GetMeasurement(i,0)<<"\t"<<histogram->GetBinMax(0,i)<<"\t"<<histogram->GetFrequency(i)<<std::endl;
259 std::ofstream histogramFile(m_ArgsInfo.histogram_arg);
260 histogramFile<<"#Histogram: "<<std::endl;
261 histogramFile<<"#MinBin\tMidBin\tMaxBin\tFrequency"<<std::endl;
262 for( int i =0; i <m_ArgsInfo.bins_arg; i++)
263 histogramFile<<histogram->GetBinMin(0,i)<<"\t"<<histogram->GetMeasurement(i,0)<<"\t"<<histogram->GetBinMax(0,i)<<"\t"<<histogram->GetFrequency(i)<<std::endl;
275 #endif //#define clitkImageStatisticsGenericFilter_txx