17 #ifndef __itkHistogramMatchingImageFilter_txx
18 #define __itkHistogramMatchingImageFilter_txx
23 #include "itkNumericTraits.h"
32 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
36 this->SetNumberOfRequiredInputs( 2 );
38 m_NumberOfHistogramLevels = 256;
39 m_NumberOfMatchPoints = 1;
41 m_QuantileTable.set_size( 3, m_NumberOfMatchPoints + 2 );
42 m_QuantileTable.fill(0);
43 m_Gradients.set_size( m_NumberOfMatchPoints + 1 );
46 m_ThresholdAtMeanIntensity =
true;
47 m_SourceIntensityThreshold = 0;
48 m_ReferenceIntensityThreshold = 0;
49 m_LowerGradient = 0.0;
50 m_UpperGradient = 0.0;
53 m_SourceHistogram = HistogramType::New();
54 m_ReferenceHistogram = HistogramType::New();
55 m_OutputHistogram = HistogramType::New();
62 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
67 Superclass::PrintSelf(os,indent);
69 os << indent <<
"NumberOfHistogramLevels: ";
70 os << m_NumberOfHistogramLevels << std::endl;
71 os << indent <<
"NumberOfMatchPoints: ";
72 os << m_NumberOfMatchPoints << std::endl;
73 os << indent <<
"ThresholdAtMeanIntensity: ";
74 os << m_ThresholdAtMeanIntensity << std::endl;
76 os << indent <<
"SourceIntensityThreshold: ";
77 os << m_SourceIntensityThreshold << std::endl;
78 os << indent <<
"ReferenceIntensityThreshold: ";
79 os << m_ReferenceIntensityThreshold << std::endl;
80 os << indent <<
"OutputIntensityThreshold: ";
81 os << m_ReferenceIntensityThreshold << std::endl;
82 os << indent <<
"Source histogram: ";
83 os << m_SourceHistogram.GetPointer() << std::endl;
84 os << indent <<
"Reference histogram: ";
85 os << m_ReferenceHistogram.GetPointer() << std::endl;
86 os << indent <<
"Output histogram: ";
87 os << m_OutputHistogram.GetPointer() << std::endl;
88 os << indent <<
"QuantileTable: " << std::endl;
89 os << m_QuantileTable << std::endl;
90 os << indent <<
"Gradients: " << std::endl;
91 os << m_Gradients << std::endl;
92 os << indent <<
"LowerGradient: ";
93 os << m_LowerGradient << std::endl;
94 os << indent <<
"UpperGradient: ";
95 os << m_UpperGradient << std::endl;
102 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
108 const_cast< InputImageType * >( reference ) );
115 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
121 if ( this->GetNumberOfInputs() < 2 )
126 return dynamic_cast<TInputImage*
>(
135 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
140 this->Superclass::GenerateInputRequestedRegion();
142 for (
unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx )
144 if ( this->GetInput(idx) )
148 image->SetRequestedRegionToLargestPossibleRegion();
157 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
167 this->ComputeMinMaxMean( source, m_SourceMinValue,
168 m_SourceMaxValue, m_SourceMeanValue );
169 this->ComputeMinMaxMean( reference, m_ReferenceMinValue,
170 m_ReferenceMaxValue, m_ReferenceMeanValue );
172 if ( m_ThresholdAtMeanIntensity )
174 m_SourceIntensityThreshold =
static_cast<InputPixelType>(m_SourceMeanValue);
175 m_ReferenceIntensityThreshold =
static_cast<InputPixelType>(m_ReferenceMeanValue);
179 m_SourceIntensityThreshold =
static_cast<InputPixelType>(m_SourceMinValue);
180 m_ReferenceIntensityThreshold =
static_cast<InputPixelType>(m_ReferenceMinValue);
183 this->ConstructHistogram( source, m_SourceHistogram,
184 m_SourceIntensityThreshold, m_SourceMaxValue );
185 this->ConstructHistogram( reference, m_ReferenceHistogram,
186 m_ReferenceIntensityThreshold,
187 m_ReferenceMaxValue );
190 m_QuantileTable.set_size( 3, m_NumberOfMatchPoints + 2 );
191 m_QuantileTable[0][0] = m_SourceIntensityThreshold;
192 m_QuantileTable[1][0] = m_ReferenceIntensityThreshold;
194 m_QuantileTable[0][m_NumberOfMatchPoints + 1] = m_SourceMaxValue;
195 m_QuantileTable[1][m_NumberOfMatchPoints + 1] = m_ReferenceMaxValue;
197 double delta = 1.0 / ( double(m_NumberOfMatchPoints) + 1.0 );
199 for ( j = 1; j < m_NumberOfMatchPoints + 1; j++ )
201 m_QuantileTable[0][j] = m_SourceHistogram->Quantile(
202 0,
double(j) * delta );
203 m_QuantileTable[1][j] = m_ReferenceHistogram->Quantile(
204 0,
double(j) * delta );
208 m_Gradients.set_size( m_NumberOfMatchPoints + 1 );
210 for ( j = 0; j < m_NumberOfMatchPoints + 1; j++ )
212 denominator = m_QuantileTable[0][j+1] -
213 m_QuantileTable[0][j];
214 if ( denominator != 0 )
216 m_Gradients[j] = m_QuantileTable[1][j+1] -
217 m_QuantileTable[1][j];
218 m_Gradients[j] /= denominator;
222 m_Gradients[j] = 0.0;
226 denominator = m_QuantileTable[0][0] - m_SourceMinValue;
227 if ( denominator != 0 )
229 m_LowerGradient = m_QuantileTable[1][0] - m_ReferenceMinValue;
230 m_LowerGradient /= denominator;
234 m_LowerGradient = 0.0;
237 denominator = m_QuantileTable[0][m_NumberOfMatchPoints+1] -
239 if ( denominator != 0 )
241 m_UpperGradient = m_QuantileTable[1][m_NumberOfMatchPoints+1] -
243 m_UpperGradient /= denominator;
247 m_UpperGradient = 0.0;
255 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
263 this->ComputeMinMaxMean( output, m_OutputMinValue,
264 m_OutputMaxValue, m_OutputMeanValue );
266 if ( m_ThresholdAtMeanIntensity )
268 m_OutputIntensityThreshold =
static_cast<OutputPixelType>(m_OutputMeanValue);
272 m_OutputIntensityThreshold =
static_cast<OutputPixelType>(m_OutputMinValue);
275 this->ConstructHistogram( output, m_OutputHistogram,
276 m_OutputIntensityThreshold, m_OutputMaxValue );
279 m_QuantileTable[2][0] = m_OutputIntensityThreshold;
281 m_QuantileTable[2][m_NumberOfMatchPoints + 1] = m_OutputMaxValue;
283 double delta = 1.0 / ( double(m_NumberOfMatchPoints) + 1.0 );
285 for (
unsigned int j = 1; j < m_NumberOfMatchPoints + 1; j++ )
287 m_QuantileTable[2][j] = m_OutputHistogram->Quantile(
288 0,
double(j) * delta );
296 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
315 InputConstIterator inIter( input, outputRegionForThread );
316 OutputIterator outIter( output, outputRegionForThread );
320 unsigned long updateVisits = 0;
321 unsigned long totalPixels = 0;
324 totalPixels = outputRegionForThread.GetNumberOfPixels();
325 updateVisits = totalPixels / 10;
326 if( updateVisits < 1 ) updateVisits = 1;
330 double srcValue, mappedValue;
332 for ( i = 0; !outIter.IsAtEnd(); ++inIter, ++outIter, i++ )
335 if ( threadId == 0 && !(i % updateVisits ) )
337 this->UpdateProgress((
float)i / (
float)totalPixels);
340 srcValue =
static_cast<double>( inIter.Get() );
342 for ( j = 0; j < m_NumberOfMatchPoints + 2; j++ )
344 if ( srcValue < m_QuantileTable[0][j] )
353 mappedValue = m_ReferenceMinValue +
354 ( srcValue - m_SourceMinValue ) * m_LowerGradient;
356 else if ( j == m_NumberOfMatchPoints + 2 )
359 mappedValue = m_ReferenceMaxValue +
360 ( srcValue - m_SourceMaxValue ) * m_UpperGradient;
365 mappedValue = m_QuantileTable[1][j-1] +
366 ( srcValue - m_QuantileTable[0][j-1] ) * m_Gradients[j-1];
369 outIter.Set( static_cast<OutputPixelType>( mappedValue ) );
379 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
384 THistogramMeasurement& minValue,
385 THistogramMeasurement& maxValue,
386 THistogramMeasurement& meanValue )
389 ConstIterator iter( image, image->GetBufferedRegion() );
394 minValue =
static_cast<THistogramMeasurement
>( iter.Get() );
397 while ( !iter.IsAtEnd() )
399 const THistogramMeasurement value =
static_cast<THistogramMeasurement
>( iter.Get() );
400 sum +=
static_cast<double>(value);
402 if ( value < minValue ) { minValue = value; }
403 if ( value > maxValue ) { maxValue = value; }
410 meanValue =
static_cast<THistogramMeasurement
>( sum /
static_cast<double>(count) );
417 template <
class TInputImage,
class TOutputImage,
class THistogramMeasurement>
423 const THistogramMeasurement minValue,
424 const THistogramMeasurement maxValue )
432 #ifdef ITK_USE_REVIEW_STATISTICS
434 lowerBound.SetSize(1);
435 upperBound.SetSize(1);
439 size[0] = m_NumberOfHistogramLevels;
440 lowerBound.
Fill(minValue);
441 upperBound.Fill(maxValue);
444 histogram->
Initialize( size , lowerBound, upperBound );
450 #ifdef ITK_USE_REVIEW_STATISTICS
451 measurement.SetSize(1);
460 ConstIterator iter( image, image->GetBufferedRegion() );
463 while ( !iter.IsAtEnd() )
467 if ( static_cast<double>(value) >= minValue &&
468 static_cast<double>(value) <= maxValue )
471 measurement[0] = value;