10 #include <itkTimeProbe.h> 15 template <
unsigned int NDimensions>
16 BalooSVFTransformAgregator <NDimensions>::
26 template <
unsigned int NDimensions>
39 itk::TimeProbe tmpTime;
45 this->estimateSVFFromTranslations();
50 this->estimateSVFFromRigidTransforms();
56 this->estimateSVFFromAffineTransforms();
63 std::cout <<
"Agregation performed in " << tmpTime.GetTotal() << std::endl;
68 template <
unsigned int NDimensions>
71 estimateSVFFromTranslations()
75 velocityField->Initialize();
81 velocityField->Allocate();
85 itk::ImageRegionIterator < VelocityFieldType > svfIterator(velocityField,
m_LargestRegion);
86 while (!svfIterator.IsAtEnd())
88 svfIterator.Set(zeroDisp);
93 weights->Initialize();
100 weights->FillBuffer(m_ZeroWeight);
103 std::vector <VelocityFieldPixelType> curDisps(nbPts);
104 std::vector <VelocityFieldIndexType> posIndexes(nbPts);
106 for (
unsigned int i = 0;i < nbPts;++i)
113 for (
unsigned int j = 0;j < NDimensions;++j)
114 tmpParams[j] = tmpTr->GetOffset()[j];
118 weights->TransformPhysicalPointToIndex(this->
GetInputOrigin(i),posIndexes[i]);
120 for (
unsigned int j = 0;j < NDimensions;++j)
121 curDisps[i][j] = tmpParams[j];
123 velocityField->SetPixel(posIndexes[i],curDisps[i] * tmpWeight);
124 weights->SetPixel(posIndexes[i],tmpWeight);
127 this->filterInputs<NDimensions>(weights,velocityField,curDisps,posIndexes);
130 typename BaseOutputTransformType::Pointer resultTransform = BaseOutputTransformType::New();
131 resultTransform->SetIdentity();
132 resultTransform->SetParametersAsVectorField(velocityField.GetPointer());
137 template <
unsigned int NDimensions>
140 estimateSVFFromRigidTransforms()
142 const unsigned int NDegreesFreedom = NDimensions * (NDimensions + 1) / 2;
143 typedef itk::Image < itk::Vector <ScalarType, NDegreesFreedom>, NDimensions > RigidFieldType;
144 typedef typename RigidFieldType::Pointer RigidFieldPointer;
145 typedef itk::Vector <ScalarType, NDegreesFreedom> RigidVectorType;
148 RigidFieldPointer rigidField = RigidFieldType::New();
149 rigidField->Initialize();
155 rigidField->Allocate();
157 RigidVectorType zeroDisp;
159 itk::ImageRegionIterator < RigidFieldType > rigidIterator(rigidField,
m_LargestRegion);
160 while (!rigidIterator.IsAtEnd())
162 rigidIterator.Set(zeroDisp);
167 weights->Initialize();
174 weights->FillBuffer(m_ZeroWeight);
176 RigidVectorType curLog;
178 vnl_matrix <InternalScalarType> tmpMatrix(NDimensions+1,NDimensions+1,0);
179 tmpMatrix(NDimensions,NDimensions) = 1;
180 std::vector < RigidVectorType > logVectors(nbPts);
181 std::vector <VelocityFieldIndexType> posIndexes(nbPts);
186 for (
unsigned int i = 0;i < nbPts;++i)
189 weights->TransformPhysicalPointToIndex(this->
GetInputOrigin(i),posIndexes[i]);
191 LogRigidTransformType *tmpTrsf = (LogRigidTransformType *)this->
GetInputTransform(i);
192 logVectors[i] = tmpTrsf->GetLogVector();
193 rigidField->SetPixel(posIndexes[i],logVectors[i] * tmpWeight);
194 weights->SetPixel(posIndexes[i],tmpWeight);
197 this->filterInputs<NDegreesFreedom>(weights,rigidField,logVectors,posIndexes);
200 velocityField->Initialize();
204 velocityField->SetOrigin (
m_Origin);
206 velocityField->Allocate();
208 itk::ImageRegionIteratorWithIndex < VelocityFieldType > svfIterator(velocityField,
m_LargestRegion);
213 rigidIterator = itk::ImageRegionIterator < RigidFieldType > (rigidField,
m_LargestRegion);
214 while (!svfIterator.IsAtEnd())
216 curLog = rigidIterator.Get();
218 unsigned int pos = 0;
219 for (
unsigned int j = 0;j < NDimensions;++j)
220 for (
unsigned int k = j+1;k < NDimensions;++k)
222 tmpMatrix(j,k) = curLog[pos];
223 tmpMatrix(k,j) = - curLog[pos];
227 for (
unsigned int j = 0;j < NDimensions;++j)
229 tmpMatrix(j,NDimensions) = curLog[pos];
233 curIndex = svfIterator.GetIndex();
234 velocityField->TransformIndexToPhysicalPoint(curIndex,curPoint);
235 for (
unsigned int i = 0;i < NDimensions;++i)
237 curDisp[i] = tmpMatrix(i,NDimensions);
238 for (
unsigned int j = 0;j < NDimensions;++j)
239 curDisp[i] += tmpMatrix(i,j) * curPoint[j];
242 svfIterator.Set(curDisp);
249 typename BaseOutputTransformType::Pointer resultTransform = BaseOutputTransformType::New();
250 resultTransform->SetIdentity();
251 resultTransform->SetParametersAsVectorField(velocityField.GetPointer());
256 template <
unsigned int NDimensions>
259 estimateSVFFromAffineTransforms()
261 const unsigned int NDegreesFreedom = NDimensions * (NDimensions + 1);
262 typedef itk::Image < itk::Vector <ScalarType, NDegreesFreedom>, NDimensions > AffineFieldType;
263 typedef typename AffineFieldType::Pointer AffineFieldPointer;
264 typedef itk::Vector <ScalarType, NDegreesFreedom> AffineVectorType;
267 AffineFieldPointer affineField = AffineFieldType::New();
268 affineField->Initialize();
274 affineField->Allocate();
276 AffineVectorType zeroDisp;
278 itk::ImageRegionIterator < AffineFieldType > affineIterator(affineField,
m_LargestRegion);
279 while (!affineIterator.IsAtEnd())
281 affineIterator.Set(zeroDisp);
286 weights->Initialize();
293 weights->FillBuffer(m_ZeroWeight);
295 AffineVectorType curLog;
298 vnl_matrix <InternalScalarType> tmpMatrix(NDimensions+1,NDimensions+1,0);
299 tmpMatrix(NDimensions,NDimensions) = 1;
300 std::vector < AffineVectorType > logVectors(nbPts);
301 std::vector < VelocityFieldIndexType > posIndexes(nbPts);
307 MatrixLoggerFilterType *logFilter =
new MatrixLoggerFilterType;
310 logFilter->SetUseRigidTransforms(
false);
313 logVectors = logFilter->GetOutput();
320 DistoTrsfType *tmpTrsf;
321 for (
unsigned int i = 0;i < nbPts;++i)
324 logVectors[i] = tmpTrsf->GetLogVector();
328 for (
unsigned int i = 0;i < nbPts;++i)
331 weights->TransformPhysicalPointToIndex(this->
GetInputOrigin(i),posIndexes[i]);
333 if (std::isnan(logVectors[i][0]))
335 logVectors[i].Fill(0);
339 affineField->SetPixel(posIndexes[i],logVectors[i] * tmpWeight);
340 weights->SetPixel(posIndexes[i],tmpWeight);
343 this->filterInputs<NDegreesFreedom>(weights,affineField,logVectors,posIndexes);
346 velocityField->Initialize();
350 velocityField->SetOrigin (
m_Origin);
352 velocityField->Allocate();
354 itk::ImageRegionIteratorWithIndex < VelocityFieldType > svfIterator(velocityField,
m_LargestRegion);
359 affineIterator = itk::ImageRegionIterator < AffineFieldType > (affineField,
m_LargestRegion);
360 while (!svfIterator.IsAtEnd())
362 curLog = affineIterator.Get();
364 unsigned int pos = 0;
365 for (
unsigned int j = 0;j < NDimensions;++j)
366 for (
unsigned int k = 0;k <= NDimensions;++k)
368 tmpMatrix(j,k) = curLog[pos];
372 curIndex = svfIterator.GetIndex();
373 velocityField->TransformIndexToPhysicalPoint(curIndex,curPoint);
374 for (
unsigned int i = 0;i < NDimensions;++i)
376 curDisp[i] = tmpMatrix(i,NDimensions);
377 for (
unsigned int j = 0;j < NDimensions;++j)
378 curDisp[i] += tmpMatrix(i,j) * curPoint[j];
381 svfIterator.Set(curDisp);
388 typename BaseOutputTransformType::Pointer resultTransform = BaseOutputTransformType::New();
389 resultTransform->SetIdentity();
390 resultTransform->SetParametersAsVectorField(velocityField.GetPointer());
395 template <
unsigned int NDimensions>
396 template <
unsigned int NDegreesOfFreedom>
399 filterInputs(
WeightImageType *weights,
typename itk::Image < itk::Vector <ScalarType, NDegreesOfFreedom>, NDimensions >::Pointer &output,
400 std::vector < itk::Vector <ScalarType, NDegreesOfFreedom> > &curTrsfs,
401 std::vector <
typename itk::Image < itk::Vector <ScalarType, NDegreesOfFreedom>, NDimensions >::IndexType > &posIndexes)
403 typedef itk::Image < itk::Vector <ScalarType, NDegreesOfFreedom>, NDimensions > FieldType;
404 typedef itk::Vector <ScalarType, NDegreesOfFreedom> FieldPixelType;
408 FieldPixelType zeroTrsf;
412 typename WeightSmootherType::Pointer weightSmooth = WeightSmootherType::New();
414 weightSmooth->SetInput(weights);
418 weightSmooth->Update();
420 typename WeightImageType::Pointer smoothedWeights = weightSmooth->GetOutput();
421 smoothedWeights->DisconnectPipeline();
425 typename SVFSmoothingFilterType::Pointer smootherPtr = SVFSmoothingFilterType::New();
427 smootherPtr->SetInput(output);
431 smootherPtr->Update();
433 typename FieldType::Pointer smoothedField = smootherPtr->GetOutput();
434 smoothedField->DisconnectPipeline();
438 FieldPixelType curTrsf;
441 std::vector < double > residuals(nbPts);
442 double averageResidual = 0, varResidual = 0;
443 for (
unsigned int i = 0;i < nbPts;++i)
445 double weightSmoothed = smoothedWeights->GetPixel(posIndexes[i]);
446 if (weightSmoothed > 0)
448 curTrsf = smoothedField->GetPixel(posIndexes[i]);
449 curTrsf /= weightSmoothed;
456 for (
unsigned int j = 0;j < NDegreesOfFreedom;++j)
457 residual += (curTrsf[j] - curTrsfs[i][j]) * (curTrsf[j] - curTrsfs[i][j]);
459 varResidual += residual;
460 residual = sqrt(residual);
461 averageResidual += residual;
462 residuals[i] = residual;
468 varResidual = sqrt((varResidual - averageResidual * averageResidual / nbPts) / (nbPts - 1.0));
469 averageResidual /= nbPts;
471 for (
unsigned int i = 0;i < nbPts;++i)
475 output->SetPixel(posIndexes[i],zeroTrsf);
476 weights->SetPixel(posIndexes[i],m_ZeroWeight);
480 weightSmooth = WeightSmootherType::New();
482 weightSmooth->SetInput(weights);
486 weightSmooth->Update();
488 smoothedWeights = weightSmooth->GetOutput();
489 smoothedWeights->DisconnectPipeline();
491 smootherPtr = SVFSmoothingFilterType::New();
493 smootherPtr->SetInput(output);
497 smootherPtr->Update();
499 output = smootherPtr->GetOutput();
500 output->DisconnectPipeline();
503 typename ExtrapolateFilterType::Pointer extrapolateFilter = ExtrapolateFilterType::New();
504 extrapolateFilter->SetInput(output);
507 extrapolateFilter->SetWeightImage(smoothedWeights);
508 extrapolateFilter->Update();
510 output = extrapolateFilter->GetOutput();
511 output->DisconnectPipeline();
void SetInput(InputType &input)
Class to compute many log-vectors in a multi-threaded way.