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->SetNumberOfRequiredInputs(2);
43 for (
int i = 1; i < 5; ++i)
46 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
49 this->
GetPSNROutput()->Set(itk::NumericTraits<RealType>::max());
50 this->
GetMSEOutput()->Set(itk::NumericTraits<RealType>::max());
51 this->
GetMAEOutput()->Set(itk::NumericTraits<RealType>::max());
60 template <
class TInputImage>
64 this->SetNthInput(0,
const_cast<TInputImage*
>(image));
70 template <
class TInputImage>
74 this->SetNthInput(1,
const_cast<TInputImage*
>(image));
77 template <
class TInputImage>
80 if (this->GetNumberOfInputs() < 1)
84 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(0));
87 template <
class TInputImage>
90 if (this->GetNumberOfInputs() < 2)
94 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(1));
97 template <
class TInputImage>
103 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
109 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
113 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
118 template <
class TInputImage>
121 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(1));
124 template <
class TInputImage>
127 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(1));
130 template <
class TInputImage>
133 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(2));
136 template <
class TInputImage>
139 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(2));
142 template <
class TInputImage>
145 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
148 template <
class TInputImage>
151 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
154 template <
class TInputImage>
157 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
160 template <
class TInputImage>
163 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
166 template <
class TInputImage>
169 Superclass::GenerateOutputInformation();
170 if (this->GetInput())
172 this->GetOutput()->CopyInformation(this->GetInput());
173 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
175 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
177 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
181 template <
class TInputImage>
191 template <
class TInputImage>
196 unsigned long diffCount;
197 RealType squareOfDifferences, absoluteValueOfDifferences;
199 int numberOfThreads = this->GetNumberOfThreads();
206 squareOfDifferences = absoluteValueOfDifferences = itk::NumericTraits<RealType>::Zero;
211 minimumRef = itk::NumericTraits<PixelType>::max();
212 maximumRef = itk::NumericTraits<PixelType>::NonpositiveMin();
214 for (i = 0; i < numberOfThreads; ++i)
217 diffCount += m_DiffCount[i];
218 squareOfDifferences += m_SquareOfDifferences[i];
219 absoluteValueOfDifferences += m_AbsoluteValueOfDifferences[i];
221 if (m_ThreadMinRef[i] < minimumRef)
223 minimumRef = m_ThreadMinRef[i];
225 if (m_ThreadMaxRef[i] > maximumRef)
227 maximumRef = m_ThreadMaxRef[i];
232 mse = (count != 0) ? squareOfDifferences /
static_cast<RealType>(count) : 0.;
234 mae = (count != 0) ? absoluteValueOfDifferences /
static_cast<RealType>(count) : 0.;
237 psnr = (std::abs(mse) > 0.0000000001 && (maximumRef - minimumRef) > 0.0000000001)
238 ? 10. * std::log10(((maximumRef - minimumRef) * (maximumRef - minimumRef)) / mse)
241 this->GetMSEOutput()->Set(mse);
242 this->GetMAEOutput()->Set(mae);
243 this->GetPSNROutput()->Set(psnr);
244 this->GetDiffCountOutput()->Set(
static_cast<RealType>(diffCount));
247 template <
class TInputImage>
250 int numberOfThreads = this->GetNumberOfThreads();
253 m_Count.SetSize(numberOfThreads);
254 m_DiffCount.SetSize(numberOfThreads);
255 m_SquareOfDifferences.SetSize(numberOfThreads);
256 m_AbsoluteValueOfDifferences.SetSize(numberOfThreads);
258 m_ThreadMinRef.SetSize(numberOfThreads);
259 m_ThreadMaxRef.SetSize(numberOfThreads);
262 m_Count.Fill(itk::NumericTraits<long>::Zero);
263 m_DiffCount.Fill(itk::NumericTraits<long>::Zero);
264 m_SquareOfDifferences.Fill(itk::NumericTraits<RealType>::Zero);
265 m_AbsoluteValueOfDifferences.Fill(itk::NumericTraits<RealType>::Zero);
266 m_ThreadMinRef.Fill(itk::NumericTraits<PixelType>::max());
267 m_ThreadMaxRef.Fill(itk::NumericTraits<PixelType>::NonpositiveMin());
270 template <
class TInputImage>
273 if (m_PhysicalSpaceCheck)
274 Superclass::VerifyInputInformation();
277 template <
class TInputImage>
288 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
293 itk::ImageRegionConstIterator<TInputImage> it1(inputPtr1, outputRegionForThread);
294 itk::ImageRegionConstIterator<TInputImage> it2(inputPtr2, outputRegionForThread);
299 while (!it1.IsAtEnd() && !it2.IsAtEnd())
302 realValue1 =
static_cast<RealType>(value1);
305 realValue2 =
static_cast<RealType>(value2);
307 if (value1 < m_ThreadMinRef[threadId])
309 m_ThreadMinRef[threadId] = value1;
311 if (value1 > m_ThreadMaxRef[threadId])
313 m_ThreadMaxRef[threadId] = value1;
316 RealType diffVal = realValue1 - realValue2;
317 m_SquareOfDifferences[threadId] += diffVal * diffVal;
318 m_AbsoluteValueOfDifferences[threadId] += std::abs(diffVal);
319 if (!itk::Math::FloatAlmostEqual(realValue1, realValue2))
321 m_DiffCount[threadId]++;
326 progress.CompletedPixel();
329 template <
class TImage>
332 Superclass::PrintSelf(os, indent);
334 os << indent <<
"PSNR: " << this->GetPSNR() << std::endl;
335 os << indent <<
"MSE: " << this->GetMSE() << std::endl;
336 os << indent <<
"MAE: " << this->GetMAE() << std::endl;
337 os << indent <<
"Count: " << this->GetDiffCount() << std::endl;