@@ -42,6 +42,25 @@ RichardsonLucyPVCImageFilter< TInputImage >
42
42
this ->m_fStopCriterion = -3e+06 ;
43
43
}
44
44
45
+ template < class TInputImage >
46
+ float RichardsonLucyPVCImageFilter< TInputImage >
47
+ ::GetZeroThreshold ( typename TInputImage::ConstPointer img )
48
+ {
49
+ // Default threshold to zero values at:
50
+ const float fZeroThreshold = 1e-4f ;
51
+
52
+ // Calculate image statistics
53
+ typename StatisticsFilterType::Pointer statsFilter = StatisticsFilterType::New ();
54
+ statsFilter->SetInput ( img );
55
+ statsFilter->Update ();
56
+
57
+ // Return default or (image max * default ) as new threshold
58
+ const float fNewThreshold = std::min ( fZeroThreshold , statsFilter->GetMaximum () * fZeroThreshold );
59
+
60
+ // Set to zero if somehow new threshold is negative!
61
+ return std::max ( fNewThreshold , 0 .0f );
62
+ }
63
+
45
64
template < class TInputImage >
46
65
void RichardsonLucyPVCImageFilter< TInputImage >
47
66
::GenerateData ()
@@ -79,50 +98,98 @@ void RichardsonLucyPVCImageFilter< TInputImage >
79
98
typename TInputImage::Pointer imageEstimate;
80
99
// Set image estimate to the original non-negative PET data for the first iteration.
81
100
imageEstimate = duplicator->GetOutput ();
101
+ imageEstimate->DisconnectPipeline ();
102
+
103
+ // Create a blank image with same dimensions as input to use for division
104
+ duplicator->SetInputImage (imageEstimate);
105
+ duplicator->Update ();
106
+
107
+ typedef itk::CastImageFilter< TInputImage, TInputImage > CastImageFilterType;
108
+ typename CastImageFilterType::Pointer castFilter = CastImageFilterType::New ();
109
+ castFilter->SetInput ( duplicator->GetOutput () );
110
+ castFilter->Update ();
111
+ typename TInputImage::Pointer blankImage = castFilter->GetOutput ();
112
+
113
+ typedef typename TInputImage::PixelType PixelType;
114
+ blankImage->FillBuffer ( itk::NumericTraits< PixelType >::Zero );
115
+
116
+ // Image to store result of division
117
+ typename TInputImage::Pointer dividedImage;
82
118
83
119
int nMaxNumOfIters = this ->m_nIterations ;
84
120
int n=1 ;
85
121
86
122
bool bStopped = false ;
87
-
88
123
89
124
while ( ( n <= nMaxNumOfIters ) && ( !bStopped ) ) {
90
- float fLog = 0.0 ;
125
+ float fLog = 0.0 ;
126
+ // f_k * h
91
127
blurFilter->SetInput ( imageEstimate );
92
- divideFilter->SetInput1 ( thresholdFilter->GetOutput () );
93
- divideFilter->SetInput2 ( blurFilter->GetOutput () );
128
+ blurFilter->Update ();
129
+
130
+ // Perform f(x) / [ f_k(x) * h ] voxel-by-voxel as itk::DivideFilterType sets image
131
+ // to max if denominator is 0.
132
+ ConstImageIterator numeratorIt ( thresholdFilter->GetOutput (), thresholdFilter->GetOutput ()->GetLargestPossibleRegion () );
133
+ ConstImageIterator denomIt ( blurFilter->GetOutput (), blurFilter->GetOutput ()->GetLargestPossibleRegion () );
134
+
135
+ duplicator->SetInputImage (blankImage);
136
+ duplicator->Update ();
137
+ dividedImage = duplicator->GetOutput ();
138
+ dividedImage->DisconnectPipeline ();
139
+
140
+ ImageRegionIterator<TInputImage> divIt ( dividedImage, dividedImage->GetLargestPossibleRegion () );
141
+
142
+ numeratorIt.GoToBegin ();
143
+ denomIt.GoToBegin ();
144
+ divIt.GoToBegin ();
145
+
146
+ // Get zero threshold
147
+ const float fSmallNum = this ->GetZeroThreshold ( blurFilter->GetOutput () );
148
+
149
+ while ( !divIt.IsAtEnd () )
150
+ {
151
+ if ( denomIt.Get () > fSmallNum )
152
+ divIt.Set (numeratorIt.Get () / denomIt.Get ());
153
+ else
154
+ divIt.Set (itk::NumericTraits< PixelType >::Zero);
155
+
156
+ ++numeratorIt;
157
+ ++denomIt;
158
+ ++divIt;
159
+ }
160
+
161
+ // Reblur correction factors
162
+ blurFilter2->SetInput ( dividedImage );
163
+ blurFilter2->Update ();
164
+
165
+ // Multiply current image estimate by reblurred correction factors
94
166
multiplyFilter->SetInput1 ( imageEstimate );
95
- multiplyFilter->SetInput2 ( divideFilter ->GetOutput () );
167
+ multiplyFilter->SetInput2 ( blurFilter2 ->GetOutput () );
96
168
multiplyFilter->Update ();
97
-
169
+
170
+ // Update image estimate
98
171
imageEstimate = multiplyFilter->GetOutput ();
99
172
imageEstimate->DisconnectPipeline ();
100
-
101
- blurFilter2->SetInput ( imageEstimate );
102
- blurFilter2->Update ();
103
173
104
174
ConstImageIterator origIt ( thresholdFilter->GetOutput (), thresholdFilter->GetOutput ()->GetLargestPossibleRegion () );
105
- ConstImageIterator currIt ( blurFilter2-> GetOutput (), blurFilter2-> GetOutput () ->GetLargestPossibleRegion () );
175
+ ConstImageIterator currIt ( imageEstimate, imageEstimate ->GetLargestPossibleRegion () );
106
176
107
177
origIt.GoToBegin ();
108
178
currIt.GoToBegin ();
109
179
110
180
while ( !currIt.IsAtEnd () )
111
181
{
112
182
if (currIt.Get () > 0.0 ) {
113
- float diff = origIt.Get () * log (currIt.Get ()) - currIt.Get ();
114
- fLog += diff;
183
+ fLog += origIt.Get () * log (currIt.Get ()) - currIt.Get ();
115
184
}
185
+
116
186
++currIt;
117
187
++origIt;
118
188
}
119
189
120
190
float fCurrentEval = fLog ;
121
191
std::cout << n << " \t " << fCurrentEval << std::endl;
122
192
n++;
123
-
124
- // if ( fCurrentEval < this->m_fStopCriterion )
125
- // bStopped = true;
126
193
}
127
194
std::cout << std::endl;
128
195
0 commit comments