@@ -33,6 +33,8 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
3333 m_CurrentArrivalFunction( nullptr )
3434{
3535 m_TargetRadius = 2 ;
36+ m_AutoTerminate = true ;
37+ m_AutoTerminateFactor = 0.5 ;
3638}
3739
3840
@@ -106,6 +108,51 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
106108 return (UniqueIndexes);
107109}
108110
111+
112+ template <typename TInputImage, typename TOutputPath>
113+ typename SpeedFunctionToPathFilter<TInputImage,TOutputPath>::InputImagePixelType
114+ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
115+ ::GetTrialGradient (IndexTypeVec idxs)
116+ {
117+ InputImagePointer arrival = m_CurrentArrivalFunction;
118+
119+ using BoundaryConditionType = ConstantBoundaryCondition<InputImageType>;
120+
121+ IndexTypeSet UniqueIndexes;
122+ typename InputImageType::SizeType radius;
123+ radius.Fill (1 );
124+ ConstNeighborhoodIterator<InputImageType, BoundaryConditionType>
125+ niterator (radius, arrival, arrival->GetLargestPossibleRegion ());
126+
127+ BoundaryConditionType bc;
128+ bc.SetConstant (itk::NumericTraits<InputImagePixelType>::max ());
129+ niterator.SetBoundaryCondition (bc);
130+ niterator.NeedToUseBoundaryConditionOn ();
131+
132+ // looking for the smallest nonzero difference
133+ InputImagePixelType mindiff (itk::NumericTraits<InputImagePixelType>::max ());
134+
135+ for (auto it = idxs.begin (); it != idxs.end (); it++ )
136+ {
137+ niterator.SetLocation (*it);
138+ InputImagePixelType CP = niterator.GetCenterPixel ();
139+ // Visit the entire neighborhood (including center) and
140+ // add any pixel that has a nonzero arrival function value
141+ for (auto NB = 0 ; NB < niterator.Size (); NB++)
142+ {
143+ // CP values should always be zero
144+ InputImagePixelType NPD = niterator.GetPixel (NB) - CP;
145+ if (NPD > 0 )
146+ {
147+ mindiff=std::min (mindiff, NPD);
148+ }
149+ }
150+ }
151+
152+ return (mindiff);
153+ }
154+
155+
109156template <typename TInputImage, typename TOutputPath>
110157typename SpeedFunctionToPathFilter<TInputImage,TOutputPath>::InputImageType *
111158SpeedFunctionToPathFilter<TInputImage,TOutputPath>
@@ -124,7 +171,6 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
124171 marching->SetInput ( speed );
125172 marching->SetGenerateGradientImage ( false );
126173 marching->SetTargetReachedModeToAllTargets ( );
127- // marching->SetTargetOffset( 2.0 * Superclass::m_TerminationValue);
128174 // Add next and previous front sources as target points to
129175 // limit the front propagation to just the required zones
130176 PointsContainerType PrevFront = m_Information[Superclass::m_CurrentOutput]->PeekPreviousFront ();
@@ -141,6 +187,7 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
141187 NodeType nodeTargetPrevious;
142188 speed->TransformPhysicalPointToIndex ( *it, indexTargetPrevious );
143189 PrevIndexVec.push_back (indexTargetPrevious);
190+ // std::cerr << "PrevTarg " << indexTargetPrevious << std::endl;
144191 }
145192
146193 for (auto it = NextFront.begin (); it != NextFront.end (); it++)
@@ -149,6 +196,8 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
149196 NodeType nodeTargetNext;
150197 speed->TransformPhysicalPointToIndex ( *it, indexTargetNext );
151198 NextIndexVec.push_back (indexTargetNext);
199+ // std::cerr << "NextTarg " << indexTargetNext << std::endl;
200+
152201 }
153202
154203 IndexTypeVec AllTargets ( PrevIndexVec );
@@ -182,6 +231,8 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
182231 nodeTrial.SetIndex ( indexTrial );
183232 trial->InsertElement ( trial->Size (), nodeTrial );
184233 CurrentIndexVec.push_back (indexTrial);
234+ // std::cerr << "TrialPt " << indexTrial << std::endl;
235+
185236 }
186237 marching->SetTrialPoints ( trial );
187238
@@ -207,9 +258,19 @@ SpeedFunctionToPathFilter<TInputImage,TOutputPath>
207258 m_Information[Superclass::m_CurrentOutput]->SetPrevious (PrevFront[MinPos]);
208259 }
209260
261+ if (m_AutoTerminate)
262+ {
263+ // Examine the neighbours of the trial points to determine the minimum neighbour
264+ // difference, for the purpose of estimating a good termination value.
265+ InputImagePixelType MD = GetTrialGradient ( CurrentIndexVec );
266+ std::cout << " Min diff for termination = " << MD << std::endl;
267+ this ->SetTerminationValue ( MD * this ->GetAutoTerminateFactor () );
268+ }
210269 // Make the arrival function flat inside the seeds, otherwise the
211270 // optimizer will cross over them. This only matters if the seeds are extended
212- if (CurrentIndexVec.size () > 1 )
271+ // Not sure that this is needed any more. Expect it was a side effect of only
272+ // adding a single point to the trial set.
273+ if ( CurrentIndexVec.size () > 1 )
213274 {
214275 for (auto vi = CurrentIndexVec.begin (); vi != CurrentIndexVec.end (); vi++)
215276 {
0 commit comments