diff --git a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.h b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.h index eaf228884..2c3d434e8 100644 --- a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.h +++ b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.h @@ -305,8 +305,8 @@ class ITK_TEMPLATE_EXPORT ParzenWindowHistogramImageToImageMetric PDFValueType * parzenValues); /** Multiply the pdf entries by the given normalization factor. */ - void - NormalizeJointPDF(JointPDFType * pdf, const double factor) const; + static void + NormalizeJointPDF(JointPDFType * pdf, const double factor); /** Compute marginal pdfs by summing over the joint pdf * direction = 0: fixed marginal pdf diff --git a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx index 4d348518e..9e24ca20c 100644 --- a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx +++ b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx @@ -24,6 +24,7 @@ #include "itkBSplineDerivativeKernelFunction2.h" #include "itkImageLinearIteratorWithIndex.h" #include "itkImageScanlineIterator.h" +#include #include #include @@ -606,19 +607,11 @@ ParzenWindowHistogramImageToImageMetric::UpdateJointP template void ParzenWindowHistogramImageToImageMetric::NormalizeJointPDF(JointPDFType * pdf, - const double factor) const + const double factor) { - using JointPDFIteratorType = ImageScanlineIterator; - JointPDFIteratorType it(pdf, pdf->GetBufferedRegion()); - const auto castfac = static_cast(factor); - while (!it.IsAtEnd()) + for (PDFValueType & pdfValue : ImageBufferRange(*pdf)) { - while (!it.IsAtEndOfLine()) - { - it.Value() *= castfac; - ++it; - } - it.NextLine(); + pdfValue *= factor; } } // end NormalizeJointPDF() diff --git a/Common/GTesting/CMakeLists.txt b/Common/GTesting/CMakeLists.txt index a24713ece..9c60484a2 100644 --- a/Common/GTesting/CMakeLists.txt +++ b/Common/GTesting/CMakeLists.txt @@ -21,6 +21,7 @@ set(ELX_COMMON_GTEST_SOURCES itkImageRandomSamplerSparseMaskGTest.cxx itkImageSamplerGTest.cxx itkParameterMapInterfaceTest.cxx + itkParzenWindowHistogramImageToImageMetricGTest.cxx ) if(USE_ImpactMetric) diff --git a/Common/GTesting/itkParzenWindowHistogramImageToImageMetricGTest.cxx b/Common/GTesting/itkParzenWindowHistogramImageToImageMetricGTest.cxx new file mode 100644 index 000000000..638d6b232 --- /dev/null +++ b/Common/GTesting/itkParzenWindowHistogramImageToImageMetricGTest.cxx @@ -0,0 +1,64 @@ +/*========================================================================= + * + * Copyright UMC Utrecht and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + +// First include the header file to be tested: +#include "itkParzenWindowHistogramImageToImageMetric.h" +#include +#include "GTesting/elxCoreMainGTestUtilities.h" +#include + +// The template to be tested. +using itk::ParzenWindowHistogramImageToImageMetric; +using elx::CoreMainGTestUtilities::CreateImageFilledWithSequenceOfNaturalNumbers; + + +// Checks the protected member function NormalizeJointPDF. +GTEST_TEST(ParzenWindowHistogramImageToImageMetric, NormalizeJointPDF) +{ + using ImageType = itk::Image; + using ParzenWindowHistogramImageToImageMetricType = ParzenWindowHistogramImageToImageMetric; + + class DerivedMetric : ParzenWindowHistogramImageToImageMetricType + { + public: + static void + TestNormalizeJointPDF(const double factor) + { + const auto pdf = CreateImageFilledWithSequenceOfNaturalNumbers(itk::Size<>{ 4, 5 }); + + const itk::ImageBufferRange imageBufferRange(*pdf); + + const std::vector originalPDFValues(imageBufferRange.cbegin(), imageBufferRange.cend()); + + ParzenWindowHistogramImageToImageMetricType::NormalizeJointPDF(pdf, factor); + + auto originalPDFValueIterator = originalPDFValues.cbegin(); + + for (const PDFValueType pixelValue : imageBufferRange) + { + EXPECT_EQ(pixelValue, *originalPDFValueIterator * factor); + ++originalPDFValueIterator; + } + } + }; + + for (const auto factor : { 0.0, 0.5, 1.0 }) + { + DerivedMetric::TestNormalizeJointPDF(factor); + } +} diff --git a/Components/Metrics/AdvancedMattesMutualInformation/itkParzenWindowMutualInformationImageToImageMetric.hxx b/Components/Metrics/AdvancedMattesMutualInformation/itkParzenWindowMutualInformationImageToImageMetric.hxx index fd4ac720d..4dcfa7129 100644 --- a/Components/Metrics/AdvancedMattesMutualInformation/itkParzenWindowMutualInformationImageToImageMetric.hxx +++ b/Components/Metrics/AdvancedMattesMutualInformation/itkParzenWindowMutualInformationImageToImageMetric.hxx @@ -78,7 +78,7 @@ ParzenWindowMutualInformationImageToImageMetric::GetV this->ComputePDFs(parameters); /** Normalize the pdfs: p = alpha h. */ - this->NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); + Superclass::NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); /** Compute the fixed and moving marginal pdfs, by summing over the joint pdf. */ this->ComputeMarginalPDF(this->m_JointPDF, this->m_FixedImageMarginalPDF, 0); @@ -156,7 +156,7 @@ ParzenWindowMutualInformationImageToImageMetric::GetV this->ComputePDFsAndPDFDerivatives(parameters); /** Normalize the pdfs: p = alpha h. */ - this->NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); + Superclass::NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); /** Compute the fixed and moving marginal pdf by summing over the histogram. */ this->ComputeMarginalPDF(this->m_JointPDF, this->m_FixedImageMarginalPDF, 0); @@ -245,7 +245,7 @@ ParzenWindowMutualInformationImageToImageMetric::GetV this->ComputePDFs(parameters); /** Normalize the joint histogram by alpha. */ - this->NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); + Superclass::NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); /** Compute the fixed and moving marginal pdf by summing over the histogram. */ this->ComputeMarginalPDF(this->m_JointPDF, this->m_FixedImageMarginalPDF, 0); diff --git a/Components/Metrics/NormalizedMutualInformation/itkParzenWindowNormalizedMutualInformationImageToImageMetric.hxx b/Components/Metrics/NormalizedMutualInformation/itkParzenWindowNormalizedMutualInformationImageToImageMetric.hxx index 183640f3d..43f1e52b5 100644 --- a/Components/Metrics/NormalizedMutualInformation/itkParzenWindowNormalizedMutualInformationImageToImageMetric.hxx +++ b/Components/Metrics/NormalizedMutualInformation/itkParzenWindowNormalizedMutualInformationImageToImageMetric.hxx @@ -146,7 +146,7 @@ ParzenWindowNormalizedMutualInformationImageToImageMetricComputePDFs(parameters); /** Normalize the pdfs: p = alpha h */ - this->NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); + Superclass::NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); /** Compute the fixed and moving marginal pdfs, by summing over the joint pdf */ this->ComputeMarginalPDF(this->m_JointPDF, this->m_FixedImageMarginalPDF, 0); @@ -186,7 +186,7 @@ ParzenWindowNormalizedMutualInformationImageToImageMetricComputePDFsAndPDFDerivatives(parameters); /** Normalize the pdfs: p = alpha h*/ - this->NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); + Superclass::NormalizeJointPDF(this->m_JointPDF, this->m_Alpha); /** Compute the fixed and moving marginal pdf by summing over the histogram */ this->ComputeMarginalPDF(this->m_JointPDF, this->m_FixedImageMarginalPDF, 0);