17 #ifndef __itkBilateralImageFilter_txx
18 #define __itkBilateralImageFilter_txx
31 template<
class TInputImage,
class TOutputImage >
39 template <
class TInputImage,
class TOutputImage>
46 Superclass::GenerateInputRequestedRegion();
50 const_cast< TInputImage *
>( this->GetInput() );
58 typename TInputImage::SizeType radius;
61 if (m_AutomaticKernelSize)
63 for (i = 0; i < ImageDimension; i++)
66 (
typename TInputImage::SizeType::SizeValueType)
67 vcl_ceil(m_DomainMu*m_DomainSigma[i]/this->GetInput()->GetSpacing()[i]);
72 for (i = 0; i < ImageDimension; i++)
74 radius[i] = m_Radius[i];
80 typename TInputImage::RegionType inputRequestedRegion;
81 inputRequestedRegion = inputPtr->GetRequestedRegion();
84 inputRequestedRegion.PadByRadius( radius );
87 if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
89 inputPtr->SetRequestedRegion( inputRequestedRegion );
98 inputPtr->SetRequestedRegion( inputRequestedRegion );
101 InvalidRequestedRegionError e(__FILE__, __LINE__);
103 e.
SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
109 template<
class TInputImage,
class TOutputImage >
118 typename InputImageType::SizeType radius;
119 typename InputImageType::SizeType domainKernelSize;
123 const typename InputImageType::SpacingType inputSpacing = inputImage->GetSpacing();
124 const typename InputImageType::PointType inputOrigin = inputImage->GetOrigin();
126 if (m_AutomaticKernelSize)
128 for (i = 0; i < ImageDimension; i++)
131 (
typename TInputImage::SizeType::SizeValueType)
132 vcl_ceil(m_DomainMu * m_DomainSigma[i] / inputSpacing[i] );
133 domainKernelSize[i] = 2 * radius[i] + 1;
138 for (i = 0; i < ImageDimension; i++)
140 radius[i] = m_Radius[i];
141 domainKernelSize[i] = 2 * radius[i] + 1;
150 gaussianImage->SetSize( domainKernelSize.GetSize() );
151 gaussianImage->SetSpacing( inputSpacing );
152 gaussianImage->SetOrigin( inputOrigin );
153 gaussianImage->SetScale( 1.0 );
154 gaussianImage->SetNormalized(
true );
156 for (i=0; i < ImageDimension; i++)
158 mean[i] = inputSpacing[i] * radius[i] + inputOrigin[i];
159 sigma[i] = m_DomainSigma[i];
161 gaussianImage->SetSigma( sigma );
162 gaussianImage->SetMean( mean );
164 gaussianImage->Update();
167 m_GaussianKernel.SetRadius(radius);
172 gaussianImage->GetOutput()
173 ->GetBufferedRegion() );
182 *kernel_it = git.
Get() / norm;
193 statistics->SetInput( inputImage );
194 statistics->GetOutput()
195 ->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() );
196 statistics->Update();
202 double rangeVariance = m_RangeSigma * m_RangeSigma;
205 double rangeGaussianDenom;
206 rangeGaussianDenom = m_RangeSigma*vcl_sqrt(2.0*vnl_math::pi);
212 m_DynamicRange = (
static_cast<double>(statistics->GetMaximum())
213 - static_cast<double>(statistics->GetMinimum()));
215 m_DynamicRangeUsed = m_RangeMu * m_RangeSigma;
217 tableDelta = m_DynamicRangeUsed
218 /
static_cast<double>(m_NumberOfRangeGaussianSamples);
221 m_RangeGaussianTable.resize( m_NumberOfRangeGaussianSamples );
222 for (i = 0, v = 0.0; i < m_NumberOfRangeGaussianSamples;
223 ++i, v += tableDelta)
225 m_RangeGaussianTable[i] = vcl_exp(-0.5*v*v/rangeVariance)/rangeGaussianDenom;
230 template<
class TInputImage,
class TOutputImage >
236 typename TInputImage::ConstPointer input = this->GetInput();
237 typename TOutputImage::Pointer output = this->GetOutput();
239 const double rangeDistanceThreshold = m_DynamicRangeUsed;
252 faceList = fC(this->GetInput(), outputRegionForThread,
253 m_GaussianKernel.GetRadius());
259 rangeDistance, pixel, gaussianProduct;
261 const double distanceToTableIndex
262 =
static_cast<double>(m_NumberOfRangeGaussianSamples)/m_DynamicRangeUsed;
273 ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
275 for (fit = faceList.begin(); fit != faceList.end(); ++fit)
279 this->GetInput(), *fit);
291 for (i=0, k_it = m_GaussianKernel.Begin(); k_it < kernelEnd;
296 rangeDistance = pixel - centerPixel;
298 if (rangeDistance < 0.0)
300 rangeDistance *= -1.0;
304 if (rangeDistance < rangeDistanceThreshold)
307 tableArg = rangeDistance * distanceToTableIndex;
308 rangeGaussian = m_RangeGaussianTable[Math::Floor<size_t>(tableArg)];
312 gaussianProduct = (*k_it) * rangeGaussian;
313 normFactor += gaussianProduct;
316 val += pixel * gaussianProduct;
323 o_iter.
Set( static_cast<OutputPixelType>(val) );
327 progress.CompletedPixel();
333 template<
class TInputImage,
class TOutputImage >
338 Superclass::PrintSelf(os,indent);
340 os << indent <<
"DomainSigma: " << m_DomainSigma << std::endl;
341 os << indent <<
"RangeSigma: " << m_RangeSigma << std::endl;
342 os << indent <<
"FilterDimensionality: " << m_FilterDimensionality << std::endl;
343 os << indent <<
"NumberOfRangeGaussianSamples: " << m_NumberOfRangeGaussianSamples << std::endl;
344 os << indent <<
"Input dynamic range: " << m_DynamicRange << std::endl;
345 os << indent <<
"Amount of dynamic range used: " << m_DynamicRangeUsed << std::endl;
346 os << indent <<
"AutomaticKernelSize: " << m_AutomaticKernelSize << std::endl;
347 os << indent <<
"Radius: " << m_Radius << std::endl;