3 #include <itkImageMomentsCalculator.h> 9 #include <itkResampleImageFilter.h> 17 template <
unsigned int ImageDimension>
20 m_BackwardImage = NULL;
21 m_ForwardImage = NULL;
23 m_InitialTransform = NULL;
25 m_OutputTransform = DisplacementFieldTransformType::New();
26 m_OutputTransform->SetIdentity();
28 m_outputTransformFile =
"";
32 m_TransformDirection = 0;
36 m_MaximumIterations = 10;
37 m_OptimizerMaximumIterations = 100;
39 m_SearchScaleRadius = 0.1;
40 m_SearchSkewRadius = 0.1;
41 m_FinalRadius = 0.001;
42 m_TranlateUpperBound = 50;
43 m_ScaleUpperBound = std::log(5.0);
44 m_SkewUpperBound = std::tan(M_PI / 3.0);
48 m_WeightedAgregation =
false;
49 m_ExtrapolationSigma = 3;
52 m_MEstimateConvergenceThreshold = 0.01;
53 m_NeighborhoodApproximation = 2.5;
54 m_ExponentiationOrder = 1;
55 m_NumberOfPyramidLevels = 3;
56 m_LastPyramidLevel = 0;
57 m_PercentageKept = 0.8;
58 this->SetNumberOfWorkUnits(itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads());
61 template <
unsigned int ImageDimension>
66 if (!m_InitialTransform)
67 m_InitialTransform = DisplacementFieldTransformType::New();
69 m_InitialTransform->SetParametersAsVectorField(field);
72 template <
unsigned int ImageDimension>
77 template <
unsigned int ImageDimension>
83 this->SetupPyramids();
86 for (
unsigned int i = 0;i < m_BackwardPyramid->GetNumberOfLevels();++i)
88 if (i + m_LastPyramidLevel >= m_BackwardPyramid->GetNumberOfLevels())
91 typename InputImageType::Pointer backwardImage = m_BackwardPyramid->GetOutput(i);
92 backwardImage->DisconnectPipeline();
94 typename InputImageType::Pointer forwardImage = m_ForwardPyramid->GetOutput(i);
95 forwardImage->DisconnectPipeline();
98 if (m_OutputTransform->GetParametersAsVectorField() != NULL)
100 typedef itk::ResampleImageFilter<VectorFieldType,VectorFieldType> VectorResampleFilterType;
101 typedef typename VectorResampleFilterType::Pointer VectorResampleFilterPointer;
104 tmpIdentity->SetIdentity();
106 VectorResampleFilterPointer tmpResample = VectorResampleFilterType::New();
107 tmpResample->SetTransform(tmpIdentity);
108 tmpResample->SetInput(m_OutputTransform->GetParametersAsVectorField());
110 tmpResample->SetSize(backwardImage->GetLargestPossibleRegion().GetSize());
111 tmpResample->SetOutputOrigin(backwardImage->GetOrigin());
112 tmpResample->SetOutputSpacing(backwardImage->GetSpacing());
113 tmpResample->SetOutputDirection(backwardImage->GetDirection());
115 tmpResample->Update();
118 m_OutputTransform->SetParametersAsVectorField(tmpOut);
119 tmpOut->DisconnectPipeline();
124 if (m_InitialTransform)
126 typedef itk::ResampleImageFilter<VectorFieldType,VectorFieldType> VectorResampleFilterType;
127 typedef typename VectorResampleFilterType::Pointer VectorResampleFilterPointer;
130 tmpIdentity->SetIdentity();
132 VectorResampleFilterPointer tmpResample = VectorResampleFilterType::New();
133 tmpResample->SetTransform(tmpIdentity);
134 tmpResample->SetInput(m_InitialTransform->GetParametersAsVectorField());
136 tmpResample->SetSize(backwardImage->GetLargestPossibleRegion().GetSize());
137 tmpResample->SetOutputOrigin(backwardImage->GetOrigin());
138 tmpResample->SetOutputSpacing(backwardImage->GetSpacing());
139 tmpResample->SetOutputDirection(backwardImage->GetDirection());
141 tmpResample->Update();
144 initialTransform = DisplacementFieldTransformType::New();
145 initialTransform->SetParametersAsVectorField(tmpOut);
146 tmpOut->DisconnectPipeline();
149 std::cout <<
"Processing pyramid level " << i << std::endl;
150 std::cout <<
"Image size: " << backwardImage->GetLargestPossibleRegion().GetSize() << std::endl;
152 double meanSpacing = 0;
153 for (
unsigned int j = 0;j < ImageDimension;++j)
154 meanSpacing += backwardImage->GetSpacing()[j];
155 meanSpacing /= ImageDimension;
158 typename BlockMatchRegistrationType::Pointer bmreg = BlockMatchRegistrationType::New();
160 bmreg->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
165 typename ResampleFilterType::Pointer refResampler = ResampleFilterType::New();
166 refResampler->SetSize(forwardImage->GetLargestPossibleRegion().GetSize());
167 refResampler->SetOutputOrigin(forwardImage->GetOrigin());
168 refResampler->SetOutputSpacing(forwardImage->GetSpacing());
169 refResampler->SetOutputDirection(forwardImage->GetDirection());
170 refResampler->SetDefaultPixelValue(0);
171 refResampler->SetNumberOfWorkUnits(GetNumberOfWorkUnits());
172 refResampler->SetScaleIntensitiesWithJacobian(
true);
173 bmreg->SetReferenceImageResampler(refResampler);
175 typename ResampleFilterType::Pointer movingResampler = ResampleFilterType::New();
176 movingResampler->SetSize(backwardImage->GetLargestPossibleRegion().GetSize());
177 movingResampler->SetOutputOrigin(backwardImage->GetOrigin());
178 movingResampler->SetOutputSpacing(backwardImage->GetSpacing());
179 movingResampler->SetOutputDirection(backwardImage->GetDirection());
180 movingResampler->SetDefaultPixelValue(0);
181 movingResampler->SetNumberOfWorkUnits(GetNumberOfWorkUnits());
182 movingResampler->SetScaleIntensitiesWithJacobian(
true);
183 bmreg->SetMovingImageResampler(movingResampler);
188 BlockMatcherType *mainMatcher =
new BlockMatcherType;
190 mainMatcher->SetBlockSize(GetBlockSize());
191 mainMatcher->SetBlockSpacing(GetBlockSpacing());
192 mainMatcher->SetBlockVarianceThreshold(GetStDevThreshold() * GetStDevThreshold());
194 bmreg->SetBlockMatcher(mainMatcher);
196 bmreg->SetFixedImage(backwardImage);
197 bmreg->SetMovingImage(forwardImage);
213 agreg->
SetDistanceBoundary(m_ExtrapolationSigma * meanSpacing * m_NeighborhoodApproximation);
231 bmreg->SetAgregator(agregPtr);
232 bmreg->SetExponentiationOrder(m_ExponentiationOrder);
234 mainMatcher->SetBlockTransformType((
typename BlockMatcherType::TransformDefinition) m_TransformKind);
235 mainMatcher->SetSimilarityType((
typename BlockMatcherType::SimilarityDefinition) m_Metric);
238 bmreg->SetSVFElasticRegSigma(m_ElasticSigma * meanSpacing);
240 bmreg->SetMaximumIterations(m_MaximumIterations);
241 mainMatcher->SetOptimizerMaximumIterations(m_OptimizerMaximumIterations);
242 mainMatcher->SetTransformDirection(m_TransformDirection);
244 if (initialTransform)
245 bmreg->SetInitialTransform(initialTransform.GetPointer());
247 bmreg->SetCurrentTransform(m_OutputTransform.GetPointer());
249 mainMatcher->SetSearchRadius(m_SearchRadius);
250 mainMatcher->SetSearchScaleRadius(m_SearchScaleRadius);
251 mainMatcher->SetSearchSkewRadius(m_SearchSkewRadius);
252 mainMatcher->SetFinalRadius(m_FinalRadius);
253 mainMatcher->SetTranslateMax(m_TranlateUpperBound);
254 mainMatcher->SetScaleMax(m_ScaleUpperBound);
255 mainMatcher->SetSkewMax(m_SkewUpperBound);
261 m_OutputTransform->SetParametersAsVectorField(resTrsf->GetParametersAsVectorField());
269 if (m_LastPyramidLevel != 0)
272 typedef itk::ResampleImageFilter<VectorFieldType,VectorFieldType> VectorResampleFilterType;
273 typedef typename VectorResampleFilterType::Pointer VectorResampleFilterPointer;
276 tmpIdentity->SetIdentity();
278 VectorResampleFilterPointer tmpResample = VectorResampleFilterType::New();
279 tmpResample->SetTransform(tmpIdentity);
280 tmpResample->SetInput(m_OutputTransform->GetParametersAsVectorField());
282 tmpResample->SetSize(m_BackwardImage->GetLargestPossibleRegion().GetSize());
283 tmpResample->SetOutputOrigin(m_BackwardImage->GetOrigin());
284 tmpResample->SetOutputSpacing(m_BackwardImage->GetSpacing());
285 tmpResample->SetOutputDirection(m_BackwardImage->GetDirection());
287 tmpResample->Update();
290 m_OutputTransform->SetParametersAsVectorField(tmpOut);
291 tmpOut->DisconnectPipeline();
299 typedef itk::MultiplyImageFilter <VectorFieldType,itk::Image <double, ImageDimension>,
VectorFieldType> MultiplyFilterType;
300 typename MultiplyFilterType::Pointer multiplyFilter = MultiplyFilterType::New();
301 multiplyFilter->SetInput(m_OutputTransform->GetParametersAsVectorField());
302 multiplyFilter->SetConstant(-1.0);
303 multiplyFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
305 multiplyFilter->Update();
307 oppositeTransform->SetParametersAsVectorField(multiplyFilter->GetOutput());
309 if (m_InitialTransform)
310 anima::composeDistortionCorrections<typename BaseAgregatorType::ScalarType,ImageDimension>
311 (m_InitialTransform,m_OutputTransform,oppositeTransform,this->GetNumberOfWorkUnits());
313 typename ResampleFilterType::Pointer tmpResampleFloating = ResampleFilterType::New();
314 tmpResampleFloating->SetTransform(m_OutputTransform);
315 tmpResampleFloating->SetInput(m_ForwardImage);
317 tmpResampleFloating->SetSize(m_BackwardImage->GetLargestPossibleRegion().GetSize());
318 tmpResampleFloating->SetOutputOrigin(m_BackwardImage->GetOrigin());
319 tmpResampleFloating->SetOutputSpacing(m_BackwardImage->GetSpacing());
320 tmpResampleFloating->SetOutputDirection(m_BackwardImage->GetDirection());
321 tmpResampleFloating->SetDefaultPixelValue(0);
322 tmpResampleFloating->SetScaleIntensitiesWithJacobian(
true);
323 tmpResampleFloating->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
324 tmpResampleFloating->Update();
326 typename ResampleFilterType::Pointer tmpResampleReference = ResampleFilterType::New();
327 tmpResampleReference->SetTransform(oppositeTransform);
328 tmpResampleReference->SetInput(m_BackwardImage);
330 tmpResampleReference->SetSize(m_BackwardImage->GetLargestPossibleRegion().GetSize());
331 tmpResampleReference->SetOutputOrigin(m_BackwardImage->GetOrigin());
332 tmpResampleReference->SetOutputSpacing(m_BackwardImage->GetSpacing());
333 tmpResampleReference->SetOutputDirection(m_BackwardImage->GetDirection());
334 tmpResampleReference->SetDefaultPixelValue(0);
335 tmpResampleReference->SetScaleIntensitiesWithJacobian(
true);
336 tmpResampleReference->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
338 tmpResampleReference->Update();
340 typedef itk::AddImageFilter <InputImageType,InputImageType,InputImageType> AddFilterType;
341 typename AddFilterType::Pointer addFilter = AddFilterType::New();
342 addFilter->SetInput1(tmpResampleFloating->GetOutput());
343 addFilter->SetInput2(tmpResampleReference->GetOutput());
344 addFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
348 typedef itk::MultiplyImageFilter <InputImageType,itk::Image <double, ImageDimension>,InputImageType> MultiplyScalarFilterType;
349 typename MultiplyScalarFilterType::Pointer multiplyScalarFilter = MultiplyScalarFilterType::New();
350 multiplyScalarFilter->SetInput(addFilter->GetOutput());
351 multiplyScalarFilter->SetConstant(0.5);
352 multiplyScalarFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
353 multiplyScalarFilter->InPlaceOn();
355 multiplyScalarFilter->Update();
357 m_OutputImage = multiplyScalarFilter->GetOutput();
358 m_OutputImage->DisconnectPipeline();
361 template <
unsigned int ImageDimension>
365 std::cout <<
"Writing output image to: " << m_resultFile << std::endl;
366 anima::writeImage<InputImageType>(m_resultFile,m_OutputImage);
368 if (m_outputTransformFile !=
"")
370 std::cout <<
"Writing output transform to: " << m_outputTransformFile << std::endl;
371 anima::writeImage<VectorFieldType>(m_outputTransformFile, const_cast <
VectorFieldType *> (m_OutputTransform->GetParametersAsVectorField()));
375 template <
unsigned int ImageDimension>
380 m_BackwardPyramid = PyramidType::New();
382 m_BackwardPyramid->SetInput(m_BackwardImage);
383 m_BackwardPyramid->SetNumberOfLevels(m_NumberOfPyramidLevels);
384 m_BackwardPyramid->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
389 typename ResampleFilterType::Pointer backwardResampler = ResampleFilterType::New();
390 m_BackwardPyramid->SetImageResampler(backwardResampler);
392 m_BackwardPyramid->Update();
395 m_ForwardPyramid = PyramidType::New();
397 m_ForwardPyramid->SetInput(m_ForwardImage);
398 m_ForwardPyramid->SetNumberOfLevels(m_NumberOfPyramidLevels);
399 m_ForwardPyramid->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
401 typename ResampleFilterType::Pointer forwardResampler = ResampleFilterType::New();
402 m_ForwardPyramid->SetImageResampler(forwardResampler);
404 m_ForwardPyramid->Update();
PyramidalDistortionCorrectionBlockMatchingBridge()
~PyramidalDistortionCorrectionBlockMatchingBridge()
DisplacementFieldTransformType::Pointer DisplacementFieldTransformPointer
void SetBlockPercentageKept(double val)
DisplacementFieldTransformType::VectorFieldType VectorFieldType
void SetInitialTransformField(VectorFieldType *field)
AffineTransformType::Pointer AffineTransformPointer
itk::Image< double, ImageDimension > InputImageType
rpi::DisplacementFieldTransform< typename BaseAgregatorType::ScalarType, ImageDimension > DisplacementFieldTransformType