/*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv Authors belong to: - University of LYON http://www.universite-lyon.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 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copyright notices for more information. It is distributed under dual licence - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ #ifndef clitkImageStatisticsGenericFilter_txx #define clitkImageStatisticsGenericFilter_txx #include "itkNthElementImageAdaptor.h" #include "itkJoinSeriesImageFilter.h" #include "itkImageRegionConstIterator.h" #include "clitkImageStatisticsGenericFilter.h" #include "clitkCropLikeImageFilter.h" #include "clitkResampleImageWithOptionsFilter.h" namespace clitk { //------------------------------------------------------------------- // Update with the number of dimensions //------------------------------------------------------------------- template void ImageStatisticsGenericFilter::UpdateWithDim(std::string PixelType) { if (m_Verbose) std::cout << "Image was detected to be "<(); } else if(PixelType == "unsigned_short"){ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; UpdateWithDimAndPixelType(); } else if (PixelType == "unsigned_char"){ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; UpdateWithDimAndPixelType(); } else if(PixelType == "double"){ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl; UpdateWithDimAndPixelType(); } else { if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; UpdateWithDimAndPixelType(); } } //------------------------------------------------------------------- // Update with the number of dimensions and the pixeltype //------------------------------------------------------------------- template void ImageStatisticsGenericFilter::UpdateWithDimAndPixelType() { // ImageTypes typedef unsigned char LabelPixelType; typedef itk::Image, Dimension> InputImageType; typedef itk::Image LabelImageType; // Read the input typedef itk::ImageFileReader InputReaderType; typename InputReaderType::Pointer reader = InputReaderType::New(); reader->SetFileName( m_InputFileName); reader->Update(); typename InputImageType::Pointer input= reader->GetOutput(); typedef itk::NthElementImageAdaptor InputImageAdaptorType; typedef itk::Image OutputImageType; typename InputImageAdaptorType::Pointer input_adaptor = InputImageAdaptorType::New(); input_adaptor->SetImage(input); // Filter typedef itk::LabelStatisticsImageFilter StatisticsImageFilterType; typename StatisticsImageFilterType::Pointer statisticsFilter=StatisticsImageFilterType::New(); statisticsFilter->SetInput(input_adaptor); // Label image typename LabelImageType::Pointer labelImage; if (m_ArgsInfo.mask_given) { int maskDimension, maskComponents; std::string maskPixelType; ReadImageDimensionAndPixelType(m_ArgsInfo.mask_arg, maskDimension, maskPixelType, maskComponents); if (maskDimension == Dimension - 1) { // Due to a limitation of filter itk::LabelStatisticsImageFilter, InputImageType and LabelImageType // must have the same image dimension. However, we want to support label images with Dl = Di - 1, // so we need to replicate the label image as many times as the size along dimension Di. if (m_Verbose) std::cout << "Replicating label image to match input image's dimension... " << std::endl; typedef itk::Image ReducedLabelImageType; typedef itk::ImageFileReader LabelImageReaderType; typedef itk::JoinSeriesImageFilter JoinImageFilterType; typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New(); labelImageReader->SetFileName(m_ArgsInfo.mask_arg); labelImageReader->Update(); typename JoinImageFilterType::Pointer joinFilter = JoinImageFilterType::New(); typename InputImageType::SizeType size = input->GetLargestPossibleRegion().GetSize(); for (unsigned int i = 0; i < size[Dimension - 1]; i++) joinFilter->PushBackInput(labelImageReader->GetOutput()); joinFilter->Update(); labelImage = joinFilter->GetOutput(); } else { typedef itk::ImageFileReader LabelImageReaderType; typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New(); labelImageReader->SetFileName(m_ArgsInfo.mask_arg); labelImageReader->Update(); labelImage= labelImageReader->GetOutput(); // Check mask sampling/size if (!HaveSameSizeAndSpacing(labelImage, input)) { if (m_ArgsInfo.allow_resize_flag) { if (m_ArgsInfo.verbose_flag) { std::cout << "Resize mask image like input" << std::endl; } typedef clitk::ResampleImageWithOptionsFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); resampler->SetInput(labelImage); resampler->SetOutputSpacing(input->GetSpacing()); resampler->SetOutputOrigin(labelImage->GetOrigin()); resampler->SetGaussianFilteringEnabled(false); resampler->Update(); labelImage = resampler->GetOutput(); //writeImage(labelImage, "test1.mha"); typedef clitk::CropLikeImageFilter FilterType; typename FilterType::Pointer crop = FilterType::New(); crop->SetInput(labelImage); crop->SetCropLikeImage(input); crop->Update(); labelImage = crop->GetOutput(); //writeImage(labelImage, "test2.mha"); } else { std::cerr << "Mask image has a different size/spacing than input. Abort. (Use option to resize)" << std::endl; exit(-1); } } } } else { labelImage=LabelImageType::New(); labelImage->SetDirection(input->GetDirection()); labelImage->SetRegions(input->GetLargestPossibleRegion()); labelImage->SetOrigin(input->GetOrigin()); labelImage->SetSpacing(input->GetSpacing()); labelImage->SetDirection(input->GetDirection()); labelImage->Allocate(); labelImage->FillBuffer(m_ArgsInfo.label_arg[0]); } statisticsFilter->SetLabelInput(labelImage); // Check/compute spacing const typename LabelImageType::SpacingType& spacing = input->GetSpacing(); double spacing_cc = (spacing[0]*spacing[1]*spacing[2])/1000; // std::cout<<"Spacing x : " << spacing[0]<SelectNthElement(c); input_adaptor->Update(); for (unsigned int k=0; k< numberOfLabels; k++) { label=m_ArgsInfo.label_arg[k]; std::cout<SetUseHistograms(true); statisticsFilter->SetHistogramParameters(m_ArgsInfo.bins_arg, m_ArgsInfo.lower_arg, m_ArgsInfo.upper_arg); } // DVH if(m_ArgsInfo.dvhistogram_given) { statisticsFilter->SetUseHistograms(true); statisticsFilter->SetHistogramParameters(m_ArgsInfo.bins_arg, m_ArgsInfo.lower_arg, m_ArgsInfo.upper_arg); } statisticsFilter->Update(); //find localization for max and min (the last pixel found) typename InputImageType::IndexType minIndex, maxIndex; if (m_Verbose && m_Localize) { itk::ImageRegionConstIterator imageIterator(input_adaptor,input_adaptor->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { if (imageIterator.Get() == statisticsFilter->GetMinimum(label)) minIndex = imageIterator.GetIndex(); if (imageIterator.Get() == statisticsFilter->GetMaximum(label)) maxIndex = imageIterator.GetIndex(); ++imageIterator; } } // Output if (m_Verbose) std::cout<<"N° of pixels: "; std::cout<GetCount(label)<GetMean(label)<GetSigma(label)<GetVariance(label)<GetMinimum(label)<GetMaximum(label)<GetSum(label)<GetCount(label)*spacing_cc<GetBoundingBox(label).size(); i++) std::cout<GetBoundingBox(label)[i]<<" "; std::cout<GetMedian(label)<GetHistogram(label); // Screen if (m_Verbose) std::cout<<"Histogram: "<GetBinMin(0,i)<<"\t"<GetMeasurement(i,0)<<"\t"<GetBinMax(0,i)<<"\t"<GetFrequency(i)<GetBinMin(0,i)<<"\t"<GetMeasurement(i,0)<<"\t"<GetBinMax(0,i)<<"\t"<GetFrequency(i)<GetHistogram(label); double totalVolumeCC = ((statisticsFilter->GetCount(label))*spacing_cc); double totalVolume = statisticsFilter->GetCount(label); // Screen std::cout<<"# Total volume : "; std::cout<GetMean(label)<<" [Gy]"<GetMinimum(label)<<" [Gy]"<GetMaximum(label)<<" [Gy]"<GetFrequency(j)); } double cumulativeVolume = (totalVolume - (popCumulativeVolume + (dvhistogram->GetFrequency(i)))); double percentCumulativeVolume =(cumulativeVolume*100)/(statisticsFilter->GetCount(label)) ; double ccCumulativeVolume = (totalVolumeCC -((popCumulativeVolume + (dvhistogram->GetFrequency(i)))*spacing_cc)); double percentDiffVolume = dvhistogram->GetFrequency(i)*100/(statisticsFilter->GetCount(label)); std::cout<GetBinMax(0,i)<<"\t "<GetFrequency(i)<<"\t "<GetFrequency(i))*spacing_cc)<<"\t "<<"\t "<GetCount(label)<<" [No. of voxels]"<GetMean(label)<<" [Gy]"<GetMinimum(label)<<" [Gy]"<GetMaximum(label)<<" [Gy]"<GetFrequency(j)); } double cumulativeVolume = (totalVolume - (popCumulativeVolume + (dvhistogram->GetFrequency(i)))); double percentCumulativeVolume =(cumulativeVolume*100)/(statisticsFilter->GetCount(label)); double ccCumulativeVolume = (totalVolumeCC -((popCumulativeVolume + (dvhistogram->GetFrequency(i)))*spacing_cc)); double percentDiffVolume = ((dvhistogram->GetFrequency(i))*100)/(statisticsFilter->GetCount(label)); dvhistogramFile<GetBinMax(0,i)<<"\t "<GetFrequency(i)<<"\t "<GetFrequency(i))*spacing_cc)<<"\t "<