22 #ifndef __StreamingMultibandFeatherMosaicFilter_hxx
23 #define __StreamingMultibandFeatherMosaicFilter_hxx
26 #include "itkProgressReporter.h"
34 template <
class TInputImage,
class TOutputImage,
class TDistanceImage>
38 m_FirstLevelTransitionDistance = 3;
39 m_FirstLevelVariance = 1;
42 template <
class TInputImage,
class TOutputImage,
class TDistanceImage>
47 m_TransitionDistances.clear();
48 m_TransitionOffsets.clear();
52 m_SubImageFilter.clear();
54 m_SingleFilter.clear();
55 m_MosaicFilter.clear();
58 for (
unsigned int level = 0; level <= m_NumberOfLevels; level++)
61 m_TransitionDistances.push_back(distance);
65 for (
unsigned int level = 0; level <= m_NumberOfLevels; level++)
67 DistanceImageValueType offset = 0.5 * (m_TransitionDistances.at(m_NumberOfLevels) - m_TransitionDistances.at(level));
68 m_TransitionOffsets.push_back(offset);
82 for (
unsigned int level = 0; level <= m_NumberOfLevels; level++)
84 itkDebugMacro(
"Create mosaic filter for level " << level);
89 mosaicFilter->SetOutputOrigin(this->GetOutputOrigin());
90 mosaicFilter->SetOutputSize(this->GetOutputSize());
91 mosaicFilter->SetOutputSpacing(this->GetOutputSpacing());
92 mosaicFilter->SetAutomaticOutputParametersComputation(this->GetAutomaticOutputParametersComputation());
93 mosaicFilter->SetScaleMatrix(this->GetScaleMatrix());
95 mosaicFilter->SetShiftScaleInputImages(this->GetShiftScaleInputImages());
96 mosaicFilter->SetInterpolator(this->GetInterpolator());
97 mosaicFilter->SetNoDataOutputPixel(this->GetNoDataOutputPixel());
100 mosaicFilter->SetNoDataInputPixel(this->GetNoDataInputPixel());
103 mosaicFilter->SetFeatheringSmoothness(this->GetFeatheringSmoothness());
105 mosaicFilter->SetDistanceInterpolator(this->GetDistanceInterpolator());
110 if (level == m_NumberOfLevels)
113 mosaicFilter->SetShiftMatrix(this->GetShiftMatrix());
120 mosaicFilter->SetShiftMatrix(nullshifts);
122 m_MosaicFilter.push_back(mosaicFilter);
126 const unsigned int numberOfImages = 0.5 * (this->GetNumberOfInputs());
127 for (
unsigned int i = 0; i < numberOfImages; i++)
130 const unsigned int inputImageIndex = 2 * i;
131 const unsigned int inputDistanceImageIndex = 2 * i + 1;
133 itkDebugMacro(
"Create filters for image " << i);
135 std::vector<DiscreteGaussianFilterPointer> gaussianFilters;
136 std::vector<PerBandFilterPointer> gaussianFilterAdapters;
137 std::vector<SubImageFilterPointer> subImageFilters;
140 for (
unsigned int level = 0; level < m_NumberOfLevels; level++)
143 itkDebugMacro(
"\tLevel " << level);
146 const double shrinkFactor = std::pow(2.0, (
double)level);
148 const double variance = std::pow(0.5 * shrinkFactor, 2.0);
152 discreteGaussianFilter->SetVariance(variance);
153 discreteGaussianFilter->SetUseImageSpacingOff();
154 discreteGaussianFilter->SetReleaseDataFlag(
true);
155 gaussianFilters.push_back(discreteGaussianFilter);
159 gaussianFilterAdapter->SetFilter(discreteGaussianFilter);
160 gaussianFilterAdapter->SetInput(this->GetInput(inputImageIndex));
161 gaussianFilterAdapter->SetReleaseDataFlag(
true);
162 gaussianFilterAdapters.push_back(gaussianFilterAdapter);
169 subtractFilter->SetInput1(this->GetInput(inputImageIndex));
170 subtractFilter->SetInput2(gaussianFilterAdapters.at(level)->GetOutput());
175 subtractFilter->SetInput1(gaussianFilterAdapters.at(level - 1)->GetOutput());
176 subtractFilter->SetInput2(gaussianFilterAdapters.at(level)->GetOutput());
178 subImageFilters.push_back(subtractFilter);
181 m_MosaicFilter[level]->PushBackInputs(subtractFilter->GetOutput(),
182 static_cast<const DistanceImageType*
>(Superclass::ProcessObject::GetInput(inputDistanceImageIndex)));
184 m_SingleFilter.push_back(gaussianFilters);
185 m_Filter.push_back(gaussianFilterAdapters);
186 m_SubImageFilter.push_back(subImageFilters);
189 itkDebugMacro(
"m_Filter size = " << m_Filter.size() <<
" / i = " << i);
190 m_MosaicFilter[m_NumberOfLevels]->PushBackInputs(m_Filter.at(i).at(m_NumberOfLevels - 1)->GetOutput(),
191 static_cast<const DistanceImageType*
>(Superclass::ProcessObject::GetInput(inputDistanceImageIndex)));
200 const double maximumSpacingInXY = std::max(std::abs(this->GetOutputSpacing()[0]), std::abs(this->GetOutputSpacing()[1]));
201 const double extrapolationOffset = ((double)m_SingleFilter.at(0).at(m_NumberOfLevels - 1)->GetMaximumKernelWidth()) * maximumSpacingInXY;
202 itkDebugMacro(<<
"Extrapolation offset: " << extrapolationOffset);
205 itkDebugMacro(
"Level\tDist\tOffset");
206 for (
unsigned int level = 0; level <= m_NumberOfLevels; level++)
208 const double offset = extrapolationOffset + m_TransitionOffsets.at(level);
209 m_MosaicFilter.at(level)->SetDistanceOffset(offset);
210 m_MosaicFilter.at(level)->SetFeatheringTransitionDistance(m_TransitionDistances.at(level));
211 itkDebugMacro(<< level <<
"\t" << m_TransitionDistances.at(level) <<
"\t" << offset);
215 m_SummingFilter = SummingFilterType::New();
216 for (
unsigned int level = 0; level <= m_NumberOfLevels; level++)
219 m_SummingFilter->PushBackInput(m_MosaicFilter.at(level)->GetOutput());
221 m_SummingFilter->SetReleaseDataFlag(
true);
227 template <
class TInputImage,
class TOutputImage,
class TDistanceImage>
230 itkDebugMacro(
"Generate data on region " << this->GetOutput()->GetRequestedRegion());
232 m_SummingFilter->GraftOutput(this->GetOutput());
233 m_SummingFilter->Update();
234 this->GraftOutput(m_SummingFilter->GetOutput());
236 itkDebugMacro(
"Generate data OK");