X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=registration%2FclitkCalculateTREGenericFilter.txx;h=7d161377f2fd0bf37751354e36e995ee0ef9dfbf;hb=573d80d0f7a17607d2ee883c21c940c0ba020282;hp=1198ac83cae18e6e835dfc20fe7c14e3f1fbb839;hpb=657652a78c2e2717a6f77e027049173442ca29f0;p=clitk.git diff --git a/registration/clitkCalculateTREGenericFilter.txx b/registration/clitkCalculateTREGenericFilter.txx index 1198ac8..7d16137 100755 --- a/registration/clitkCalculateTREGenericFilter.txx +++ b/registration/clitkCalculateTREGenericFilter.txx @@ -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,10 +14,14 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html -======================================================================-====*/ +===========================================================================**/ #ifndef clitkCalculateTREGenericFilter_txx #define clitkCalculateTREGenericFilter_txx + +#include "clitkBSplineDeformableTransform.h" + + /* ================================================= * @file clitkCalculateTREGenericFilter.txx * @author @@ -28,6 +32,495 @@ ===================================================*/ +//===================================================================================== +// Macros +// Rômulo Pinho - 25/02/2011 +// The macros below avoid the duplication of code after introducing the function +// UpdateCoeffsWithDim(). Although the code generated by these functions will be +// duplicated anyway (since they're template functions) the macros make their sources +// more intelligible. +// Ideally, these macros should be made member functions, with the typedefs inside the +// the filter class, but that would change the class' interface, since it would need +// to become a template class (with parameter Dimension). To avoid breaking legacy code, +// I opted for the macros, although I don't quite like them (especially long ones like +// these). In any case, it's advisable to think of a better solution, even if it breaks +// the class' interface. +//===================================================================================== + +//----------------------------- +// Typedefs +//----------------------------- +#define TypedefsMacro \ +\ + typedef itk::Point PointType; \ + typedef clitk::List PointListType; \ + typedef clitk::Lists PointListsType; \ +\ + typedef itk::Vector VectorType; \ + typedef clitk::List VectorListType; \ + typedef clitk::Lists VectorListsType; \ +\ + typedef itk::Vector DeformationVectorType; \ + typedef itk::Image DeformationFieldType; + +//------------------------------------------------------------------- +// Build the point lists necessary for the computation of distances. +//------------------------------------------------------------------- +#define BuildPointListsMacro(filenames) \ +\ + m_NumberOfFields=filenames.size(); \ + m_NumberOfLists=m_ArgsInfo.input_given; \ + if ( (m_NumberOfLists!=m_NumberOfFields) && (m_NumberOfLists!=1) ) \ + { \ + std::cerr<<"Error: Number of lists (="< StatisticsFilterType; \ + typename StatisticsFilterType::Pointer statisticsFilter=StatisticsFilterType::New(); \ +\ + /* // Statistics (magnitude) */ \ + MeasureListType oMeanList, oStdList, oMaxList; \ + ValueType oMean, oStd, oMax; \ + statisticsFilter->GetStatistics(originalDistanceLists, oMean, oStd, oMax, oMeanList, oStdList, oMaxList); \ +\ + /* // Statistics (per component) */\ + VectorListType oMeanXYZList, oStdXYZList,oMaxXYZList; \ + VectorType oMeanXYZ, oStdXYZ, oMaxXYZ; \ + statisticsFilter->GetStatistics(originalDistanceLists, oMeanXYZ, oStdXYZ, oMaxXYZ, oMeanXYZList, oStdXYZList, oMaxXYZList); \ +\ +\ + /* //----------------------------- */\ + /* // Output */\ + /* //----------------------------- */\ + std::vector labels; \ + labels.push_back("MeanX\tSDX"); \ + labels.push_back("MeanY\tSDY"); \ + labels.push_back("MeanZ\tSDZ"); \ + labels.push_back("MeanT\tSDT"); \ + labels.push_back("MaxX"); \ + labels.push_back("MaxY"); \ + labels.push_back("MaxZ"); \ + labels.push_back("MaxT"); \ +\ +\ + /* // Output to screen */\ + if(m_Verbose) \ + { \ +\ + /* // Numbers of DVF */\ + std::cout<<"# Number\tDVF"<GetStatistics(displacementLists, dmean, dstd, dmax, dmeanList, dstdList, dmaxList); \ +\ + /* // Statistics (per component) */\ + VectorListType dmeanXYZList, dstdXYZList,dmaxXYZList; \ + VectorType dmeanXYZ, dstdXYZ, dmaxXYZ; \ + statisticsFilter->GetStatistics(displacementLists, dmeanXYZ, dstdXYZ, dmaxXYZ,dmeanXYZList, dstdXYZList, dmaxXYZList); \ +\ +\ + /* //----------------------------- */\ + /* // Statistics TRE */\ + /* //----------------------------- */\ +\ + /* // Statistics (magnitude) */\ + MeasureListType meanList, stdList, maxList; \ + ValueType mean, std, max; \ + statisticsFilter->GetStatistics(treLists, mean, std, max, meanList, stdList, maxList); \ +\ + /* // Statistics (per component) */\ + VectorListType meanXYZList, stdXYZList,maxXYZList; \ + VectorType meanXYZ, stdXYZ, maxXYZ; \ + statisticsFilter->GetStatistics(treLists, meanXYZ, stdXYZ, maxXYZ, meanXYZList, stdXYZList, maxXYZList); \ +\ +\ + /* // Output to screen */\ + if(m_Verbose) \ + { \ +\ + std::cout< filenames; \ + for (unsigned int i=0;i > originalDistanceListsMag=originalDistanceLists.Norm(); \ + std::vector filenames; \ + for (unsigned int i=0;i filenames; \ + for (unsigned int i=0;i > displacementListsMag=displacementLists.Norm(); \ + std::vector filenames; \ + for (unsigned int i=0;i filenames; \ + for (unsigned int i=0;i filenames; \ + for (unsigned int i=0;i > treMagLists=treLists.Norm(); \ +\ + std::vector filenames; \ + for (unsigned int i=0;i VectorType; + // if using dvfs + typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; - typedef itk::ImageFileReader InputReaderType; + typedef itk::ImageFileReader DvfReaderType; std::vector dvfs; + for (unsigned int i=0; i< m_ArgsInfo.vf_given; i++) { - typename InputReaderType::Pointer reader = InputReaderType::New(); - reader->SetFileName( m_ArgsInfo.vf_arg[i]); - if (m_Verbose) std::cout<<"Reading vector field "<< i <<"..."<Update(); - dvfs.push_back( reader->GetOutput() ); + typename DvfReaderType::Pointer reader = DvfReaderType::New(); + reader->SetFileName( m_ArgsInfo.vf_arg[i]); + if (m_Verbose) std::cout<<"Reading vector field "<< i <<"..."<Update(); + dvfs.push_back( reader->GetOutput() ); } - + ProcessVectorFields(dvfs, m_ArgsInfo.vf_arg); + } //----------------------------- @@ -61,279 +556,84 @@ namespace clitk //----------------------------- template void - CalculateTREGenericFilter::ProcessVectorFields(std::vector, Dimension>::Pointer > dvfs, char** filenames ) + CalculateTREGenericFilter::ProcessVectorFields(std::vector, Dimension>::Pointer > dvfs, char** filenames ) { - std::vector new_filenames; for (unsigned int i=0;i(dvfs, new_filenames); + UpdateDVFWithDim(dvfs, new_filenames); } - //------------------------------------------------------------------- - // Update with the number of dimensions - //------------------------------------------------------------------- - template + //----------------------------- + // Read Coefficient Images + //----------------------------- + template void - CalculateTREGenericFilter::UpdateWithDim(std::vector, Dimension>::Pointer > dvfs, std::vector filenames) + CalculateTREGenericFilter::ReadCoefficientImages(void) { - if (m_Verbose) std::cout << "Image was detected to be "< MeasureListType; - - typedef itk::Point PointType; - typedef clitk::List PointListType; - typedef clitk::Lists PointListsType; - - typedef itk::Vector VectorType; - typedef clitk::List VectorListType; - typedef clitk::Lists VectorListsType; + // if using coefficient images + typedef itk::Vector VectorType; + typedef itk::Image CoefficientImageType; - typedef itk::Vector DeformationVectorType; - typedef itk::Image DeformationFieldType; + typedef itk::ImageFileReader CoeffReaderType; + std::vector coeffs; - //----------------------------- - // Number of inputs - //----------------------------- - unsigned int numberOfFields=filenames.size(); - unsigned int numberOfLists=m_ArgsInfo.input_given; - if ( (numberOfLists!=numberOfFields) && (numberOfLists!=1) ) - { - std::cerr<<"Error: Number of lists (="<SetFileName( m_ArgsInfo.coeff_arg[i]); + if (m_Verbose) std::cout<<"Reading coefficient image "<< i <<"..."<Update(); + coeffs.push_back( reader->GetOutput() ); } + + ProcessCoefficientImages(coeffs, m_ArgsInfo.coeff_arg); + } - - //----------------------------- - // Input point lists - //----------------------------- - PointListsType pointLists; - unsigned int numberOfPoints=0; - for (unsigned int i=0; i + void + CalculateTREGenericFilter::ProcessCoefficientImages(std::vector, Dimension>::Pointer > coeffs, char** filenames ) + { + std::vector new_filenames; + for (unsigned int i=0;i(coeffs, new_filenames); + } + - // Verify the number of points - if (i==0) numberOfPoints=pointLists[i].size(); - else - { - if (numberOfPoints!=pointLists[i].size()) - { - std::cerr<<"Size of first list ("< + void + CalculateTREGenericFilter::UpdateDVFWithDim(std::vector, Dimension>::Pointer > dvfs, std::vector filenames) + { + if (m_Verbose) std::cout << "Image was detected to be "< GenericVectorInterpolatorType; + typedef clitk::GenericVectorInterpolator GenericVectorInterpolatorType; typename GenericVectorInterpolatorType::Pointer genericInterpolator=GenericVectorInterpolatorType::New(); genericInterpolator->SetArgsInfo(m_ArgsInfo); - typedef itk::VectorInterpolateImageFunction InterpolatorType; + typedef itk::VectorInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator=genericInterpolator->GetInterpolatorPointer(); - //===================================================================================== - // Original distance between points - //===================================================================================== - VectorListsType originalDistanceLists(numberOfFields); - - //----------------------------- - // Calculate original distances - //----------------------------- - PointType referencePoint; - VectorType distance; - for (unsigned int phaseIndex=0; phaseIndex StatisticsFilterType; - typename StatisticsFilterType::Pointer statisticsFilter=StatisticsFilterType::New(); - - // Statistics (magnitude) - MeasureListType oMeanList, oStdList, oMaxList; - ValueType oMean, oStd, oMax; - statisticsFilter->GetStatistics(originalDistanceLists, oMean, oStd, oMax, oMeanList, oStdList, oMaxList); - - // Statistics (per component) - VectorListType oMeanXYZList, oStdXYZList,oMaxXYZList; - VectorType oMeanXYZ, oStdXYZ, oMaxXYZ; - statisticsFilter->GetStatistics(originalDistanceLists, oMeanXYZ, oStdXYZ, oMaxXYZ, oMeanXYZList, oStdXYZList, oMaxXYZList); - - - //----------------------------- - // Output - //----------------------------- - std::vector labels; - labels.push_back("MeanX\tSDX"); - labels.push_back("MeanY\tSDY"); - labels.push_back("MeanZ\tSDZ"); - labels.push_back("MeanT\tSDT"); - labels.push_back("MaxX"); - labels.push_back("MaxY"); - labels.push_back("MaxZ"); - labels.push_back("MaxT"); - - - // Output to screen - if(m_Verbose) - { - - // Numbers of DVF - std::cout<<"# Number\tDVF"<SetInputImage( dvfs[phaseIndex]); - for (unsigned int pointIndex=0; pointIndexSetInputImage( dvfs[phaseIndex] ); + for (unsigned int pointIndex=0; pointIndex + void + CalculateTREGenericFilter::UpdateCoeffsWithDim(std::vector, Dimension>::Pointer > coeffs, std::vector filenames) + { + // call macros + TypedefsMacro; + BuildPointListsMacro(filenames); + OriginalDistancesMacro; + + //===================================================================================== + // Distance between points after warp + //===================================================================================== + //----------------------------- - // Statistics displacements + // Transform to get the transformed points from the coeff images //----------------------------- + typedef clitk::BSplineDeformableTransform TransformType; + typename TransformType::Pointer transform = TransformType::New(); + + PointListsType warpedPointLists(m_NumberOfFields); + VectorListsType treLists(m_NumberOfFields), displacementLists(m_NumberOfFields); - // Statistics (magnitude) - MeasureListType dmeanList, dstdList, dmaxList; - ValueType dmean, dstd, dmax; - statisticsFilter->GetStatistics(displacementLists, dmean, dstd, dmax, dmeanList, dstdList, dmaxList); - - // Statistics (per component) - VectorListType dmeanXYZList, dstdXYZList,dmaxXYZList; - VectorType dmeanXYZ, dstdXYZ, dmaxXYZ; - statisticsFilter->GetStatistics(displacementLists, dmeanXYZ, dstdXYZ, dmaxXYZ,dmeanXYZList, dstdXYZList, dmaxXYZList); - - //----------------------------- - // Statistics TRE + // Calculate residual distances //----------------------------- - - // Statistics (magnitude) - MeasureListType meanList, stdList, maxList; - ValueType mean, std, max; - statisticsFilter->GetStatistics(treLists, mean, std, max, meanList, stdList, maxList); - - // Statistics (per component) - VectorListType meanXYZList, stdXYZList,maxXYZList; - VectorType meanXYZ, stdXYZ, maxXYZ; - statisticsFilter->GetStatistics(treLists, meanXYZ, stdXYZ, maxXYZ, meanXYZList, stdXYZList, maxXYZList); - - - // Output to screen - if(m_Verbose) - { - - std::cout< filenames; - for (unsigned int i=0;i > originalDistanceListsMag=originalDistanceLists.Norm(); - std::vector filenames; - for (unsigned int i=0;i filenames; - for (unsigned int i=0;i > displacementListsMag=displacementLists.Norm(); - std::vector filenames; - for (unsigned int i=0;i filenames; - for (unsigned int i=0;i filenames; - for (unsigned int i=0;iSetCoefficientImage(coeffs[phaseIndex]); + + // transform the input points + for (unsigned int pointIndex=0; pointIndexTransformPoint(referencePoint); + + // Warp + displacement=warpedPoint-referencePoint; + displacementLists[phaseIndex].push_back(displacement); + warpedPointLists[phaseIndex].push_back(warpedPoint); + tre=pointLists[phaseIndex][pointIndex]-warpedPoint; + treLists[phaseIndex].push_back(tre); + } } - // Output tre mag - if( m_ArgsInfo.treMag_given) - { - clitk::Lists > treMagLists=treLists.Norm(); - - std::vector filenames; - for (unsigned int i=0;i