From 91772230f030ccd0c9157e3f8380cfb35f62c88d Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 5 May 2026 12:40:53 +0200 Subject: [PATCH 1/4] STYLE: Declare NormalizeJointPDF static `ParzenWindowHistogramImageToImageMetric::NormalizeJointPDF` does not use `this`. Following MISRA-C++ Rule "If a member function can be made static then it shall be made static" and https://clang.llvm.org/extra/clang-tidy/checks/readability/convert-member-functions-to-static.html --- .../itkParzenWindowHistogramImageToImageMetric.h | 4 ++-- .../itkParzenWindowHistogramImageToImageMetric.hxx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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..8355c64dd 100644 --- a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx +++ b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx @@ -606,7 +606,7 @@ ParzenWindowHistogramImageToImageMetric::UpdateJointP template void ParzenWindowHistogramImageToImageMetric::NormalizeJointPDF(JointPDFType * pdf, - const double factor) const + const double factor) { using JointPDFIteratorType = ImageScanlineIterator; JointPDFIteratorType it(pdf, pdf->GetBufferedRegion()); From 19011dee6c7415c27354698c7b77c8720fd5f2c1 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 5 May 2026 12:43:22 +0200 Subject: [PATCH 2/4] ENH: Add NormalizeJointPDF unit test Added GTEST_TEST(ParzenWindowHistogramImageToImageMetric, NormalizeJointPDF) --- Common/GTesting/CMakeLists.txt | 1 + ...WindowHistogramImageToImageMetricGTest.cxx | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 Common/GTesting/itkParzenWindowHistogramImageToImageMetricGTest.cxx 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); + } +} From 7414ccaad30a44c86cc93d3fd2bb583fe008af05 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 5 May 2026 12:47:17 +0200 Subject: [PATCH 3/4] STYLE: Call NormalizeJointPDF in the static way Replaced `this->NormalizeJointPDF` with `Superclass::NormalizeJointPDF`. --- .../itkParzenWindowMutualInformationImageToImageMetric.hxx | 6 +++--- ...nWindowNormalizedMutualInformationImageToImageMetric.hxx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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); From 432044f8940a50f1a83826b0b0e3b0b3b4cd37e9 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Tue, 5 May 2026 12:58:47 +0200 Subject: [PATCH 4/4] STYLE: Use ImageBufferRange in NormalizeJointPDF Simplified the implementation, and probably made it faster. --- .../itkParzenWindowHistogramImageToImageMetric.hxx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx b/Common/CostFunctions/itkParzenWindowHistogramImageToImageMetric.hxx index 8355c64dd..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 @@ -608,17 +609,9 @@ void ParzenWindowHistogramImageToImageMetric::NormalizeJointPDF(JointPDFType * pdf, 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()