22 #ifndef __StreamingMosaicFilterBase_hxx
23 #define __StreamingMosaicFilterBase_hxx
30 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
34 m_OutputSpacing.Fill(0);
35 m_OutputOrigin.Fill(0);
37 m_ShiftScaleInputImages =
false;
38 m_AutomaticOutputParametersComputation =
true;
39 Superclass::SetCoordinateTolerance(itk::NumericTraits<double>::max());
40 Superclass::SetDirectionTolerance(itk::NumericTraits<double>::max());
41 interpolatorRadius = 0;
48 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
56 for (
unsigned int dim = 0; dim < OutputImageType::ImageDimension; ++dim)
58 imageLastIndex[dim] = image->GetLargestPossibleRegion().GetSize()[dim];
64 image->TransformIndexToPhysicalPoint(imageLastIndex, imageEnd);
65 for (
unsigned int dim = 0; dim < OutputImageType::ImageDimension; ++dim)
67 extentInf[dim] = vnl_math_min(imageOrigin[dim], imageEnd[dim]);
68 extentSup[dim] = vnl_math_max(imageOrigin[dim], imageEnd[dim]);
79 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
91 this->GetOutput()->TransformIndexToPhysicalPoint(outIndexStart, outPointStart);
92 this->GetOutput()->TransformIndexToPhysicalPoint(outIndexEnd, outPointEnd);
96 inputImage->TransformPhysicalPointToIndex(outPointStart, defIndexStart);
97 inputImage->TransformPhysicalPointToIndex(outPointEnd, defIndexEnd);
102 for (
unsigned int dim = 0; dim < OutputImageType::ImageDimension; ++dim)
104 defRequestedIndex[dim] = vnl_math_min(defIndexStart[dim], defIndexEnd[dim]);
105 defRequestedSize[dim] = vnl_math_max(defIndexStart[dim], defIndexEnd[dim]) - defRequestedIndex[dim] + 1;
110 computedInputRegion.PadByRadius(1);
113 computedInputRegion.PadByRadius(interpolatorRadius);
115 inputRegion = computedInputRegion;
118 return inputRegion.Crop(inputImage->GetLargestPossibleRegion());
121 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
133 if (OutputRegionToInputRegion(outRegion, inRegion, inputTile))
137 itkDebugMacro(<<
"Image #" << inputImageIndex <<
"\n" << inRegion <<
" is inside the requested region");
138 AddUsedInputImageIndex(inputImageIndex);
143 itkDebugMacro(<<
"Image #" << inputImageIndex <<
"\n" << inRegion <<
" is outside the requested region");
144 inRegion.GetModifiableSize().Fill(0);
145 inRegion.GetModifiableIndex().Fill(0);
147 inputTile->SetRequestedRegion(inRegion);
153 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
156 usedInputIndices.clear();
159 for (
unsigned int i = 0; i < this->GetNumberOfInputs(); ++i)
161 ComputeRequestedRegionOfInputImage(i);
166 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
170 const unsigned int numberOfInputImages = this->GetNumberOfInputImages();
173 if (m_ShiftScaleInputImages)
175 if (m_ShiftMatrix.rows() == 0)
177 m_ShiftMatrix.set_size(numberOfInputImages, nbOfBands);
178 m_ShiftMatrix.fill(itk::NumericTraits<InternalValueType>::Zero);
180 if (m_ScaleMatrix.rows() == 0)
182 m_ScaleMatrix.set_size(numberOfInputImages, nbOfBands);
183 m_ScaleMatrix.fill(itk::NumericTraits<InternalValueType>::One);
185 if (m_ShiftMatrix.cols() != nbOfBands || m_ScaleMatrix.cols() != nbOfBands)
187 itkWarningMacro(<<
"Shift-Scale matrices should have " << nbOfBands <<
" cols (1 col/band)"
188 <<
" instead of " << m_ShiftMatrix.cols());
190 if (m_ShiftMatrix.rows() != numberOfInputImages || m_ScaleMatrix.rows() != numberOfInputImages)
192 itkWarningMacro(<<
"Shift-Scale matrices must have " << numberOfInputImages <<
" rows (1 row/input image)"
193 <<
" instead of " << m_ShiftMatrix.rows());
205 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
208 itkDebugMacro(<<
"Computing output parameters of the mosaic image");
212 m_OutputSpacing.Fill(itk::NumericTraits<double>::max());
213 extentInf.Fill(itk::NumericTraits<double>::max());
214 extentSup.Fill(itk::NumericTraits<double>::NonpositiveMin());
217 for (
unsigned int imageIndex = 0; imageIndex < this->GetNumberOfInputs(); imageIndex++)
224 for (
unsigned int dim = 0; dim < OutputImageType::ImageDimension; ++dim)
226 if (vcl_abs(currentImage->GetSignedSpacing()[dim]) < vcl_abs(m_OutputSpacing[dim]))
228 m_OutputSpacing[dim] = currentImage->GetSignedSpacing()[dim];
234 ImageToExtent(currentImage, currentInputImageExtentInf, currentInputImageExtentSup);
235 for (
unsigned int dim = 0; dim < OutputImageType::ImageDimension; ++dim)
237 extentInf[dim] = vnl_math_min(currentInputImageExtentInf[dim], extentInf[dim]);
238 extentSup[dim] = vnl_math_max(currentInputImageExtentSup[dim], extentSup[dim]);
243 m_OutputSize[0] = std::round((extentSup[0] - extentInf[0]) / vcl_abs(m_OutputSpacing[0]));
244 m_OutputSize[1] = std::round((extentSup[1] - extentInf[1]) / vcl_abs(m_OutputSpacing[1]));
247 m_OutputOrigin[0] = extentInf[0];
248 m_OutputOrigin[1] = extentSup[1];
256 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
259 itkDebugMacro(<<
"Generate output information");
260 Superclass::GenerateOutputInformation();
266 itkDebugMacro(<<
"No interpolator specified. Using default");
267 typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New();
272 interpolatorRadius = StreamingTraitsType::CalculateNeededRadiusForInterpolator(m_Interpolator);
275 if (m_AutomaticOutputParametersComputation)
277 ComputeOutputParameters();
284 std::string projectionRef =
"";
285 for (
unsigned int imageIndex = 0; imageIndex < this->GetNumberOfInputs(); imageIndex++)
287 itkDebugMacro(<<
"Input image #" << imageIndex);
293 itkDebugMacro(<<
"\tSize : " << currentImage->GetLargestPossibleRegion().GetSize());
294 itkDebugMacro(<<
"\tSpacing: " << currentImage->GetSignedSpacing());
295 itkDebugMacro(<<
"\tOrigin : " << currentImage->GetOrigin());
298 nbOfBands = vnl_math_max(nbOfBands, currentImage->GetNumberOfComponentsPerPixel());
301 itk::MetaDataDictionary metaData = currentImage->GetMetaDataDictionary();
302 std::string currentProjectionRef;
308 if (projectionRef.size() != 0)
310 if (currentProjectionRef.size() != 0)
312 if (currentProjectionRef.compare(projectionRef) != 0)
314 itkWarningMacro(<<
"Input images may have not the same projection");
319 projectionRef = currentProjectionRef;
321 itk::MetaDataDictionary mosaicMetaData;
325 if (m_NoDataInputPixel.GetSize() != nbOfBands)
327 if (m_NoDataInputPixel.GetSize() != 0)
328 itkWarningMacro(<<
"Specified NoDataInputPixel has not " << nbOfBands <<
" components. Using default (zeros)");
330 m_NoDataInputPixel.SetSize(nbOfBands);
331 m_NoDataInputPixel.Fill(itk::NumericTraits<InputImageInternalPixelType>::Zero);
333 if (m_NoDataOutputPixel.GetSize() == 0)
335 itkDebugMacro(<<
"NoDataOutputPixel not set. Using zeros");
336 m_NoDataOutputPixel.SetSize(nbOfBands);
337 m_NoDataOutputPixel.Fill(itk::NumericTraits<InputImageInternalPixelType>::Zero);
342 std::vector<bool> noDataValueAvailable;
343 std::vector<double> noDataValues1;
344 for (
unsigned int band = 0; band < nbOfBands; band++)
346 noDataValueAvailable.push_back(
true);
347 noDataValues1.push_back(
static_cast<double>(m_NoDataOutputPixel[band]));
352 minOutputPixelValue =
static_cast<InternalValueType>(itk::NumericTraits<OutputImageInternalPixelType>::NonpositiveMin());
353 maxOutputPixelValue =
static_cast<InternalValueType>(itk::NumericTraits<OutputImageInternalPixelType>::max());
357 outputRegionStart.Fill(0);
360 outputPtr->SetOrigin(m_OutputOrigin);
361 outputPtr->SetSignedSpacing(m_OutputSpacing);
362 outputPtr->SetNumberOfComponentsPerPixel(nbOfBands);
363 outputPtr->SetLargestPossibleRegion(outputRegion);
365 itkDebugMacro(<<
"Output mosaic parameters:"
366 <<
"\n\tBands : " << nbOfBands <<
"\n\tOrigin : " << m_OutputOrigin <<
"\n\tSize : " << m_OutputSize <<
"\n\tSpacing: " << m_OutputSpacing);
369 if (m_ShiftScaleInputImages)
371 CheckShiftScaleMatrices();
378 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
381 bool isDataInCurrentInputPixel =
false;
383 for (
unsigned int band = 0; band < nbOfBands; band++)
385 isDataInCurrentInputPixel = isDataInCurrentInputPixel || (pixelValue[band] != m_NoDataInputPixel[band]);
387 return isDataInCurrentInputPixel;
393 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
396 if (pixelValue < minOutputPixelValue)
397 pixelValue = minOutputPixelValue;
398 if (pixelValue > maxOutputPixelValue)
399 pixelValue = maxOutputPixelValue;
407 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
412 itkExceptionMacro(<<
"Interpolator not set");
420 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
424 m_Interpolator->SetInputImage(NULL);
427 template <
class TInputImage,
class TOutputImage,
class TInternalValueType>
429 typename std::vector<InputImageType*>& image,
typename std::vector<InterpolatorPointerType>& interpolator)
433 const unsigned int n = GetNumberOfUsedInputImages();
435 interpolator.reserve(n);
439 for (
unsigned int i = 0; i < n; i++)
442 image.push_back(
const_cast<InputImageType*
>(this->GetInput(usedInputIndices.at(i))));
445 interpolator.push_back(
static_cast<InterpolatorType*
>((m_Interpolator->CreateAnother()).GetPointer()));
446 interpolator[i]->SetInputImage(image[i]);