/*========================================================================= 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 clitkCalculateTREGenericFilter_txx #define clitkCalculateTREGenericFilter_txx #include "clitkBSplineDeformableTransform.h" /* ================================================= * @file clitkCalculateTREGenericFilter.txx * @author * @date * * @brief * ===================================================*/ //===================================================================================== // 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 void CalculateTREGenericFilter::ReadVectorFields(void) { // if using dvfs typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::ImageFileReader DvfReaderType; std::vector dvfs; for (unsigned int i=0; i< m_ArgsInfo.vf_given; i++) { 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); } //----------------------------- // Process DVF //----------------------------- template void CalculateTREGenericFilter::ProcessVectorFields(std::vector, Dimension>::Pointer > dvfs, char** filenames ) { std::vector new_filenames; for (unsigned int i=0;i(dvfs, new_filenames); } //----------------------------- // Read Coefficient Images //----------------------------- template void CalculateTREGenericFilter::ReadCoefficientImages(void) { // if using coefficient images typedef itk::Vector VectorType; typedef itk::Image CoefficientImageType; typedef itk::ImageFileReader CoeffReaderType; std::vector coeffs; for (unsigned int i=0; i< m_ArgsInfo.coeff_given; i++) { typename CoeffReaderType::Pointer reader = CoeffReaderType::New(); reader->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); } //----------------------------- // Process Coefficient Images //----------------------------- template void CalculateTREGenericFilter::ProcessCoefficientImages(std::vector, Dimension>::Pointer > coeffs, char** filenames ) { std::vector new_filenames; for (unsigned int i=0;i(coeffs, new_filenames); } //------------------------------------------------------------------- // Update DVF with the number of dimensions //------------------------------------------------------------------- template void CalculateTREGenericFilter::UpdateDVFWithDim(std::vector, Dimension>::Pointer > dvfs, std::vector filenames) { if (m_Verbose) std::cout << "Image was detected to be "< GenericVectorInterpolatorType; typename GenericVectorInterpolatorType::Pointer genericInterpolator=GenericVectorInterpolatorType::New(); genericInterpolator->SetArgsInfo(m_ArgsInfo); typedef itk::VectorInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator=genericInterpolator->GetInterpolatorPointer(); PointListsType warpedPointLists(m_NumberOfFields); VectorListsType treLists(m_NumberOfFields), displacementLists(m_NumberOfFields); //----------------------------- // Calculate residual distances //----------------------------- VectorType displacement, tre; PointType warpedPoint; for (unsigned int phaseIndex=0; phaseIndexSetInputImage( dvfs[phaseIndex] ); for (unsigned int pointIndex=0; pointIndexIsInsideBuffer(referencePoint) ) displacement=interpolator->Evaluate(referencePoint); else displacement.Fill(0.0); // Warp warpedPoint=referencePoint+displacement; displacementLists[phaseIndex].push_back(displacement); warpedPointLists[phaseIndex].push_back(warpedPoint); tre=pointLists[phaseIndex][pointIndex]-warpedPoint; treLists[phaseIndex].push_back(tre); } } StatisticsDisplacementsMacro; } //------------------------------------------------------------------- // Update coefficients with the number of dimensions //------------------------------------------------------------------- template void CalculateTREGenericFilter::UpdateCoeffsWithDim(std::vector, Dimension>::Pointer > coeffs, std::vector filenames) { // call macros TypedefsMacro; BuildPointListsMacro(filenames); OriginalDistancesMacro; //===================================================================================== // Distance between points after warp //===================================================================================== //----------------------------- // 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); //----------------------------- // Calculate residual distances //----------------------------- VectorType displacement, tre; PointType warpedPoint; for (unsigned int phaseIndex=0; phaseIndexSetCoefficientImage(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); } } StatisticsDisplacementsMacro; } }//end clitk #endif //#define clitkCalculateTREGenericFilter_txx