#ifndef _CLITKVECTORBSPLINEINTERPOLATEIMAGEFUNCTIONWITHLUT_TXX #define _CLITKVECTORBSPLINEINTERPOLATEIMAGEFUNCTIONWITHLUT_TXX /* ========================================================================= @file itkBSplineInterpolateImageFunctionWithLUT.txx @author jefvdmb@gmail.com 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. ========================================================================= */ namespace clitk { //==================================================================== template VectorBSplineInterpolateImageFunctionWithLUT:: VectorBSplineInterpolateImageFunctionWithLUT():Superclass() { // Set default values //for(int i=0; i void VectorBSplineInterpolateImageFunctionWithLUT:: SetLUTSamplingFactor(const int& s) { for(int i=0; i void VectorBSplineInterpolateImageFunctionWithLUT:: SetLUTSamplingFactors(const SizeType& s) { for(int i=0; i // void VectorBSplineInterpolateImageFunctionWithLUT:: // SetOutputSpacing(const SpacingType & s) { // for(int i=0; i void VectorBSplineInterpolateImageFunctionWithLUT:: SetSplineOrder(const unsigned int& SplineOrder) { Superclass::SetSplineOrder(SplineOrder); // Compute support and half size static const int d = TImageType::ImageDimension; for(int l=0; l void VectorBSplineInterpolateImageFunctionWithLUT:: SetSplineOrders(const SizeType& SplineOrders) { mSplineOrders=SplineOrders; // Compute support and half size static const int d = TImageType::ImageDimension; for(int l=0; l void VectorBSplineInterpolateImageFunctionWithLUT:: SetInputImage(const TImageType * inputData) { //============================== // if (!mInputIsCoef) // { Superclass::SetInputImage(inputData); // } //============================== // //JV Don't call superclass (decomposition filter is executeed each time!) // else // { // this->m_Coefficients = inputData; // if ( this->m_Coefficients.IsNotNull()) // { // this->m_DataLength = this->m_Coefficients->GetBufferedRegion().GetSize(); // } // //Call super-superclass in case more input arrives // itk::ImageFunction::RealType, TCoefficientType>::SetInputImage(inputData); // } if (!inputData) return; UpdateWeightsProperties(); } //==================================================================== template void VectorBSplineInterpolateImageFunctionWithLUT:: UpdateWeightsProperties() { // Compute Memory offset inside coefficients images (for looping over coefficients) static const unsigned int d = TImageType::ImageDimension; mInputMemoryOffset[0] = 1; for(unsigned int l=1; lm_Coefficients->GetLargestPossibleRegion().GetSize(l-1); } //JV Put here? if (!mWeightsAreUpToDate) { // Compute mSupportOffset according to input size mSupportOffset.resize(mSupportSize); mSupportIndex.resize(mSupportSize); for(unsigned int l=0; l(mSupportIndex[k], mInputMemoryOffset); // next coefficient index if (k != mSupportSize-1) { for(unsigned int l=0; l(mSupportIndex[k+1][l]) == mSupport[l]) { mSupportIndex[k+1][l] = 0; l++; } else stop = true; } } } // // Check // for(unsigned int l=0; l void VectorBSplineInterpolateImageFunctionWithLUT:: 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 VectorBSplineInterpolateImageFunctionWithLUT::IndexType VectorBSplineInterpolateImageFunctionWithLUT:: 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 odd 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 VectorBSplineInterpolateImageFunctionWithLUT::OutputType VectorBSplineInterpolateImageFunctionWithLUT:: EvaluateAtContinuousIndex(const ContinuousIndexType & x) const { // For shorter coding static const unsigned int d = TImageType::ImageDimension; // Compute the index 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 boundaryCase = false; for (unsigned int l=0; l= this->m_Coefficients->GetLargestPossibleRegion().GetSize(l)) { boundaryCase = true; } } // Pointer to support offset const int * psupport; // Special case for boundary (to be changed ....) std::vector correctedSupportOffset; if (boundaryCase) { // return -1000; //std::vector coef(mSupportSize); // DD(EvaluateIndex); //std::vector CorrectedSupportOffset;//(mSupportSize); std::vector correctedSupportIndex;//(mSupportSize); correctedSupportIndex.resize(mSupportSize); correctedSupportOffset.resize(mSupportSize); for(unsigned int i=0; im_Coefficients->GetLargestPossibleRegion().GetSize(l); // DD(a); // DD(b); long d2 = 2 * b - 2; if (a < 0) { correctedSupportIndex[i][l] = -a - d2*(-a/d2) - evaluateIndex[l];//mSupportIndex[i][l]-a; } else { if (a>=b) { correctedSupportIndex[i][l] = d2 - a - evaluateIndex[l]; } else { correctedSupportIndex[i][l] = mSupportIndex[i][l]; //a - d2*(a/d2) - EvaluateIndex[l]; } /* if (a>=b) { correctedSupportIndex[i][l] = d2 - a - EvaluateIndex[l];//mSupportIndex[i][l] - (a-(b-1)); } else { correctedSupportIndex[i][l] = mSupportIndex[i][l]; } */ } } // DD(correctedSupportIndex[i]); correctedSupportOffset[i] = itk::Index2Offset(correctedSupportIndex[i], mInputMemoryOffset); } // for (unsigned int l=0; lm_Coefficients->GetPixel(evaluateIndex)); // Main loop over BSpline support CoefficientImagePixelType interpolated = 0.0; for (unsigned int p=0; p void VectorBSplineInterpolateImageFunctionWithLUT:: EvaluateWeightsAtContinuousIndex(const ContinuousIndexType& x, const TCoefficientType ** pweights, IndexType & evaluateIndex)const { // JV Compute BSpline weights if not up to date! Problem const: pass image as last // if (!mWeightsAreUpToDate) UpdatePrecomputedWeights(); // For shorter coding static const unsigned int d = TImageType::ImageDimension; // Compute the index 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); *pweights = mWeightsCalculator.GetFirstTensorProduct(weightIndex); } //==================================================================== } //end namespace #endif //_CLITKVECTORBSPLINEINTERPOLATEIMAGEFUNCTIONWITHLUT_TXX