Skip to content

Commit 7b31773

Browse files
committed
Extended seeds/way points and support for seeds on the edge of images.
Extended seeds can be useful in minimal path applications. For example it might be known that a feature crosses a plane, but not exactly where. This patch allows the user to find the minimal path between a point and a plane, or between two planes. These changes are intended to be compatible with previous code using this module. There are issues with the back propogation steps. The original implementation was returning a value of 0 from the image cost function when the queried location was outside the image buffer. This causes problems whenever the path touches an image edge (or when a seed is on an image edge), as the back propogation process will terminate. This has been addressed by supplying methods to set the values returned when the query is outside the image buffer. Similar issues can occur when a speed image includes paths that are a single voxel wide. Gradient descent back propogation can be incorrectly terminated because the interpolator produces an artificial minima due to very large values in the arrival time image around the single voxel path. This problem hasn't been addressed.
1 parent 5a2017e commit 7b31773

34 files changed

+549
-63
lines changed

include/itkArrivalFunctionToPathFilter.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ class ITK_EXPORT ArrivalFunctionToPathFilter :
180180
typedef SingleValuedNonLinearOptimizer OptimizerType;
181181
typedef RegularStepGradientDescentOptimizer DefaultOptimizerType;
182182

183+
/** The points are in vectors to support extended "nodes" */
184+
typedef std::vector < PointType> PointsContainerType;
185+
183186
/** Get/set the Optimizer. */
184187
itkSetObjectMacro( Optimizer, OptimizerType );
185188
itkGetConstObjectMacro( Optimizer, OptimizerType );
@@ -226,12 +229,12 @@ class ITK_EXPORT ArrivalFunctionToPathFilter :
226229
virtual InputImageType * ComputeArrivalFunction( );
227230

228231
/** Get the next end point from which to back propagate. */
229-
virtual const PointType & GetNextEndPoint( );
232+
virtual const PointsContainerType & GetNextEndPoint( );
230233

231234
typename CostFunctionType::Pointer m_CostFunction;
232235
typename OptimizerType::Pointer m_Optimizer;
233236
typename OptimizerType::MeasureType m_TerminationValue;
234-
std::vector<PointType> m_PointList;
237+
std::vector<PointsContainerType> m_PointList;
235238
unsigned int m_CurrentOutput;
236239

237240
private:

include/itkArrivalFunctionToPathFilter.hxx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ void
5353
ArrivalFunctionToPathFilter<TInputImage,TOutputPath>
5454
::AddPathEndPoint(const PointType &point)
5555
{
56-
m_PointList.push_back( point );
56+
PointsContainerType V(1);
57+
V[0] = point;
58+
m_PointList.push_back( V );
5759
this->Modified();
5860
}
5961

@@ -95,7 +97,7 @@ ArrivalFunctionToPathFilter<TInputImage,TOutputPath>
9597
}
9698

9799
template<class TInputImage, class TOutputPath>
98-
const typename ArrivalFunctionToPathFilter<TInputImage,TOutputPath>::PointType &
100+
const typename ArrivalFunctionToPathFilter<TInputImage,TOutputPath>::PointsContainerType &
99101
ArrivalFunctionToPathFilter<TInputImage,TOutputPath>
100102
::GetNextEndPoint()
101103
{
@@ -190,7 +192,8 @@ ArrivalFunctionToPathFilter<TInputImage,TOutputPath>
190192
}
191193

192194
// Get the end point to back propagate from
193-
PointType pointEnd = this->GetNextEndPoint();
195+
PointsContainerType allpoints = this->GetNextEndPoint();
196+
PointType pointEnd = allpoints[0];
194197

195198
// Convert end point to parameters type
196199
typename CostFunctionType::ParametersType end(InputImageDimension);

include/itkSingleImageCostFunction.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ class ITK_EXPORT SingleImageCostFunction :
128128
virtual void GetDerivative( const ParametersType & parameters,
129129
DerivativeType & derivative ) const ITK_OVERRIDE;
130130

131+
// Set these depending on whether you will be minimizing or maximizing.
132+
// They control the value returned when the point isn't inside the buffer.
133+
void SetMinimize()
134+
{
135+
m_OutsideValue = itk::NumericTraits< ImagePixelType >::max();
136+
}
137+
void SetMaximize()
138+
{
139+
m_OutsideValue = itk::NumericTraits< ImagePixelType >::NonpositiveMin();
140+
}
141+
142+
131143
protected:
132144
SingleImageCostFunction();
133145
virtual ~SingleImageCostFunction() {}
@@ -139,7 +151,10 @@ class ITK_EXPORT SingleImageCostFunction :
139151
ImageConstPointer m_Image;
140152
typename InterpolatorType::Pointer m_Interpolator;
141153
typename GradientImageFunctionType::Pointer m_GradientImageFunction;
142-
154+
/** Used to define the value outside the image buffer. Important when
155+
* path points are on the edge of an image */
156+
ImagePixelType m_OutsideValue;
157+
143158
};
144159

145160
} // end namespace itk

include/itkSingleImageCostFunction.hxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ SingleImageCostFunction<TImage>
7272
m_Interpolator->SetInputImage( m_Image );
7373
m_GradientImageFunction->SetInputImage( m_Image );
7474

75+
this->SetMinimize();
7576
// If there are any objects observing the cost function,
7677
// call them to give the user code a chance to set parameters
7778
this->InvokeEvent( InitializeEvent() );
@@ -101,7 +102,7 @@ SingleImageCostFunction<TImage>
101102
}
102103
else
103104
{
104-
return 0.0;
105+
return m_OutsideValue;
105106
}
106107
}
107108

include/itkSpeedFunctionPathInformation.h

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ namespace itk
2929
* \brief PathInfo class for encapsulating information about a path
3030
* for a SpeedFunctionToPathFilter Object.
3131
* The points are stored as follows: end, start, way0, way1, ..., wayN.
32+
* Each element of a path can be a set of points - e.g. "end" may be
33+
* derived from a segmentation mask. Alternatively start and end may
34+
* be the left and right sides of a 2d image, producing a minimal
35+
* path across the image.
3236
* Fronts are propagated in reverse order: wayN, ..., way1, way0, start.
3337
* (NOTE: a front is never propagated from end).
3438
*
@@ -55,14 +59,16 @@ class SpeedFunctionPathInformation :
5559
typedef SmartPointer<Self> Pointer;
5660
typedef SmartPointer<const Self> ConstPointer;
5761

62+
5863
/** Run-time type information (and related methods). */
5964
itkTypeMacro(SpeedFunctionPathInformation, LightObject);
6065

6166
/** Method for creation through the object factory. */
6267
itkNewMacro(Self);
6368

6469
/** Some point typedefs. */
65-
typedef TPoint PointType;
70+
typedef TPoint PointType;
71+
typedef std::vector< PointType > PointsContainerType;
6672

6773
void ClearInfo();
6874

@@ -72,34 +78,60 @@ class SpeedFunctionPathInformation :
7278

7379
void AddWayPoint( const PointType & way );
7480

81+
82+
/** Methods for adding extended path components **/
83+
void SetStartPoint( const PointsContainerType & start );
84+
85+
void SetEndPoint( const PointsContainerType & end );
86+
87+
void AddWayPoint( const PointsContainerType & way );
88+
89+
// methods for modifying path seeds - needed when using
90+
// an extended seed.
91+
void SetCurrent( const PointsContainerType & newcurrent );
92+
void SetPrevious( const PointsContainerType & newprevious );
93+
void SetNext( const PointsContainerType & newnext );
94+
95+
void SetCurrent( const PointType & current );
96+
void SetPrevious( const PointType & newprevious );
97+
void SetNext( const PointType & newnext );
98+
99+
void Advance();
100+
75101
unsigned int GetNumberOfPoints( ) const;
76102

77-
const PointType & GetStartPoint( ) const;
103+
const PointsContainerType & GetStartPoint( ) const;
78104

79-
const PointType & GetEndPoint( ) const;
105+
const PointsContainerType & GetEndPoint( ) const;
80106

81-
const PointType & GetWayPoint( SizeValueType i ) const;
107+
const PointsContainerType & GetWayPoint( SizeValueType i ) const;
82108

83109
bool HasNextFront( ) const;
84110

85-
const PointType & GetCurrentFrontAndAdvance( );
86-
87-
const PointType & PeekCurrentFront( ) const;
111+
const PointsContainerType & GetCurrentFrontAndAdvance( );
88112

89-
const PointType & PeekNextFront( ) const;
113+
const PointsContainerType & PeekCurrentFront( ) const;
90114

91-
const PointType & PeekPreviousFront( ) const;
115+
const PointsContainerType & PeekNextFront( ) const;
92116

117+
const PointsContainerType & PeekPreviousFront( ) const;
118+
93119

94120
protected:
95121
SpeedFunctionPathInformation( );
96122
virtual ~SpeedFunctionPathInformation( );
97123
virtual void PrintSelf( std::ostream& os, Indent indent ) const ITK_OVERRIDE;
98124

99-
std::vector< PointType > m_Information;
100-
SizeValueType m_Front;
125+
std::vector< PointsContainerType > m_Information;
126+
SizeValueType m_Front;
101127

102128

129+
PointsContainerType PtoPVec(const PointType & P)
130+
{
131+
PointsContainerType V(1);
132+
V[0]=P;
133+
return(V);
134+
}
103135
private:
104136
ITK_DISALLOW_COPY_AND_ASSIGN(SpeedFunctionPathInformation);
105137
};

include/itkSpeedFunctionPathInformation.hxx

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,116 @@ template <typename TPoint>
5252
void SpeedFunctionPathInformation<TPoint>
5353
::SetStartPoint( const PointType & start )
5454
{
55-
m_Information[1] = start;
55+
m_Information[1] = PtoPVec(start);
5656
}
5757

5858

5959
template <typename TPoint>
6060
void SpeedFunctionPathInformation<TPoint>
6161
::SetEndPoint( const PointType & end )
6262
{
63-
m_Information[0] = end;
63+
m_Information[0] = PtoPVec( end );
6464
}
6565

6666

6767
template <typename TPoint>
6868
void SpeedFunctionPathInformation<TPoint>
6969
::AddWayPoint( const PointType & way )
70+
{
71+
m_Information.push_back( PtoPVec(way) );
72+
m_Front++;
73+
}
74+
75+
template <typename TPoint>
76+
void SpeedFunctionPathInformation<TPoint>
77+
::SetCurrent( const PointType & newcurrent )
78+
{
79+
m_Information[m_Front] = PtoPVec(newcurrent);
80+
}
81+
82+
template <typename TPoint>
83+
void SpeedFunctionPathInformation<TPoint>
84+
::Advance( void )
85+
{
86+
m_Front--;
87+
}
88+
89+
template <typename TPoint>
90+
void SpeedFunctionPathInformation<TPoint>
91+
::SetStartPoint( const PointsContainerType & start )
92+
{
93+
m_Information[1] = start;
94+
}
95+
96+
97+
template <typename TPoint>
98+
void SpeedFunctionPathInformation<TPoint>
99+
::SetEndPoint( const PointsContainerType & end )
100+
{
101+
m_Information[0] = end;
102+
}
103+
104+
105+
template <typename TPoint>
106+
void SpeedFunctionPathInformation<TPoint>
107+
::AddWayPoint( const PointsContainerType & way )
70108
{
71109
m_Information.push_back( way );
72110
m_Front++;
73111
}
74112

113+
template <typename TPoint>
114+
void SpeedFunctionPathInformation<TPoint>
115+
::SetCurrent( const PointsContainerType & newcurrent )
116+
{
117+
m_Information[m_Front] = newcurrent;
118+
}
119+
120+
template <typename TPoint>
121+
void SpeedFunctionPathInformation<TPoint>
122+
::SetPrevious( const PointsContainerType & newprevious )
123+
{
124+
SizeValueType F;
125+
if ( m_Front == m_Information.size()-1 )
126+
{
127+
F=0;
128+
}
129+
else
130+
{
131+
F = m_Front+1;
132+
}
133+
m_Information[F] = newprevious;
134+
}
135+
template <typename TPoint>
136+
void SpeedFunctionPathInformation<TPoint>
137+
::SetNext( const PointsContainerType & newnext )
138+
{
139+
SizeValueType F;
140+
if (m_Front <= 1)
141+
{
142+
F=1;
143+
}
144+
else
145+
{
146+
F = m_Front - 1;
147+
}
148+
m_Information[F] = newnext;
149+
}
150+
151+
template <typename TPoint>
152+
void SpeedFunctionPathInformation<TPoint>
153+
::SetPrevious( const PointType & newprevious )
154+
{
155+
SetPrevious(PtoPVec(newprevious));
156+
}
157+
158+
template <typename TPoint>
159+
void SpeedFunctionPathInformation<TPoint>
160+
::SetNext( const PointType & newnext )
161+
{
162+
SetNext(PtoPVec(newnext));
163+
}
164+
75165

76166
template <typename TPoint>
77167
unsigned int SpeedFunctionPathInformation<TPoint>
@@ -82,7 +172,7 @@ unsigned int SpeedFunctionPathInformation<TPoint>
82172

83173

84174
template <typename TPoint>
85-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
175+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
86176
SpeedFunctionPathInformation<TPoint>
87177
::GetStartPoint( ) const
88178
{
@@ -91,7 +181,7 @@ SpeedFunctionPathInformation<TPoint>
91181

92182

93183
template <typename TPoint>
94-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
184+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
95185
SpeedFunctionPathInformation<TPoint>
96186
::GetEndPoint( ) const
97187
{
@@ -100,7 +190,7 @@ SpeedFunctionPathInformation<TPoint>
100190

101191

102192
template <typename TPoint>
103-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
193+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
104194
SpeedFunctionPathInformation<TPoint>
105195
::GetWayPoint( SizeValueType i ) const
106196
{
@@ -118,7 +208,7 @@ bool SpeedFunctionPathInformation<TPoint>
118208

119209

120210
template <typename TPoint>
121-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
211+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
122212
SpeedFunctionPathInformation<TPoint>
123213
::GetCurrentFrontAndAdvance( )
124214
{
@@ -127,7 +217,7 @@ SpeedFunctionPathInformation<TPoint>
127217

128218

129219
template <typename TPoint>
130-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
220+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
131221
SpeedFunctionPathInformation<TPoint>
132222
::PeekCurrentFront( ) const
133223
{
@@ -136,7 +226,7 @@ SpeedFunctionPathInformation<TPoint>
136226

137227

138228
template <typename TPoint>
139-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
229+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
140230
SpeedFunctionPathInformation<TPoint>
141231
::PeekNextFront( ) const
142232
{
@@ -152,7 +242,7 @@ SpeedFunctionPathInformation<TPoint>
152242

153243

154244
template <typename TPoint>
155-
const typename SpeedFunctionPathInformation<TPoint>::PointType &
245+
const typename SpeedFunctionPathInformation<TPoint>::PointsContainerType &
156246
SpeedFunctionPathInformation<TPoint>
157247
::PeekPreviousFront( ) const
158248
{

0 commit comments

Comments
 (0)