23 #ifndef otbWaveletFilterBank_hxx
24 #define otbWaveletFilterBank_hxx
30 #include "itkPeriodicBoundaryCondition.h"
39 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
42 this->SetNumberOfRequiredInputs(1);
43 this->SetNumberOfRequiredInputs(1);
45 unsigned int numOfOutputs = 1 << InputImageDimension;
47 this->SetNumberOfRequiredOutputs(numOfOutputs);
48 for (
unsigned int i = 0; i < numOfOutputs; ++i)
50 this->SetNthOutput(i, OutputImageType::New());
53 m_UpSampleFilterFactor = 0;
54 m_SubsampleImageFactor = 1;
57 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
60 Superclass::GenerateOutputInformation();
62 if (GetSubsampleImageFactor() == 1)
66 otbGenericMsgDebugMacro(<<
"initial region " << this->GetInput()->GetLargestPossibleRegion().GetSize()[0] <<
","
67 << this->GetInput()->GetLargestPossibleRegion().GetSize()[1]);
70 this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput()->GetLargestPossibleRegion());
72 for (
unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
74 this->GetOutput(i)->SetRegions(newRegion);
80 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
83 Superclass::GenerateInputRequestedRegion();
87 lowPassOperator.SetDirection(0);
88 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
89 lowPassOperator.CreateDirectional();
91 unsigned int radius = lowPassOperator.GetRadius()[0];
94 highPassOperator.SetDirection(0);
95 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
96 highPassOperator.CreateDirectional();
98 if (radius < highPassOperator.GetRadius()[0])
99 radius = highPassOperator.GetRadius()[0];
104 inputRegion.PadByRadius(radius);
106 if (inputRegion.Crop(input->GetLargestPossibleRegion()))
108 input->SetRequestedRegion(inputRegion);
112 input->SetRequestedRegion(inputRegion);
113 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
114 err.SetLocation(ITK_LOCATION);
115 err.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
116 err.SetDataObject(input);
121 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
125 unsigned int one = 1;
126 if (m_SubsampleImageFactor > 1)
129 for (
unsigned int i = 0; i < InputImageDimension; ++i)
131 if ((m_SubsampleImageFactor * (this->GetInput()->GetRequestedRegion().GetSize()[i] / m_SubsampleImageFactor)) !=
132 this->GetInput()->GetRequestedRegion().GetSize()[i])
134 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
135 err.SetLocation(ITK_LOCATION);
136 err.SetDescription(
"Requested region dimension cannot be used in multiresolution analysis (crop it).");
142 if (InputImageDimension > 1)
145 m_InternalImages.resize(InputImageDimension - 1);
146 for (
unsigned int i = 0; i < m_InternalImages.size(); ++i)
149 m_InternalImages[InputImageDimension - 2 - i].resize(one << (i + 1));
153 this->Superclass::CallCopyInputRegionToOutputRegion(intermediateRegion, this->GetInput()->GetLargestPossibleRegion());
155 AllocateInternalData(intermediateRegion);
160 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
166 for (
unsigned int direction = 0; direction < InputImageDimension - 1; direction++)
168 this->CallCopyInputRegionToOutputRegion(InputImageDimension - 1 - direction, smallerRegion, largerRegion);
170 const unsigned int d = InputImageDimension - 2 - direction;
171 for (
unsigned int i = 0; i < m_InternalImages[d].size(); ++i)
173 m_InternalImages[d][i] = OutputImageType::New();
174 m_InternalImages[d][i]->SetRegions(smallerRegion);
175 m_InternalImages[d][i]->Allocate();
176 m_InternalImages[d][i]->FillBuffer(0);
179 largerRegion = smallerRegion;
183 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
186 if (m_SubsampleImageFactor > 1 && InputImageDimension > 1)
188 m_InternalImages.clear();
192 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
196 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
198 if (GetSubsampleImageFactor() > 1)
206 for (
unsigned int i = 0; i < InputImageDimension; ++i)
208 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
209 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
212 destRegion.SetIndex(destIndex);
213 destRegion.SetSize(destSize);
220 lowPassOperator.SetDirection(0);
221 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
222 lowPassOperator.CreateDirectional();
224 unsigned long radius[InputImageDimension];
225 radius[0] = lowPassOperator.GetRadius()[0];
228 highPassOperator.SetDirection(0);
229 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
230 highPassOperator.CreateDirectional();
232 if (radius[0] < highPassOperator.GetRadius()[0]) radius[0] = highPassOperator.GetRadius()[0];
234 for (
unsigned int i = 1; i < InputImageDimension; ++i)
238 paddedRegion.PadByRadius(radius);
240 if (paddedRegion.Crop(this->GetInput()->GetLargestPossibleRegion()))
242 destRegion = paddedRegion;
248 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
253 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
255 if (GetSubsampleImageFactor() > 1)
263 for (
unsigned int i = 0; i < InputImageDimension; ++i)
267 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
268 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
272 destIndex[i] = srcIndex[i];
273 destSize[i] = srcSize[i];
277 destRegion.SetIndex(destIndex);
278 destRegion.SetSize(destSize);
282 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
286 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
288 if (GetSubsampleImageFactor() > 1)
290 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
291 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
293 typename OutputImageRegionType::IndexType destIndex;
294 typename OutputImageRegionType::SizeType destSize;
296 for (
unsigned int i = 0; i < InputImageDimension; ++i)
299 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
300 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
303 destRegion.SetIndex(destIndex);
304 destRegion.SetSize(destSize);
308 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
313 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
315 if (GetSubsampleImageFactor() > 1)
317 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
318 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
320 typename OutputImageRegionType::IndexType destIndex;
321 typename OutputImageRegionType::SizeType destSize;
323 for (
unsigned int i = 0; i < InputImageDimension; ++i)
328 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
329 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
333 destIndex[i] = srcIndex[i];
334 destSize[i] = srcSize[i];
338 destRegion.SetIndex(destIndex);
339 destRegion.SetSize(destSize);
343 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
345 itk::ThreadIdType threadId)
347 unsigned int dir = InputImageDimension - 1;
349 if ((1 << dir) >=
static_cast<int>(this->GetNumberOfOutputs()))
351 std::ostringstream msg;
352 msg <<
"Output number 1<<" << dir <<
" = " << (1 << dir) <<
" not allocated\n";
353 msg <<
"Number of expected outputs " << this->GetNumberOfOutputs() <<
"\n";
354 throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
357 itk::ProgressReporter reporter(
this, threadId, outputRegionForThread.GetNumberOfPixels() * this->GetNumberOfOutputs() * 2);
361 this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
367 if (dir != 0 && m_SubsampleImageFactor > 1)
369 outputLowPass = m_InternalImages[dir - 1][0];
370 outputHighPass = m_InternalImages[dir - 1][1];
374 typedef itk::ConstNeighborhoodIterator<InputImageType> NeighborhoodIteratorType;
375 typedef itk::NeighborhoodInnerProduct<InputImageType> InnerProductType;
376 typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
380 typename SubsampleIteratorType::IndexType subsampling;
382 subsampling[dir] = GetSubsampleImageFactor();
385 InnerProductType innerProduct;
389 highPassOperator.SetDirection(dir);
390 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
391 highPassOperator.CreateDirectional();
393 SubsampleIteratorType subItHighPass(input, inputRegionForThread);
394 subItHighPass.SetSubsampleFactor(subsampling);
395 subItHighPass.GoToBegin();
397 NeighborhoodIteratorType itHighPass(highPassOperator.GetRadius(), input, inputRegionForThread);
398 itk::PeriodicBoundaryCondition<InputImageType> boundaryCondition;
399 itHighPass.OverrideBoundaryCondition(&boundaryCondition);
401 IteratorType outHighPass(outputHighPass, subItHighPass.GenerateOutputInformation());
402 outHighPass.GoToBegin();
404 while (!subItHighPass.IsAtEnd() && !outHighPass.IsAtEnd())
406 itHighPass.SetLocation(subItHighPass.GetIndex());
407 outHighPass.Set(innerProduct(itHighPass, highPassOperator));
412 reporter.CompletedPixel();
417 lowPassOperator.SetDirection(dir);
418 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
419 lowPassOperator.CreateDirectional();
421 SubsampleIteratorType subItLowPass(input, inputRegionForThread);
422 subItLowPass.SetSubsampleFactor(subsampling);
423 subItLowPass.GoToBegin();
425 NeighborhoodIteratorType itLowPass(lowPassOperator.GetRadius(), input, inputRegionForThread);
426 itLowPass.OverrideBoundaryCondition(&boundaryCondition);
428 IteratorType outLowPass(outputLowPass, subItLowPass.GenerateOutputInformation());
429 outLowPass.GoToBegin();
431 while (!subItLowPass.IsAtEnd() && !outLowPass.IsAtEnd())
433 itLowPass.SetLocation(subItLowPass.GetIndex());
434 outLowPass.Set(innerProduct(itLowPass, lowPassOperator));
439 reporter.CompletedPixel();
446 this->CallCopyInputRegionToOutputRegion(dir, outputImageRegion, inputRegionForThread);
448 ThreadedGenerateDataAtDimensionN(0, dir - 1, reporter, outputImageRegion, threadId);
449 ThreadedGenerateDataAtDimensionN(1 << dir, dir - 1, reporter, outputImageRegion, threadId);
453 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
455 unsigned int idx,
unsigned int direction, itk::ProgressReporter& reporter,
const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
463 this->CallCopyInputRegionToOutputRegion(direction, outputImageRegion, outputRegionForThread);
465 if (m_SubsampleImageFactor > 1)
467 input = m_InternalImages[direction][idx / (1 << (direction + 1))];
471 outputLowPass = m_InternalImages[direction - 1][idx / (1 << direction)];
472 outputHighPass = m_InternalImages[direction - 1][idx / (1 << direction) + 1];
480 outputLowPass->SetRegions(outputImageRegion);
481 outputLowPass->Allocate();
482 outputLowPass->FillBuffer(0);
486 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
487 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
488 typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
492 typename SubsampleIteratorType::IndexType subsampling;
494 subsampling[direction] = GetSubsampleImageFactor();
497 InnerProductType innerProduct;
501 highPassOperator.SetDirection(direction);
502 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
503 highPassOperator.CreateDirectional();
505 SubsampleIteratorType subItHighPass(input, outputRegionForThread);
506 subItHighPass.SetSubsampleFactor(subsampling);
507 subItHighPass.GoToBegin();
509 NeighborhoodIteratorType itHighPass(highPassOperator.GetRadius(), input, outputRegionForThread);
510 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
511 itHighPass.OverrideBoundaryCondition(&boundaryCondition);
513 IteratorType outHighPass(outputHighPass, subItHighPass.GenerateOutputInformation());
514 outHighPass.GoToBegin();
516 while (!subItHighPass.IsAtEnd() && !outHighPass.IsAtEnd())
518 itHighPass.SetLocation(subItHighPass.GetIndex());
519 outHighPass.Set(innerProduct(itHighPass, highPassOperator));
524 reporter.CompletedPixel();
529 lowPassOperator.SetDirection(direction);
530 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
531 lowPassOperator.CreateDirectional();
533 SubsampleIteratorType subItLowPass(input, outputRegionForThread);
534 subItLowPass.SetSubsampleFactor(subsampling);
535 subItLowPass.GoToBegin();
537 NeighborhoodIteratorType itLowPass(lowPassOperator.GetRadius(), input, outputRegionForThread);
538 itLowPass.OverrideBoundaryCondition(&boundaryCondition);
540 IteratorType outLowPass(outputLowPass, subItLowPass.GenerateOutputInformation());
541 outLowPass.GoToBegin();
543 while (!subItLowPass.IsAtEnd() && !outLowPass.IsAtEnd())
545 itLowPass.SetLocation(subItLowPass.GetIndex());
546 outLowPass.Set(innerProduct(itLowPass, lowPassOperator));
551 reporter.CompletedPixel();
555 itk::ImageRegionConstIterator<OutputImageType> inIt(outputLowPass, outputImageRegion);
556 IteratorType outIt((direction != 0 && m_SubsampleImageFactor > 1)
557 ?
static_cast<OutputImageType*
>(m_InternalImages[direction - 2][idx / (1 << (direction - 1))])
558 : this->GetOutput(idx),
561 for (inIt.GoToBegin(), outIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt, ++outIt)
563 outIt.Set(inIt.Get());
568 ThreadedGenerateDataAtDimensionN(idx, direction - 1, reporter, outputImageRegion, threadId);
569 ThreadedGenerateDataAtDimensionN(idx + (1 << direction), direction - 1, reporter, outputImageRegion, threadId);
577 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
580 this->SetNumberOfRequiredInputs(1 << InputImageDimension);
582 m_UpSampleFilterFactor = 0;
583 m_SubsampleImageFactor = 1;
587 this->SetNumberOfThreads(1);
590 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
593 Superclass::GenerateOutputInformation();
595 for (
unsigned int i = 1; i < this->GetNumberOfInputs(); ++i)
597 for (
unsigned int dim = 0; dim < InputImageDimension; dim++)
599 if (this->GetInput(0)->GetLargestPossibleRegion().GetSize()[dim] != this->GetInput(i)->GetLargestPossibleRegion().GetSize()[dim])
601 throw itk::ExceptionObject(__FILE__, __LINE__,
"Input images are not of the same dimension", ITK_LOCATION);
608 otbGenericMsgDebugMacro(<<
"initial region " << this->GetInput(0)->GetLargestPossibleRegion().GetSize()[0] <<
","
609 << this->GetInput(0)->GetLargestPossibleRegion().GetSize()[1]);
612 this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput(0)->GetLargestPossibleRegion());
613 this->GetOutput()->SetRegions(newRegion);
618 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
621 Superclass::GenerateInputRequestedRegion();
625 lowPassOperator.SetDirection(0);
626 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
627 lowPassOperator.CreateDirectional();
629 unsigned int radius = lowPassOperator.GetRadius()[0];
632 highPassOperator.SetDirection(0);
633 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
634 highPassOperator.CreateDirectional();
636 if (radius < highPassOperator.GetRadius()[0])
637 radius = highPassOperator.GetRadius()[0];
640 for (
unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
644 inputRegion.PadByRadius(radius);
646 if (inputRegion.Crop(input->GetLargestPossibleRegion()))
648 input->SetRequestedRegion(inputRegion);
652 input->SetRequestedRegion(inputRegion);
653 itk::InvalidRequestedRegionError err(__FILE__, __LINE__);
654 err.SetLocation(ITK_LOCATION);
655 err.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
656 err.SetDataObject(input);
662 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
665 unsigned int one = 1;
666 if (InputImageDimension > 1)
669 m_InternalImages.resize(InputImageDimension - 1);
670 for (
unsigned int i = 0; i < m_InternalImages.size(); ++i)
673 m_InternalImages[i].resize(one << (i + 1));
677 Superclass::CallCopyInputRegionToOutputRegion(intermediateRegion, this->GetInput(0)->GetLargestPossibleRegion());
679 AllocateInternalData(intermediateRegion);
683 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
689 for (
unsigned int direction = 0; direction < InputImageDimension - 1; direction++)
691 this->CallCopyInputRegionToOutputRegion(direction, largerRegion, smallerRegion);
693 for (
unsigned int i = 0; i < m_InternalImages[direction].size(); ++i)
695 m_InternalImages[direction][i] = OutputImageType::New();
696 m_InternalImages[direction][i]->SetRegions(largerRegion);
697 m_InternalImages[direction][i]->Allocate();
698 m_InternalImages[direction][i]->FillBuffer(0);
701 smallerRegion = largerRegion;
705 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
708 if (m_SubsampleImageFactor > 1 && InputImageDimension > 1)
710 m_InternalImages.clear();
714 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
718 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
720 if (GetSubsampleImageFactor() > 1)
728 for (
unsigned int i = 0; i < InputImageDimension; ++i)
731 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
732 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
735 destRegion.SetIndex(destIndex);
736 destRegion.SetSize(destSize);
741 lowPassOperator.SetDirection(0);
742 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
743 lowPassOperator.CreateDirectional();
745 typename InputImageRegionType::SizeType radius;
746 radius[0] = lowPassOperator.GetRadius()[0];
749 highPassOperator.SetDirection(0);
750 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
751 highPassOperator.CreateDirectional();
753 if (radius[0] < highPassOperator.GetRadius()[0])
754 radius[0] = highPassOperator.GetRadius()[0];
756 for (
unsigned int i = 1; i < InputImageDimension; ++i)
767 paddedRegion.PadByRadius(radius);
769 if (paddedRegion.Crop(this->GetInput(0)->GetLargestPossibleRegion()))
771 destRegion = paddedRegion;
777 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
781 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
783 if (GetSubsampleImageFactor() > 1)
791 for (
unsigned int i = 0; i < InputImageDimension; ++i)
793 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
794 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
797 destRegion.SetIndex(destIndex);
798 destRegion.SetSize(destSize);
802 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
807 Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
809 if (GetSubsampleImageFactor() > 1)
817 for (
unsigned int i = 0; i < InputImageDimension; ++i)
822 destIndex[i] = srcIndex[i] / GetSubsampleImageFactor();
823 destSize[i] = srcSize[i] / GetSubsampleImageFactor();
827 destIndex[i] = srcIndex[i];
828 destSize[i] = srcSize[i];
832 destRegion.SetIndex(destIndex);
833 destRegion.SetSize(destSize);
837 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
842 Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
844 if (GetSubsampleImageFactor() > 1)
846 typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
847 typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
849 typename OutputImageRegionType::IndexType destIndex;
850 typename OutputImageRegionType::SizeType destSize;
852 for (
unsigned int i = 0; i < InputImageDimension; ++i)
856 destIndex[i] = srcIndex[i] * GetSubsampleImageFactor();
857 destSize[i] = srcSize[i] * GetSubsampleImageFactor();
861 destIndex[i] = srcIndex[i];
862 destSize[i] = srcSize[i];
866 destRegion.SetIndex(destIndex);
867 destRegion.SetSize(destSize);
871 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
873 itk::ThreadIdType threadId)
875 itk::ProgressReporter reporter(
this, threadId, outputRegionForThread.GetNumberOfPixels() * this->GetNumberOfInputs());
878 this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
880 unsigned int dir = 0;
884 lowPassOperator.SetDirection(dir);
885 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
886 lowPassOperator.CreateDirectional();
890 highPassOperator.SetDirection(dir);
891 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
892 highPassOperator.CreateDirectional();
895 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
896 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
899 typename NeighborhoodIteratorType::RadiusType radiusMax;
900 for (
unsigned int idx = 0; idx < OutputImageDimension; ++idx)
902 radiusMax[idx] = lowPassOperator.GetRadius(idx);
903 if (radiusMax[idx] < highPassOperator.GetRadius(idx))
904 radiusMax[idx] = highPassOperator.GetRadius(idx);
908 if (m_SubsampleImageFactor > 1)
910 for (
unsigned int i = 0; i < this->GetNumberOfInputs(); i += 2)
916 if (dir != InputImageDimension - 1)
918 outputImage = m_InternalImages[0][i / 2];
922 typename FilterType::InputImageIndexType delta;
924 delta[dir] = this->GetSubsampleImageFactor();
927 cropedLowPass->SetRegions(inputRegionForThread);
928 cropedLowPass->Allocate();
929 cropedLowPass->FillBuffer(0.);
930 itk::ImageRegionIterator<InputImageType> cropedLowPassIt(cropedLowPass, inputRegionForThread);
931 itk::ImageRegionIterator<InputImageType> imgLowPassIt(imgLowPass, inputRegionForThread);
932 for (cropedLowPassIt.GoToBegin(), imgLowPassIt.GoToBegin(); !cropedLowPassIt.IsAtEnd() && !imgLowPassIt.IsAtEnd(); ++cropedLowPassIt, ++imgLowPassIt)
934 cropedLowPassIt.Set(imgLowPassIt.Get());
937 typename FilterType::Pointer overSampledLowPass = FilterType::New();
938 overSampledLowPass->SetInput(cropedLowPass);
939 overSampledLowPass->SetSubsampleFactor(delta);
940 overSampledLowPass->Update();
943 cropedHighPass->SetRegions(inputRegionForThread);
944 cropedHighPass->Allocate();
945 cropedHighPass->FillBuffer(0.);
946 itk::ImageRegionIterator<InputImageType> cropedHighPassIt(cropedHighPass, inputRegionForThread);
947 itk::ImageRegionIterator<InputImageType> imgHighPassIt(imgHighPass, inputRegionForThread);
948 for (cropedHighPassIt.GoToBegin(), imgHighPassIt.GoToBegin(); !cropedHighPassIt.IsAtEnd() && !imgHighPassIt.IsAtEnd();
949 ++cropedHighPassIt, ++imgHighPassIt)
951 cropedHighPassIt.Set(imgHighPassIt.Get());
954 typename FilterType::Pointer overSampledHighPass = FilterType::New();
955 overSampledHighPass->SetInput(cropedHighPass);
956 overSampledHighPass->SetSubsampleFactor(delta);
957 overSampledHighPass->Update();
959 InnerProductType innerProduct;
961 itk::ImageRegionIterator<OutputImageType> out(outputImage, overSampledLowPass->GetOutput()->GetRequestedRegion());
963 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), overSampledLowPass->GetOutput(), overSampledLowPass->GetOutput()->GetRequestedRegion());
964 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
965 lowIter.OverrideBoundaryCondition(&boundaryCondition);
967 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), overSampledHighPass->GetOutput(), overSampledHighPass->GetOutput()->GetRequestedRegion());
968 highIter.OverrideBoundaryCondition(&boundaryCondition);
971 highIter.GoToBegin();
974 while (!out.IsAtEnd())
976 out.Set(innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator));
982 reporter.CompletedPixel();
988 for (
unsigned int i = 0; i < this->GetNumberOfInputs(); i += 2)
994 if (dir != InputImageDimension - 1)
996 outputImage = m_InternalImages[0][i / 2];
999 InnerProductType innerProduct;
1001 itk::ImageRegionIterator<OutputImageType> out(outputImage, imgLowPass->GetRequestedRegion());
1003 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), imgLowPass, imgLowPass->GetRequestedRegion());
1004 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1005 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1007 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), imgHighPass, imgLowPass->GetRequestedRegion());
1008 highIter.OverrideBoundaryCondition(&boundaryCondition);
1010 lowIter.GoToBegin();
1011 highIter.GoToBegin();
1014 while (!out.IsAtEnd())
1016 out.Set((innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator)) / 2.);
1022 reporter.CompletedPixel();
1027 if (dir != InputImageDimension - 1)
1031 this->CallCopyInputRegionToOutputRegion(dir, outputImageRegion, inputRegionForThread);
1033 ThreadedGenerateDataAtDimensionN(dir + 1, reporter, outputImageRegion, threadId);
1037 template <
class TInputImage,
class TOutputImage,
class TWaveletOperator>
1039 unsigned int direction, itk::ProgressReporter& reporter,
const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
1042 this->CallCopyInputRegionToOutputRegion(direction, outputImageRegion, outputRegionForThread);
1046 lowPassOperator.SetDirection(direction);
1047 lowPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
1048 lowPassOperator.CreateDirectional();
1052 highPassOperator.SetDirection(direction);
1053 highPassOperator.SetUpSampleFactor(this->GetUpSampleFilterFactor());
1054 highPassOperator.CreateDirectional();
1057 typedef itk::ConstNeighborhoodIterator<OutputImageType> NeighborhoodIteratorType;
1058 typedef itk::NeighborhoodInnerProduct<OutputImageType> InnerProductType;
1060 typename NeighborhoodIteratorType::RadiusType radiusMax;
1061 for (
unsigned int i = 0; i < InputImageDimension; ++i)
1063 radiusMax[i] = lowPassOperator.GetRadius(i);
1064 if (radiusMax[i] < highPassOperator.GetRadius(i))
1065 radiusMax[i] = highPassOperator.GetRadius(i);
1069 if (m_SubsampleImageFactor > 1)
1071 for (
unsigned int i = 0; i < m_InternalImages[direction - 1].size(); i += 2)
1077 if (direction < InputImageDimension - 1)
1079 outputImage = m_InternalImages[direction][i / 2];
1083 typename FilterType::InputImageIndexType delta;
1085 delta[direction] = this->GetSubsampleImageFactor();
1088 cropedLowPass->SetRegions(outputRegionForThread);
1089 cropedLowPass->Allocate();
1090 cropedLowPass->FillBuffer(0.);
1091 itk::ImageRegionIterator<InputImageType> cropedLowPassIt(cropedLowPass, outputRegionForThread);
1092 itk::ImageRegionIterator<InputImageType> imgLowPassIt(imgLowPass, outputRegionForThread);
1093 for (cropedLowPassIt.GoToBegin(), imgLowPassIt.GoToBegin(); !cropedLowPassIt.IsAtEnd() && !imgLowPassIt.IsAtEnd(); ++cropedLowPassIt, ++imgLowPassIt)
1095 cropedLowPassIt.Set(imgLowPassIt.Get());
1098 typename FilterType::Pointer overSampledLowPass = FilterType::New();
1099 overSampledLowPass->SetInput(cropedLowPass);
1100 overSampledLowPass->SetSubsampleFactor(delta);
1101 overSampledLowPass->SetNumberOfThreads(1);
1102 overSampledLowPass->Update();
1105 cropedHighPass->SetRegions(outputRegionForThread);
1106 cropedHighPass->Allocate();
1107 cropedHighPass->FillBuffer(0.);
1108 itk::ImageRegionIterator<InputImageType> cropedHighPassIt(cropedHighPass, outputRegionForThread);
1109 itk::ImageRegionIterator<InputImageType> imgHighPassIt(imgHighPass, outputRegionForThread);
1110 for (cropedHighPassIt.GoToBegin(), imgHighPassIt.GoToBegin(); !cropedHighPassIt.IsAtEnd() && !imgHighPassIt.IsAtEnd();
1111 ++cropedHighPassIt, ++imgHighPassIt)
1113 cropedHighPassIt.Set(imgHighPassIt.Get());
1116 typename FilterType::Pointer overSampledHighPass = FilterType::New();
1117 overSampledHighPass->SetInput(cropedHighPass);
1118 overSampledHighPass->SetSubsampleFactor(delta);
1119 overSampledHighPass->SetNumberOfThreads(1);
1120 overSampledHighPass->Update();
1122 InnerProductType innerProduct;
1124 itk::ImageRegionIterator<OutputImageType> out(outputImage, overSampledLowPass->GetOutput()->GetRequestedRegion());
1128 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), overSampledLowPass->GetOutput(), overSampledLowPass->GetOutput()->GetRequestedRegion());
1129 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1130 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1132 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), overSampledHighPass->GetOutput(), overSampledHighPass->GetOutput()->GetRequestedRegion());
1133 highIter.OverrideBoundaryCondition(&boundaryCondition);
1135 lowIter.GoToBegin();
1136 highIter.GoToBegin();
1139 while (!out.IsAtEnd())
1141 out.Set(innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator));
1147 reporter.CompletedPixel();
1153 for (
unsigned int i = 0; i < m_InternalImages[direction - 1].size(); i += 2)
1159 if (direction < InputImageDimension - 1)
1161 outputImage = m_InternalImages[direction][i / 2];
1164 InnerProductType innerProduct;
1166 itk::ImageRegionIterator<OutputImageType> out(outputImage, imgLowPass->GetRequestedRegion());
1168 NeighborhoodIteratorType lowIter(lowPassOperator.GetRadius(), imgLowPass, imgLowPass->GetRequestedRegion());
1169 itk::PeriodicBoundaryCondition<OutputImageType> boundaryCondition;
1170 lowIter.OverrideBoundaryCondition(&boundaryCondition);
1172 NeighborhoodIteratorType highIter(highPassOperator.GetRadius(), imgHighPass, imgLowPass->GetRequestedRegion());
1173 highIter.OverrideBoundaryCondition(&boundaryCondition);
1175 lowIter.GoToBegin();
1176 highIter.GoToBegin();
1179 while (!out.IsAtEnd())
1181 out.Set((innerProduct(lowIter, lowPassOperator) + innerProduct(highIter, highPassOperator)) / 2.);
1187 reporter.CompletedPixel();
1192 if (direction < InputImageDimension - 1)
1194 ThreadedGenerateDataAtDimensionN(direction + 1, reporter, outputImageRegion, threadId);