21 #ifndef otbBinaryFunctorNeighborhoodJoinHistogramImageFilter_hxx
22 #define otbBinaryFunctorNeighborhoodJoinHistogramImageFilter_hxx
25 #include "itkImageRegionIterator.h"
26 #include "itkNeighborhoodAlgorithm.h"
27 #include "itkProgressReporter.h"
35 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
38 this->SetNumberOfRequiredInputs(2);
40 m_UsePaddingValue =
false;
41 m_UpperBoundIncreaseFactor = 0.001;
48 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
52 this->SetNthInput(0,
const_cast<TInputImage1*
>(image1));
58 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
62 this->SetNthInput(1,
const_cast<TInputImage2*
>(image2));
65 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
68 if (this->GetNumberOfInputs() < 1)
72 return static_cast<const TInputImage1*
>(this->itk::ProcessObject::GetInput(0));
75 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
78 if (this->GetNumberOfInputs() < 2)
82 return static_cast<const TInputImage2*
>(this->itk::ProcessObject::GetInput(1));
85 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
89 Superclass::GenerateInputRequestedRegion();
94 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
96 if (!inputPtr1 || !inputPtr2 || !outputPtr)
102 typename TInputImage1::RegionType inputRequestedRegion1, inputRequestedRegion2;
103 inputRequestedRegion1 = inputPtr1->GetRequestedRegion();
106 inputRequestedRegion1.PadByRadius(m_Radius);
107 inputRequestedRegion2 = inputRequestedRegion1;
110 if (inputRequestedRegion1.Crop(inputPtr1->GetLargestPossibleRegion()))
112 inputPtr1->SetRequestedRegion(inputRequestedRegion1);
120 inputPtr1->SetRequestedRegion(inputRequestedRegion1);
123 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
124 std::ostringstream msg;
125 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
126 e.SetLocation(msg.str());
127 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region of image 1.");
128 e.SetDataObject(inputPtr1);
131 if (inputRequestedRegion2.Crop(inputPtr2->GetLargestPossibleRegion()))
133 inputPtr2->SetRequestedRegion(inputRequestedRegion2);
141 inputPtr2->SetRequestedRegion(inputRequestedRegion2);
144 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
145 std::ostringstream msg;
146 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
147 e.SetLocation(msg.str());
148 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region of image 1.");
149 e.SetDataObject(inputPtr2);
155 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
158 this->ComputeHistogram();
164 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
171 itk::ImageRegionConstIterator<Input1ImageType> fiIt(pInput1Image, pInput1Image->GetBufferedRegion());
173 minInput1 = fiIt.Value();
174 maxInput1 = fiIt.Value();
176 while (!fiIt.IsAtEnd())
180 if (value < minInput1)
184 else if (value > maxInput1)
195 itk::ImageRegionConstIterator<Input2ImageType> miIt(pInput2Image, pInput2Image->GetBufferedRegion());
197 minInput2 = miIt.Value();
198 maxInput2 = miIt.Value();
200 while (!miIt.IsAtEnd())
204 if (value < minInput2)
208 else if (value > maxInput2)
218 lowerBound.SetSize(2);
219 upperBound.SetSize(2);
222 lowerBound[0] = minInput1;
223 lowerBound[1] = minInput2;
224 upperBound[0] = maxInput1 + (maxInput1 - minInput1) * m_UpperBoundIncreaseFactor;
225 upperBound[1] = maxInput2 + (maxInput2 - minInput2) * m_UpperBoundIncreaseFactor;
227 typedef itk::ImageRegionConstIteratorWithIndex<Input1ImageType> Input1IteratorType;
228 typedef itk::ImageRegionConstIteratorWithIndex<Input2ImageType> Input2IteratorType;
230 typename Input1ImageType::RegionType input1Region;
231 typename Input1ImageType::RegionType input2Region;
233 input1Region = pInput1Image->GetRequestedRegion();
234 Input1IteratorType ti1(pInput1Image, input1Region);
236 input2Region = pInput2Image->GetRequestedRegion();
237 Input2IteratorType ti2(pInput2Image, input2Region);
239 typename HistogramType::Pointer histogram = HistogramType::New();
241 histogramSize.Fill(256);
242 histogram->SetMeasurementVectorSize(2);
243 histogram->Initialize(histogramSize, lowerBound, upperBound);
247 while (!ti1.IsAtEnd() && !ti2.IsAtEnd())
250 typename HistogramType::IndexType sample(2);
251 sample[0] = ti1.Get();
252 sample[1] = ti2.Get();
253 if (sample[0] != itk::NumericTraits<Input1ImagePixelType>::Zero && sample[1] != itk::NumericTraits<Input2ImagePixelType>::Zero)
254 histogram->IncreaseFrequencyOfIndex(sample, 1);
260 m_Histogram = histogram;
266 template <
class TInputImage1,
class TInputImage2,
class TOutputImage,
class TFunction>
270 itk::ZeroFluxNeumannBoundaryCondition<TInputImage1> nbc1;
271 itk::ZeroFluxNeumannBoundaryCondition<TInputImage2> nbc2;
288 itk::ImageRegionIterator<TOutputImage> outputIt;
291 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1>::FaceListType faceList1;
292 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1> bC1;
293 faceList1 = bC1(inputPtr1, outputRegionForThread, r1);
295 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2>::FaceListType faceList2;
296 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2> bC2;
297 faceList2 = bC2(inputPtr2, outputRegionForThread, r2);
299 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1>::FaceListType::iterator fit1;
300 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2>::FaceListType::iterator fit2;
303 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
307 for (fit1 = faceList1.begin(), fit2 = faceList2.begin(); fit1 != faceList1.end() && fit2 != faceList2.end(); ++fit1, ++fit2)
309 neighInputIt1 = itk::ConstNeighborhoodIterator<TInputImage1>(r1, inputPtr1, *fit1);
310 neighInputIt2 = itk::ConstNeighborhoodIterator<TInputImage2>(r1, inputPtr2, *fit2);
311 outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, outputRegionForThread);
313 outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit1);
314 neighInputIt1.OverrideBoundaryCondition(&nbc1);
315 neighInputIt1.GoToBegin();
316 neighInputIt2.OverrideBoundaryCondition(&nbc2);
317 neighInputIt2.GoToBegin();
319 while (!outputIt.IsAtEnd())
322 outputIt.Set(m_Functor(neighInputIt1, neighInputIt2, m_Histogram));
327 progress.CompletedPixel();