7 #include <itkPoolMultiThreader.h> 12 template <
typename TInputImageType>
13 BaseBlockMatcher <TInputImageType>
16 m_ForceComputeBlocks =
false;
17 m_NumberOfThreads = itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads();
19 m_BlockPercentageKept = 0.8;
23 m_BlockVarianceThreshold = 25;
26 m_FinalRadius = 0.001;
27 m_OptimizerMaximumIterations = 100;
33 m_HighestProcessedBlock = 0;
36 template <
typename TInputImageType>
42 typedef typename TInputImageType::IOPixelType InputPixelType;
44 typedef typename InitializerType::Pointer InitializerPointer;
46 InitializerPointer initPtr = InitializerType::New();
47 initPtr->AddReferenceImage(m_ReferenceImage);
49 if (m_NumberOfThreads != 0)
50 initPtr->SetNumberOfThreads(m_NumberOfThreads);
52 initPtr->SetPercentageKept(m_BlockPercentageKept);
53 initPtr->SetBlockSize(m_BlockSize);
54 initPtr->SetBlockSpacing(m_BlockSpacing);
55 initPtr->SetScalarVarianceThreshold(m_BlockVarianceThreshold);
56 initPtr->SetOrientedModelVarianceThreshold(m_BlockVarianceThreshold);
57 initPtr->AddGenerationMask(m_BlockGenerationMask);
59 initPtr->SetRequestedRegion(m_ReferenceImage->GetLargestPossibleRegion());
61 m_BlockRegions = initPtr->GetOutput();
62 m_BlockPositions = initPtr->GetOutputPositions();
65 std::cout <<
"Generated " << m_BlockRegions.size() <<
" blocks..." << std::endl;
67 m_BlockTransformPointers.resize(m_BlockRegions.size());
68 m_BlockWeights.resize(m_BlockRegions.size());
69 for (
unsigned int i = 0;i < m_BlockRegions.size();++i)
70 m_BlockTransformPointers[i] = this->GetNewBlockTransform(m_BlockPositions[i]);
73 template <
typename TInputImageType>
79 switch (m_OptimizerType)
84 optimizer = LocalOptimizerType::New();
85 LocalOptimizerType *tmpOpt = (LocalOptimizerType *)optimizer.GetPointer();
86 tmpOpt->SetRhoBegin(m_SearchRadius);
87 tmpOpt->SetRhoEnd(m_FinalRadius);
89 tmpOpt->SetNumberSamplingPoints(m_BlockTransformPointers[0]->GetNumberOfParameters() + 2);
90 tmpOpt->SetMaximumIteration(m_OptimizerMaximumIterations);
91 tmpOpt->SetMaximize(this->GetMaximizedMetric());
100 optimizer = LocalOptimizerType::New();
102 LocalOptimizerType *tmpOpt = (LocalOptimizerType *)optimizer.GetPointer();
103 LocalOptimizerType::StepsType steps(m_BlockTransformPointers[0]->GetNumberOfParameters());
105 typename InputImageType::SpacingType fixedSpacing = m_ReferenceImage->GetSpacing();
106 typename InputImageType::DirectionType fixedDirection = m_ReferenceImage->GetDirection();
108 vnl_matrix <double> geometry(InputImageType::ImageDimension,InputImageType::ImageDimension);
109 for (
unsigned int i = 0;i < InputImageType::ImageDimension;++i)
111 double tmpVoxSize = fixedSpacing[i];
113 for (
unsigned int j = 0;j < InputImageType::ImageDimension;++j)
114 geometry(j,i) = tmpVoxSize*fixedDirection(j,i);
117 tmpOpt->SetGeometry(geometry);
119 LocalOptimizerType::ScalesType tmpScales(InputImageType::ImageDimension);
121 for (
unsigned i = 0; i < steps.Size(); ++i)
123 steps[i] = m_SearchRadius;
124 tmpScales[i] = m_StepSize;
127 tmpOpt->SetNumberOfSteps(steps);
128 tmpOpt->SetScales(tmpScales);
129 tmpOpt->SetMaximize(this->GetMaximizedMetric());
134 this->TransformDependantOptimizerSetup(optimizer);
139 template <
typename TInputImageType>
145 if ((m_ForceComputeBlocks) || (m_BlockTransformPointers.size() == 0))
146 this->InitializeBlocks();
148 m_HighestProcessedBlock = 0;
149 itk::PoolMultiThreader::Pointer threadWorker = itk::PoolMultiThreader::New();
154 threadWorker->SetSingleMethod(this->ThreadedMatching,tmpStr);
155 threadWorker->SingleMethodExecute();
160 template <
typename TInputImageType>
161 ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
163 ::ThreadedMatching(
void *arg)
165 itk::MultiThreaderBase::WorkUnitInfo *threadArgs = (itk::MultiThreaderBase::WorkUnitInfo *)arg;
169 return ITK_THREAD_RETURN_DEFAULT_VALUE;
172 template <
typename TInputImageType>
175 ::ProcessBlockMatch()
177 bool continueLoop =
true;
178 unsigned int highestToleratedBlockIndex = m_BlockRegions.size();
180 unsigned int stepData = std::ceil(m_BlockRegions.size() / (10 * this->GetNumberOfWorkUnits()));
181 unsigned int minNumBlocks = std::min(highestToleratedBlockIndex,static_cast <unsigned int> (10));
182 stepData = std::max(minNumBlocks,stepData);
186 m_LockHighestProcessedBlock.lock();
188 if (m_HighestProcessedBlock >= highestToleratedBlockIndex)
190 m_LockHighestProcessedBlock.unlock();
191 continueLoop =
false;
195 unsigned int startPoint = m_HighestProcessedBlock;
196 unsigned int endPoint = m_HighestProcessedBlock + stepData;
197 if (endPoint > highestToleratedBlockIndex)
198 endPoint = highestToleratedBlockIndex;
200 m_HighestProcessedBlock = endPoint;
202 m_LockHighestProcessedBlock.unlock();
204 this->BlockMatch(startPoint,endPoint);
208 template <
typename TInputImageType>
211 ::BlockMatch(
unsigned int startIndex,
unsigned int endIndex)
217 for (
unsigned int block = startIndex;block < endIndex;++block)
219 this->BlockMatchingSetup(metric, block);
220 optimizer->SetCostFunction(metric);
221 optimizer->SetInitialPosition(m_BlockTransformPointers[block]->GetParameters());
225 optimizer->StartOptimization();
227 catch (itk::ExceptionObject & err)
229 m_BlockWeights[block] = 0;
233 m_BlockTransformPointers[block]->SetParameters(optimizer->GetCurrentPosition());
235 double val = optimizer->GetValue(optimizer->GetCurrentPosition());
236 m_BlockWeights[block] = this->ComputeBlockWeight(val,block);
MetricType::Pointer MetricPointer
void SetNumberOfWorkUnits(unsigned int val)
OptimizerType::Pointer OptimizerPointer