21 #ifndef otbStreamingCompareImageFilter_hxx
22 #define otbStreamingCompareImageFilter_hxx
25 #include "itkImageRegionIterator.h"
26 #include "itkProgressReporter.h"
33 template <
class TInputImage>
35 : m_SquareOfDifferences(1), m_AbsoluteValueOfDifferences(1), m_ThreadMinRef(1), m_ThreadMaxRef(1), m_Count(1), m_DiffCount(1), m_PhysicalSpaceCheck(true)
37 this->DynamicMultiThreadingOff();
38 this->SetNumberOfRequiredInputs( 2 );
44 for (
int i = 1; i < 5; ++i)
47 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
50 this->
GetPSNROutput()->Set(itk::NumericTraits<RealType>::max());
51 this->
GetMSEOutput()->Set(itk::NumericTraits<RealType>::max());
52 this->
GetMAEOutput()->Set(itk::NumericTraits<RealType>::max());
61 template <
class TInputImage>
65 this->SetNthInput(0,
const_cast<TInputImage*
>(image));
71 template <
class TInputImage>
75 this->SetNthInput(1,
const_cast<TInputImage*
>(image));
78 template <
class TInputImage>
81 if (this->GetNumberOfInputs() < 1)
85 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(0));
88 template <
class TInputImage>
91 if (this->GetNumberOfInputs() < 2)
95 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(1));
98 template <
class TInputImage>
104 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
110 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
114 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
119 template <
class TInputImage>
122 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(1));
125 template <
class TInputImage>
128 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(1));
131 template <
class TInputImage>
134 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(2));
137 template <
class TInputImage>
140 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(2));
143 template <
class TInputImage>
146 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
149 template <
class TInputImage>
152 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
155 template <
class TInputImage>
158 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
161 template <
class TInputImage>
164 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
167 template <
class TInputImage>
170 Superclass::GenerateOutputInformation();
171 if (this->GetInput())
173 this->GetOutput()->CopyInformation(this->GetInput());
174 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
176 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
178 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
182 template <
class TInputImage>
192 template <
class TInputImage>
197 unsigned long diffCount;
198 RealType squareOfDifferences, absoluteValueOfDifferences;
200 int numberOfThreads = this->GetNumberOfWorkUnits();
207 squareOfDifferences = absoluteValueOfDifferences = itk::NumericTraits<RealType>::Zero;
212 minimumRef = itk::NumericTraits<PixelType>::max();
213 maximumRef = itk::NumericTraits<PixelType>::NonpositiveMin();
215 for (i = 0; i < numberOfThreads; ++i)
218 diffCount += m_DiffCount[i];
219 squareOfDifferences += m_SquareOfDifferences[i];
220 absoluteValueOfDifferences += m_AbsoluteValueOfDifferences[i];
222 if (m_ThreadMinRef[i] < minimumRef)
224 minimumRef = m_ThreadMinRef[i];
226 if (m_ThreadMaxRef[i] > maximumRef)
228 maximumRef = m_ThreadMaxRef[i];
233 mse = (count != 0) ? squareOfDifferences /
static_cast<RealType>(count) : 0.;
235 mae = (count != 0) ? absoluteValueOfDifferences /
static_cast<RealType>(count) : 0.;
238 psnr = (std::abs(mse) > 0.0000000001 && (maximumRef - minimumRef) > 0.0000000001)
239 ? 10. * std::log10(((maximumRef - minimumRef) * (maximumRef - minimumRef)) / mse)
242 this->GetMSEOutput()->Set(mse);
243 this->GetMAEOutput()->Set(mae);
244 this->GetPSNROutput()->Set(psnr);
245 this->GetDiffCountOutput()->Set(
static_cast<RealType>(diffCount));
248 template <
class TInputImage>
251 int numberOfThreads = this->GetNumberOfWorkUnits();
254 m_Count.SetSize(numberOfThreads);
255 m_DiffCount.SetSize(numberOfThreads);
256 m_SquareOfDifferences.SetSize(numberOfThreads);
257 m_AbsoluteValueOfDifferences.SetSize(numberOfThreads);
259 m_ThreadMinRef.SetSize(numberOfThreads);
260 m_ThreadMaxRef.SetSize(numberOfThreads);
263 m_Count.Fill(itk::NumericTraits<long>::Zero);
264 m_DiffCount.Fill(itk::NumericTraits<long>::Zero);
265 m_SquareOfDifferences.Fill(itk::NumericTraits<RealType>::Zero);
266 m_AbsoluteValueOfDifferences.Fill(itk::NumericTraits<RealType>::Zero);
267 m_ThreadMinRef.Fill(itk::NumericTraits<PixelType>::max());
268 m_ThreadMaxRef.Fill(itk::NumericTraits<PixelType>::NonpositiveMin());
271 template <
class TInputImage>
274 if (m_PhysicalSpaceCheck)
275 Superclass::VerifyInputInformation();
278 template <
class TInputImage>
289 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
294 itk::ImageRegionConstIterator<TInputImage> it1(inputPtr1, outputRegionForThread);
295 itk::ImageRegionConstIterator<TInputImage> it2(inputPtr2, outputRegionForThread);
300 while (!it1.IsAtEnd() && !it2.IsAtEnd())
303 realValue1 =
static_cast<RealType>(value1);
306 realValue2 =
static_cast<RealType>(value2);
308 if (value1 < m_ThreadMinRef[threadId])
310 m_ThreadMinRef[threadId] = value1;
312 if (value1 > m_ThreadMaxRef[threadId])
314 m_ThreadMaxRef[threadId] = value1;
317 RealType diffVal = realValue1 - realValue2;
318 m_SquareOfDifferences[threadId] += diffVal * diffVal;
319 m_AbsoluteValueOfDifferences[threadId] += std::abs(diffVal);
320 if (!itk::Math::FloatAlmostEqual(realValue1, realValue2))
322 m_DiffCount[threadId]++;
327 progress.CompletedPixel();
330 template <
class TImage>
333 Superclass::PrintSelf(os, indent);
335 os << indent <<
"PSNR: " << this->GetPSNR() << std::endl;
336 os << indent <<
"MSE: " << this->GetMSE() << std::endl;
337 os << indent <<
"MAE: " << this->GetMAE() << std::endl;
338 os << indent <<
"Count: " << this->GetDiffCount() << std::endl;
RealObjectType * GetDiffCountOutput()
void AllocateOutputs() override
void Reset(void) override
const TInputImage * GetInput2()
RealObjectType * GetMAEOutput()
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
void Synthetize(void) override
void SetInput2(const TInputImage *image)
void SetInput1(const TInputImage *image)
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
TInputImage::Pointer InputImagePointer
itk::NumericTraits< PixelType >::RealType RealType
const TInputImage * GetInput1()
void VerifyInputInformation() const override
RealObjectType * GetMSEOutput()
TInputImage::RegionType RegionType
void GenerateOutputInformation() override
RealObjectType * GetPSNROutput()
PersistentCompareImageFilter()
itk::SimpleDataObjectDecorator< RealType > RealObjectType
TInputImage::PixelType PixelType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.