23 #ifndef otbWaveletFilterBank_hxx
24 #define otbWaveletFilterBank_hxx
30 #include "itkPeriodicBoundaryCondition.h"
39 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
42 this->DynamicMultiThreadingOff();
43 this->SetNumberOfRequiredInputs(1);
44 this->SetNumberOfRequiredInputs(1);
46 unsigned int numOfOutputs = 1 << InputImageDimension;
48 this->SetNumberOfRequiredOutputs(numOfOutputs);
49 for (
unsigned int i = 0; i < numOfOutputs; ++i)
51 this->SetNthOutput(i, OutputImageType::New());
54 m_UpSampleFilterFactor = 0;
55 m_SubsampleImageFactor = 1;
58 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
61 Superclass::GenerateOutputInformation();
63 if (GetSubsampleImageFactor() == 1)
67 otbGenericMsgDebugMacro(<<
"initial region " << this->GetInput()->GetLargestPossibleRegion().GetSize()[0] <<
","
68 << this->GetInput()->GetLargestPossibleRegion().GetSize()[1]);
71 this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput()->GetLargestPossibleRegion());
73 for (
unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
75 this->GetOutput(i)->SetRegions(newRegion);
81 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
84 Superclass::GenerateInputRequestedRegion();
88 lowPassOperator.SetDirection(0);
89 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
90 lowPassOperator.CreateDirectional();
92 unsigned int radius = lowPassOperator.GetRadius()[0];
95 highPassOperator.SetDirection(0);
96 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
97 highPassOperator.CreateDirectional();
99 if (radius < highPassOperator.GetRadius()[0])
100 radius = highPassOperator.GetRadius()[0];
105 inputRegion.PadByRadius(radius);
107 if (inputRegion.Crop(input->GetLargestPossibleRegion()))
109 input->SetRequestedRegion(inputRegion);
113 input->SetRequestedRegion(inputRegion);
114 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
115 err.SetLocation(ITK_LOCATION);
116 err.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
117 err.SetDataObject(input);
122 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
126 unsigned int one = 1;
127 if (m_SubsampleImageFactor > 1)
130 for (
unsigned int i = 0; i < InputImageDimension; ++i)
132 if ((m_SubsampleImageFactor * (this->GetInput()->GetRequestedRegion().GetSize()[i] / m_SubsampleImageFactor)) !=
133 this->GetInput()->GetRequestedRegion().GetSize()[i])
135 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
136 err.SetLocation(ITK_LOCATION);
137 err.SetDescription(
"Requested region dimension cannot be used in multiresolution analysis (crop it).");
143 if (InputImageDimension > 1)
146 m_InternalImages.resize(InputImageDimension - 1);
147 for (
unsigned int i = 0; i < m_InternalImages.size(); ++i)
150 m_InternalImages[InputImageDimension - 2 - i].resize(one << (i + 1));
154 this->Superclass::CallCopyInputRegionToOutputRegion(intermediateRegion, this->GetInput()->GetLargestPossibleRegion());
156 AllocateInternalData(intermediateRegion);
161 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
167 for (
unsigned int direction = 0; direction < InputImageDimension - 1; direction++)
169 this->CallCopyInputRegionToOutputRegion(InputImageDimension - 1 - direction, smallerRegion, largerRegion);
171 const unsigned int d = InputImageDimension - 2 - direction;
172 for (
unsigned int i = 0; i < m_InternalImages[d].size(); ++i)
174 m_InternalImages[d][i] = OutputImageType::New();
175 m_InternalImages[d][i]->SetRegions(smallerRegion);
176 m_InternalImages[d][i]->Allocate();
177 m_InternalImages[d][i]->FillBuffer(0);
180 largerRegion = smallerRegion;
184 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
187 if (m_SubsampleImageFactor > 1 && InputImageDimension > 1)
189 m_InternalImages.clear();
193 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
197 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
199 if (GetSubsampleImageFactor() > 1)
207 for (
unsigned int i = 0; i < InputImageDimension; ++i)
209 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
210 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
213 destRegion.SetIndex(destIndex);
214 destRegion.SetSize(destSize);
221 lowPassOperator.SetDirection(0);
222 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
223 lowPassOperator.CreateDirectional();
225 unsigned long radius[InputImageDimension];
226 radius[0] = lowPassOperator.GetRadius()[0];
229 highPassOperator.SetDirection(0);
230 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
231 highPassOperator.CreateDirectional();
233 if (radius[0] < highPassOperator.GetRadius()[0]) radius[0] = highPassOperator.GetRadius()[0];
235 for (
unsigned int i = 1; i < InputImageDimension; ++i)
239 paddedRegion.PadByRadius(radius);
241 if (paddedRegion.Crop(this->GetInput()->GetLargestPossibleRegion()))
243 destRegion = paddedRegion;
249 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
254 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
256 if (GetSubsampleImageFactor() > 1)
264 for (
unsigned int i = 0; i < InputImageDimension; ++i)
268 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
269 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
273 destIndex[i] = srcIndex[i];
274 destSize[i] = srcSize[i];
278 destRegion.SetIndex(destIndex);
279 destRegion.SetSize(destSize);
283 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
287 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
289 if (GetSubsampleImageFactor() > 1)
291 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
292 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
294 typename OutputImageRegionType::IndexType destIndex;
295 typename OutputImageRegionType::SizeType destSize;
297 for (
unsigned int i = 0; i < InputImageDimension; ++i)
300 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
301 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
304 destRegion.SetIndex(destIndex);
305 destRegion.SetSize(destSize);
309 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
314 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
316 if (GetSubsampleImageFactor() > 1)
318 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
319 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
321 typename OutputImageRegionType::IndexType destIndex;
322 typename OutputImageRegionType::SizeType destSize;
324 for (
unsigned int i = 0; i < InputImageDimension; ++i)
329 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
330 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
334 destIndex[i] = srcIndex[i];
335 destSize[i] = srcSize[i];
339 destRegion.SetIndex(destIndex);
340 destRegion.SetSize(destSize);
344 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
346 itk::ThreadIdType threadId)
348 unsigned int dir = InputImageDimension - 1;
350 itk::ProgressReporter reporter(
this, threadId, outputRegionForThread.GetNumberOfPixels() * this->GetNumberOfInputs());
352 if ((1 << dir) >=
static_cast<int>(this->GetNumberOfOutputs()))
354 std::ostringstream msg;
355 msg <<
"Output number 1<<" << dir <<
" = " << (1 << dir) <<
" not allocated\n";
356 msg <<
"Number of expected outputs " << this->GetNumberOfOutputs() <<
"\n";
357 throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
362 this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
368 if (dir != 0 && m_SubsampleImageFactor > 1)
370 outputLowPass = m_InternalImages[dir - 1][0];
371 outputHighPass = m_InternalImages[dir - 1][1];
375 typedef itk::ConstNeighborhoodIterator<InputImageType> NeighborhoodIteratorType;
376 typedef itk::NeighborhoodInnerProduct<InputImageType> InnerProductType;
377 typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
381 typename SubsampleIteratorType::IndexType subsampling;
383 subsampling[dir] = GetSubsampleImageFactor();
386 InnerProductType innerProduct;
390 highPassOperator.SetDirection(dir);
391 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
392 highPassOperator.CreateDirectional();
394 SubsampleIteratorType subItHighPass(input, inputRegionForThread);
395 subItHighPass.SetSubsampleFactor(subsampling);
396 subItHighPass.GoToBegin();
398 NeighborhoodIteratorType itHighPass(highPassOperator.GetRadius(), input, inputRegionForThread);
399 itk::PeriodicBoundaryCondition<InputImageType> boundaryCondition;
400 itHighPass.OverrideBoundaryCondition(&boundaryCondition);
402 IteratorType outHighPass(outputHighPass, subItHighPass.GenerateOutputInformation());
403 outHighPass.GoToBegin();
405 while (!subItHighPass.IsAtEnd() && !outHighPass.IsAtEnd())
407 itHighPass.SetLocation(subItHighPass.GetIndex());
408 outHighPass.Set(innerProduct(itHighPass, highPassOperator));
413 reporter.CompletedPixel();
418 lowPassOperator.SetDirection(dir);
419 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
420 lowPassOperator.CreateDirectional();
422 SubsampleIteratorType subItLowPass(input, inputRegionForThread);
423 subItLowPass.SetSubsampleFactor(subsampling);
424 subItLowPass.GoToBegin();
426 NeighborhoodIteratorType itLowPass(lowPassOperator.GetRadius(), input, inputRegionForThread);
427 itLowPass.OverrideBoundaryCondition(&boundaryCondition);
429 IteratorType outLowPass(outputLowPass, subItLowPass.GenerateOutputInformation());
430 outLowPass.GoToBegin();
432 while (!subItLowPass.IsAtEnd() && !outLowPass.IsAtEnd())
434 itLowPass.SetLocation(subItLowPass.GetIndex());
435 outLowPass.Set(innerProduct(itLowPass, lowPassOperator));
440 reporter.CompletedPixel();
447 this->CallCopyInputRegionToOutputRegion(dir, outputImageRegion, inputRegionForThread);
449 ThreadedGenerateDataAtDimensionN(0, dir - 1, reporter, outputImageRegion, threadId);
450 ThreadedGenerateDataAtDimensionN(1 << dir, dir - 1, reporter, outputImageRegion, threadId);
454 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
456 unsigned int idx,
unsigned int direction, itk::ProgressReporter& reporter,
const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
464 this->CallCopyInputRegionToOutputRegion(direction, outputImageRegion, outputRegionForThread);
466 if (m_SubsampleImageFactor > 1)
468 input = m_InternalImages[direction][idx / (1 << (direction + 1))];
472 outputLowPass = m_InternalImages[direction - 1][idx / (1 << direction)];
473 outputHighPass = m_InternalImages[direction - 1][idx / (1 << direction) + 1];
481 outputLowPass->SetRegions(outputImageRegion);
482 outputLowPass->Allocate();
483 outputLowPass->FillBuffer(0);
487 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
488 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
489 typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
493 typename SubsampleIteratorType::IndexType subsampling;
495 subsampling[direction] = GetSubsampleImageFactor();
498 InnerProductType innerProduct;
502 highPassOperator.SetDirection(direction);
503 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
504 highPassOperator.CreateDirectional();
506 SubsampleIteratorType subItHighPass(input, outputRegionForThread);
507 subItHighPass.SetSubsampleFactor(subsampling);
508 subItHighPass.GoToBegin();
510 NeighborhoodIteratorType itHighPass(highPassOperator.GetRadius(), input, outputRegionForThread);
511 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
512 itHighPass.OverrideBoundaryCondition(&boundaryCondition);
514 IteratorType outHighPass(outputHighPass, subItHighPass.GenerateOutputInformation());
515 outHighPass.GoToBegin();
517 while (!subItHighPass.IsAtEnd() && !outHighPass.IsAtEnd())
519 itHighPass.SetLocation(subItHighPass.GetIndex());
520 outHighPass.Set(innerProduct(itHighPass, highPassOperator));
525 reporter.CompletedPixel();
530 lowPassOperator.SetDirection(direction);
531 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
532 lowPassOperator.CreateDirectional();
534 SubsampleIteratorType subItLowPass(input, outputRegionForThread);
535 subItLowPass.SetSubsampleFactor(subsampling);
536 subItLowPass.GoToBegin();
538 NeighborhoodIteratorType itLowPass(lowPassOperator.GetRadius(), input, outputRegionForThread);
539 itLowPass.OverrideBoundaryCondition(&boundaryCondition);
541 IteratorType outLowPass(outputLowPass, subItLowPass.GenerateOutputInformation());
542 outLowPass.GoToBegin();
544 while (!subItLowPass.IsAtEnd() && !outLowPass.IsAtEnd())
546 itLowPass.SetLocation(subItLowPass.GetIndex());
547 outLowPass.Set(innerProduct(itLowPass, lowPassOperator));
552 reporter.CompletedPixel();
556 itk::ImageRegionConstIterator<OutputImageType> inIt(outputLowPass, outputImageRegion);
557 IteratorType outIt((direction != 0 && m_SubsampleImageFactor > 1)
558 ?
static_cast<OutputImageType*
>(m_InternalImages[direction - 2][idx / (1 << (direction - 1))])
559 : this->GetOutput(idx),
562 for (inIt.GoToBegin(), outIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt, ++outIt)
564 outIt.Set(inIt.Get());
569 ThreadedGenerateDataAtDimensionN(idx, direction - 1, reporter, outputImageRegion, threadId);
570 ThreadedGenerateDataAtDimensionN(idx + (1 << direction), direction - 1, reporter, outputImageRegion, threadId);
578 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
581 this->DynamicMultiThreadingOff();
582 this->SetNumberOfRequiredInputs(1 << InputImageDimension);
584 m_UpSampleFilterFactor = 0;
585 m_SubsampleImageFactor = 1;
589 this->SetNumberOfWorkUnits(1);
592 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
595 Superclass::GenerateOutputInformation();
597 for (
unsigned int i = 1; i < this->GetNumberOfInputs(); ++i)
599 for (
unsigned int dim = 0; dim < InputImageDimension; dim++)
601 if (this->GetInput(0)->GetLargestPossibleRegion().GetSize()[dim] != this->GetInput(i)->GetLargestPossibleRegion().GetSize()[dim])
603 throw itk::ExceptionObject(__FILE__, __LINE__,
"Input images are not of the same dimension", ITK_LOCATION);
610 otbGenericMsgDebugMacro(<<
"initial region " << this->GetInput(0)->GetLargestPossibleRegion().GetSize()[0] <<
","
611 << this->GetInput(0)->GetLargestPossibleRegion().GetSize()[1]);
614 this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput(0)->GetLargestPossibleRegion());
615 this->GetOutput()->SetRegions(newRegion);
620 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
623 Superclass::GenerateInputRequestedRegion();
627 lowPassOperator.SetDirection(0);
628 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
629 lowPassOperator.CreateDirectional();
631 unsigned int radius = lowPassOperator.GetRadius()[0];
634 highPassOperator.SetDirection(0);
635 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
636 highPassOperator.CreateDirectional();
638 if (radius < highPassOperator.GetRadius()[0])
639 radius = highPassOperator.GetRadius()[0];
642 for (
unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
646 inputRegion.PadByRadius(radius);
648 if (inputRegion.Crop(input->GetLargestPossibleRegion()))
650 input->SetRequestedRegion(inputRegion);
654 input->SetRequestedRegion(inputRegion);
655 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
656 err.SetLocation(ITK_LOCATION);
657 err.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
658 err.SetDataObject(input);
664 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
667 unsigned int one = 1;
668 if (InputImageDimension > 1)
671 m_InternalImages.resize(InputImageDimension - 1);
672 for (
unsigned int i = 0; i < m_InternalImages.size(); ++i)
675 m_InternalImages[i].resize(one << (i + 1));
679 Superclass::CallCopyInputRegionToOutputRegion(intermediateRegion, this->GetInput(0)->GetLargestPossibleRegion());
681 AllocateInternalData(intermediateRegion);
685 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
691 for (
unsigned int direction = 0; direction < InputImageDimension - 1; direction++)
693 this->CallCopyInputRegionToOutputRegion(direction, largerRegion, smallerRegion);
695 for (
unsigned int i = 0; i < m_InternalImages[direction].size(); ++i)
697 m_InternalImages[direction][i] = OutputImageType::New();
698 m_InternalImages[direction][i]->SetRegions(largerRegion);
699 m_InternalImages[direction][i]->Allocate();
700 m_InternalImages[direction][i]->FillBuffer(0);
703 smallerRegion = largerRegion;
707 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
710 if (m_SubsampleImageFactor > 1 && InputImageDimension > 1)
712 m_InternalImages.clear();
716 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
720 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
722 if (GetSubsampleImageFactor() > 1)
730 for (
unsigned int i = 0; i < InputImageDimension; ++i)
733 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
734 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
737 destRegion.SetIndex(destIndex);
738 destRegion.SetSize(destSize);
743 lowPassOperator.SetDirection(0);
744 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
745 lowPassOperator.CreateDirectional();
747 typename InputImageRegionType::SizeType radius;
748 radius[0] = lowPassOperator.GetRadius()[0];
751 highPassOperator.SetDirection(0);
752 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
753 highPassOperator.CreateDirectional();
755 if (radius[0] < highPassOperator.GetRadius()[0])
756 radius[0] = highPassOperator.GetRadius()[0];
758 for (
unsigned int i = 1; i < InputImageDimension; ++i)
769 paddedRegion.PadByRadius(radius);
771 if (paddedRegion.Crop(this->GetInput(0)->GetLargestPossibleRegion()))
773 destRegion = paddedRegion;
779 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
783 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
785 if (GetSubsampleImageFactor() > 1)
793 for (
unsigned int i = 0; i < InputImageDimension; ++i)
795 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
796 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
799 destRegion.SetIndex(destIndex);
800 destRegion.SetSize(destSize);
804 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
809 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
811 if (GetSubsampleImageFactor() > 1)
819 for (
unsigned int i = 0; i < InputImageDimension; ++i)
824 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
825 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
829 destIndex[i] = srcIndex[i];
830 destSize[i] = srcSize[i];
834 destRegion.SetIndex(destIndex);
835 destRegion.SetSize(destSize);
839 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
844 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
846 if (GetSubsampleImageFactor() > 1)
848 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
849 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
851 typename OutputImageRegionType::IndexType destIndex;
852 typename OutputImageRegionType::SizeType destSize;
854 for (
unsigned int i = 0; i < InputImageDimension; ++i)
858 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
859 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
863 destIndex[i] = srcIndex[i];
864 destSize[i] = srcSize[i];
868 destRegion.SetIndex(destIndex);
869 destRegion.SetSize(destSize);
873 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
875 itk::ThreadIdType threadId)
877 itk::ProgressReporter reporter(
this, threadId, outputRegionForThread.GetNumberOfPixels() * this->GetNumberOfInputs());
880 this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
882 unsigned int dir = 0;
886 lowPassOperator.SetDirection(dir);
887 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
888 lowPassOperator.CreateDirectional();
892 highPassOperator.SetDirection(dir);
893 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
894 highPassOperator.CreateDirectional();
897 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
898 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
901 typename NeighborhoodIteratorType::RadiusType radiusMax;
902 for (
unsigned int idx = 0; idx < OutputImageDimension; ++idx)
904 radiusMax[idx] = lowPassOperator.GetRadius(idx);
905 if (radiusMax[idx] < highPassOperator.GetRadius(idx))
906 radiusMax[idx] = highPassOperator.GetRadius(idx);
910 if (m_SubsampleImageFactor > 1)
912 for (
unsigned int i = 0; i < this->GetNumberOfInputs(); i += 2)
918 if (dir != InputImageDimension - 1)
920 outputImage = m_InternalImages[0][i / 2];
924 typename FilterType::InputImageIndexType delta;
926 delta[dir] = this->GetSubsampleImageFactor();
929 cropedLowPass->SetRegions(inputRegionForThread);
930 cropedLowPass->Allocate();
931 cropedLowPass->FillBuffer(0.);
932 itk::ImageRegionIterator<InputImageType> cropedLowPassIt(cropedLowPass, inputRegionForThread);
933 itk::ImageRegionIterator<InputImageType> imgLowPassIt(imgLowPass, inputRegionForThread);
934 for (cropedLowPassIt.GoToBegin(), imgLowPassIt.GoToBegin(); !cropedLowPassIt.IsAtEnd() && !imgLowPassIt.IsAtEnd(); ++cropedLowPassIt, ++imgLowPassIt)
936 cropedLowPassIt.Set(imgLowPassIt.Get());
939 typename FilterType::Pointer overSampledLowPass = FilterType::New();
940 overSampledLowPass->SetInput(cropedLowPass);
941 overSampledLowPass->SetSubsampleFactor(delta);
942 overSampledLowPass->Update();
945 cropedHighPass->SetRegions(inputRegionForThread);
946 cropedHighPass->Allocate();
947 cropedHighPass->FillBuffer(0.);
948 itk::ImageRegionIterator<InputImageType> cropedHighPassIt(cropedHighPass, inputRegionForThread);
949 itk::ImageRegionIterator<InputImageType> imgHighPassIt(imgHighPass, inputRegionForThread);
950 for (cropedHighPassIt.GoToBegin(), imgHighPassIt.GoToBegin(); !cropedHighPassIt.IsAtEnd() && !imgHighPassIt.IsAtEnd();
951 ++cropedHighPassIt, ++imgHighPassIt)
953 cropedHighPassIt.Set(imgHighPassIt.Get());
956 typename FilterType::Pointer overSampledHighPass = FilterType::New();
957 overSampledHighPass->SetInput(cropedHighPass);
958 overSampledHighPass->SetSubsampleFactor(delta);
959 overSampledHighPass->Update();
961 InnerProductType innerProduct;
963 itk::ImageRegionIterator<OutputImageType> out(outputImage, overSampledLowPass->GetOutput()->GetRequestedRegion());
965 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), overSampledLowPass->GetOutput(), overSampledLowPass->GetOutput()->GetRequestedRegion());
966 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
967 lowIter.OverrideBoundaryCondition(&boundaryCondition);
969 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), overSampledHighPass->GetOutput(), overSampledHighPass->GetOutput()->GetRequestedRegion());
970 highIter.OverrideBoundaryCondition(&boundaryCondition);
973 highIter.GoToBegin();
976 while (!out.IsAtEnd())
978 out.Set(innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator));
984 reporter.CompletedPixel();
990 for (
unsigned int i = 0; i < this->GetNumberOfInputs(); i += 2)
996 if (dir != InputImageDimension - 1)
998 outputImage = m_InternalImages[0][i / 2];
1001 InnerProductType innerProduct;
1003 itk::ImageRegionIterator<OutputImageType> out(outputImage, imgLowPass->GetRequestedRegion());
1005 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), imgLowPass, imgLowPass->GetRequestedRegion());
1006 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1007 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1009 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), imgHighPass, imgLowPass->GetRequestedRegion());
1010 highIter.OverrideBoundaryCondition(&boundaryCondition);
1012 lowIter.GoToBegin();
1013 highIter.GoToBegin();
1016 while (!out.IsAtEnd())
1018 out.Set((innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator)) / 2.);
1024 reporter.CompletedPixel();
1029 if (dir != InputImageDimension - 1)
1033 this->CallCopyInputRegionToOutputRegion(dir, outputImageRegion, inputRegionForThread);
1035 ThreadedGenerateDataAtDimensionN(dir + 1, reporter, outputImageRegion, threadId);
1039 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
1041 unsigned int direction, itk::ProgressReporter& reporter,
const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
1044 this->CallCopyInputRegionToOutputRegion(direction, outputImageRegion, outputRegionForThread);
1048 lowPassOperator.SetDirection(direction);
1049 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
1050 lowPassOperator.CreateDirectional();
1054 highPassOperator.SetDirection(direction);
1055 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
1056 highPassOperator.CreateDirectional();
1059 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
1060 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
1062 typename NeighborhoodIteratorType::RadiusType radiusMax;
1063 for (
unsigned int i = 0; i < InputImageDimension; ++i)
1065 radiusMax[i] = lowPassOperator.GetRadius(i);
1066 if (radiusMax[i] < highPassOperator.GetRadius(i))
1067 radiusMax[i] = highPassOperator.GetRadius(i);
1071 if (m_SubsampleImageFactor > 1)
1073 for (
unsigned int i = 0; i < m_InternalImages[direction - 1].size(); i += 2)
1079 if (direction < InputImageDimension - 1)
1081 outputImage = m_InternalImages[direction][i / 2];
1085 typename FilterType::InputImageIndexType delta;
1087 delta[direction] = this->GetSubsampleImageFactor();
1090 cropedLowPass->SetRegions(outputRegionForThread);
1091 cropedLowPass->Allocate();
1092 cropedLowPass->FillBuffer(0.);
1093 itk::ImageRegionIterator<InputImageType> cropedLowPassIt(cropedLowPass, outputRegionForThread);
1094 itk::ImageRegionIterator<InputImageType> imgLowPassIt(imgLowPass, outputRegionForThread);
1095 for (cropedLowPassIt.GoToBegin(), imgLowPassIt.GoToBegin(); !cropedLowPassIt.IsAtEnd() && !imgLowPassIt.IsAtEnd(); ++cropedLowPassIt, ++imgLowPassIt)
1097 cropedLowPassIt.Set(imgLowPassIt.Get());
1100 typename FilterType::Pointer overSampledLowPass = FilterType::New();
1101 overSampledLowPass->SetInput(cropedLowPass);
1102 overSampledLowPass->SetSubsampleFactor(delta);
1103 overSampledLowPass->SetNumberOfWorkUnits(1);
1104 overSampledLowPass->Update();
1107 cropedHighPass->SetRegions(outputRegionForThread);
1108 cropedHighPass->Allocate();
1109 cropedHighPass->FillBuffer(0.);
1110 itk::ImageRegionIterator<InputImageType> cropedHighPassIt(cropedHighPass, outputRegionForThread);
1111 itk::ImageRegionIterator<InputImageType> imgHighPassIt(imgHighPass, outputRegionForThread);
1112 for (cropedHighPassIt.GoToBegin(), imgHighPassIt.GoToBegin(); !cropedHighPassIt.IsAtEnd() && !imgHighPassIt.IsAtEnd();
1113 ++cropedHighPassIt, ++imgHighPassIt)
1115 cropedHighPassIt.Set(imgHighPassIt.Get());
1118 typename FilterType::Pointer overSampledHighPass = FilterType::New();
1119 overSampledHighPass->SetInput(cropedHighPass);
1120 overSampledHighPass->SetSubsampleFactor(delta);
1121 overSampledHighPass->SetNumberOfWorkUnits(1);
1122 overSampledHighPass->Update();
1124 InnerProductType innerProduct;
1126 itk::ImageRegionIterator<OutputImageType> out(outputImage, overSampledLowPass->GetOutput()->GetRequestedRegion());
1130 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), overSampledLowPass->GetOutput(), overSampledLowPass->GetOutput()->GetRequestedRegion());
1131 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1132 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1134 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), overSampledHighPass->GetOutput(), overSampledHighPass->GetOutput()->GetRequestedRegion());
1135 highIter.OverrideBoundaryCondition(&boundaryCondition);
1137 lowIter.GoToBegin();
1138 highIter.GoToBegin();
1141 while (!out.IsAtEnd())
1143 out.Set(innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator));
1149 reporter.CompletedPixel();
1155 for (
unsigned int i = 0; i < m_InternalImages[direction - 1].size(); i += 2)
1161 if (direction < InputImageDimension - 1)
1163 outputImage = m_InternalImages[direction][i / 2];
1166 InnerProductType innerProduct;
1168 itk::ImageRegionIterator<OutputImageType> out(outputImage, imgLowPass->GetRequestedRegion());
1170 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), imgLowPass, imgLowPass->GetRequestedRegion());
1171 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1172 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1174 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), imgHighPass, imgLowPass->GetRequestedRegion());
1175 highIter.OverrideBoundaryCondition(&boundaryCondition);
1177 lowIter.GoToBegin();
1178 highIter.GoToBegin();
1181 while (!out.IsAtEnd())
1183 out.Set((innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator)) / 2.);
1189 reporter.CompletedPixel();
1194 if (direction < InputImageDimension - 1)
1196 ThreadedGenerateDataAtDimensionN(direction + 1, reporter, outputImageRegion, threadId);
Performs a down sampling of an image.
Regular subsample iterator over an image.
One level stationary wavelet transform.
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
#define otbGenericMsgDebugMacro(x)