#ifndef _ITKINTERPOLATEIMAGEFUNCTIONWITHLUT_ #define _ITKINTERPOLATEIMAGEFUNCTIONWITHLUT_ /* ========================================================================= @file itkBSplineInterpolateImageFunctionWithLUT.txx @author David Sarrut Copyright (c) * CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. * L�on B�rard cancer center, 28 rue La�nnec, 69373 Lyon cedex 08, France * http://www.creatis.insa-lyon.fr/rio This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. ========================================================================= */ #include "itkCastImageFilter.h" //==================================================================== template BSplineInterpolateImageFunctionWithLUT:: BSplineInterpolateImageFunctionWithLUT():Superclass() { // Set default values for(int i=0; i void BSplineInterpolateImageFunctionWithLUT:: SetLUTSamplingFactor(int s) { for(int i=0; i void BSplineInterpolateImageFunctionWithLUT:: SetOutputSpacing(const SpacingType & s) { for(int i=0; i void BSplineInterpolateImageFunctionWithLUT:: SetSplineOrder(unsigned int SplineOrder) { Superclass::SetSplineOrder(SplineOrder); // Compute support and half size static const int d = TImageType::ImageDimension; for(int l=0; l void BSplineInterpolateImageFunctionWithLUT:: SetSplineOrders(SizeType SplineOrders) { mSplineOrders=SplineOrders; DD(mSplineOrders); // Compute support and half size static const int d = TImageType::ImageDimension; for(int l=0; l void BSplineInterpolateImageFunctionWithLUT:: SetInputImage(const TImageType * inputData) { // Call superclass SetInputImage and return if input is null // clitk::Timer t; // t.Start(); //ds // this->InterpolateImageFunction::SetInputImage(inputData); //============================== if (!mInputIsCoef) { Superclass::SetInputImage(inputData); // t.Stop(); } //============================== else { // If inputData is not float/double, we do not want to set // mInputIsCoef to true, but the compiler goes here ... if (typeid(typename TImageType::PixelType) != typeid(TCoefficientType)) { std::cerr << "Input should be float or double to be set as 'coefficients' with SetInputImageIsCoefficient(true) and should be the same type than TCoefficientType" << std::endl; exit(0); } else { itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension); typedef Image CoefficientImageType; typedef itk::CastImageFilter< TImageType, CoefficientImageType> CastFilterType; typename CastFilterType::Pointer castFilter=CastFilterType::New(); castFilter->SetInput(inputData); castFilter->Update(); this->m_Coefficients=castFilter->GetOutput(); if ( this->m_Coefficients.IsNotNull()) this->m_DataLength = this->m_Coefficients->GetBufferedRegion().GetSize(); } // //JV input should be double or float. To keep it generic: cast to the CoefficientImageType // /** Dimension underlying input image. */ // itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension); // /** Internal Coefficient typedef support */ // DD( ImageDimension); // typedef Image CoefficientImageType; // typedef itk::CastImageFilter< TImageType, CoefficientImageType> CastFilterType; // typename CastFilterType::Pointer castFilter=CastFilterType::New(); // castFilter->SetInput(inputData); // castFilter->Update(); // DS this->InterpolateImageFunction::m_Coefficients = inputData; // //JV cast to the coeff type, don't tell my mother // this->InterpolateImageFunction::SetInputImage(inputData); // this->m_Coefficients=castFilter->GetOutput(); // DS ?????? this->m_Coefficients = inputData; // // //============================== old not generic solution // // this->InterpolateImageFunction::SetInputImage(inputData); // // DS this->InterpolateImageFunction::m_Coefficients = inputData; // // this->m_Coefficients = inputData; // // //============================== // if ( this->m_Coefficients.IsNotNull()) { // this->m_DataLength = this->m_Coefficients->GetBufferedRegion().GetSize(); // } } // t.Stop(); if (!inputData) return; // mCoefficientTimer = t; // Compute Memory offset inside coefficients images (for looping over coefficients) static const int d = TImageType::ImageDimension; mInputMemoryOffset[0] = 1; for(int l=1; lm_Coefficients->GetLargestPossibleRegion().GetSize(l-1); } // Compute mSupportOffset according to input size mSupportOffset.resize(mSupportSize); mSupportIndex.resize(mSupportSize); for(int l=0; l(mSupportIndex[k], mInputMemoryOffset); // next coefficient index if (k != mSupportSize-1) { for(int l=0; l void BSplineInterpolateImageFunctionWithLUT:: UpdatePrecomputedWeights() { // mLUTTimer.Reset(); // mLUTTimer.Start(); mWeightsCalculator.SetSplineOrders(mSplineOrders); mWeightsCalculator.SetSamplingFactors(mSamplingFactors); mWeightsCalculator.ComputeTensorProducts(); mWeightsAreUpToDate = true; //DS // coef = new TCoefficientType[mSupportSize]; // mCorrectedSupportIndex.resize(mSupportSize); // mCorrectedSupportOffset.resize(mSupportSize); // mLUTTimer.Stop(); // mLUTTimer.Print("LUT \t"); } //==================================================================== //==================================================================== template typename BSplineInterpolateImageFunctionWithLUT::IndexType BSplineInterpolateImageFunctionWithLUT:: GetSampleIndexOfPixelPosition(const ContinuousIndexType & x, IndexType & EvaluateIndex) const { /* WARNING : sometimes, a floating number x could not really be represented in memory. In this case, the difference between x and floor(x) can be almost 1 (instead of 0). So we take into account such special case, otherwise it could lead to annoying results. */ // static const TCoefficientType tiny = 1.0e-7; IndexType index; for(int l=0; l *mIntrinsecErrorMax) *mIntrinsecErrorMax = fabs(index[l]-t2); */ // When to close to 1, take the next coefficient for ordd order, but // only change index for odd if (index[l] == (int)mSamplingFactors[l]) { index[l] = 0; if (mSplineOrders[l] & 1) EvaluateIndex[l] = EvaluateIndex[l]+1; } } // The end return index; } //==================================================================== //==================================================================== template typename BSplineInterpolateImageFunctionWithLUT::OutputType BSplineInterpolateImageFunctionWithLUT:: EvaluateAtContinuousIndex(const ContinuousIndexType & x) const { // For shorter coding static const unsigned int d = TImageType::ImageDimension; // Compute the indexe of the first interpolation coefficient in the // coefficient image IndexType EvaluateIndex; long indx; for (unsigned int l=0; lm_SplineOrder / 2; EvaluateIndex[l] = indx; } else { // Use this index calculation for even splineOrder if (mSplineOrders[l] == 0) EvaluateIndex[l] = (long)rint(x[l]); else { indx = (long)vcl_floor((x[l]+ 0.5)) - mSplineOrders[l] / 2; //this->m_SplineOrder / 2; EvaluateIndex[l] = indx; } } } // Compute index of precomputed weights and get pointer to first weights const IndexType weightIndex = GetSampleIndexOfPixelPosition(x, EvaluateIndex); const TCoefficientType * pweights = mWeightsCalculator.GetFirstTensorProduct(weightIndex); // Check boundaries bool mBoundaryCase = false; for (unsigned int l=0; l= this->m_Coefficients->GetLargestPossibleRegion().GetSize(l)) { mBoundaryCase = true; } } // Pointer to support offset const int * psupport; // Special case for boundary (to be changed ....) std::vector mCorrectedSupportOffset;//(mSupportSize); if (mBoundaryCase) { // return -1000; //std::vector coef(mSupportSize); // DD(EvaluateIndex); std::vector mCorrectedSupportIndex;//(mSupportSize); mCorrectedSupportIndex.resize(mSupportSize); mCorrectedSupportOffset.resize(mSupportSize); for(unsigned int i=0; im_Coefficients->GetLargestPossibleRegion().GetSize(l); // DD(a); // DD(b); long d2 = 2 * b - 2; if (a < 0) { mCorrectedSupportIndex[i][l] = -a - d2*(-a/d2) - EvaluateIndex[l];//mSupportIndex[i][l]-a; } else { if (a>=b) { mCorrectedSupportIndex[i][l] = d2 - a - EvaluateIndex[l]; } else { mCorrectedSupportIndex[i][l] = mSupportIndex[i][l]; //a - d2*(a/d2) - EvaluateIndex[l]; } /* if (a>=b) { mCorrectedSupportIndex[i][l] = d2 - a - EvaluateIndex[l];//mSupportIndex[i][l] - (a-(b-1)); } else { mCorrectedSupportIndex[i][l] = mSupportIndex[i][l]; } */ } } // DD(mCorrectedSupportIndex[i]); mCorrectedSupportOffset[i] = Index2Offset(mCorrectedSupportIndex[i], mInputMemoryOffset); } // for (unsigned int l=0; lm_Coefficients->GetPixel(EvaluateIndex)); // Main loop over BSpline support TCoefficientType interpolated = 0.0; for (unsigned int p=0; p