From e7b5ec17faec73838608b4d3bbd56c75c5d59241 Mon Sep 17 00:00:00 2001 From: Axel Garcia Date: Fri, 22 May 2026 15:33:51 +0200 Subject: [PATCH] ENH: Remove rtkAdditiveGaussianNoiseImageFilter to use the itk version --- .../rtkdrawgeometricphantom.cxx | 4 +- .../rtkdrawgeometricphantom.py | 2 +- .../rtkdrawshepploganphantom.cxx | 4 +- .../rtkdrawshepploganphantom.py | 2 +- .../rtkprojectshepploganphantom.cxx | 1 - include/rtkAdditiveGaussianNoiseImageFilter.h | 324 ------------------ .../rtkAdditiveGaussianNoiseImageFilter.hxx | 79 ----- include/rtkGgoFunctions.h | 6 +- test/rtkrampfiltertest.cxx | 4 +- 9 files changed, 11 insertions(+), 415 deletions(-) delete mode 100644 include/rtkAdditiveGaussianNoiseImageFilter.h delete mode 100644 include/rtkAdditiveGaussianNoiseImageFilter.hxx diff --git a/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.cxx b/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.cxx index 75c56f680..ea6bee37b 100644 --- a/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.cxx +++ b/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.cxx @@ -18,10 +18,10 @@ #include "rtkdrawgeometricphantom_ggo.h" #include "itkImageFileWriter.h" -#include "rtkAdditiveGaussianNoiseImageFilter.h" #include "rtkDrawGeometricPhantomImageFilter.h" #include "rtkGgoFunctions.h" +#include int main(int argc, char * argv[]) @@ -93,7 +93,7 @@ main(int argc, char * argv[]) OutputImageType::Pointer output = dq->GetOutput(); if (args_info.noise_given) { - auto noisy = rtk::AdditiveGaussianNoiseImageFilter::New(); + auto noisy = itk::AdditiveGaussianNoiseImageFilter::New(); noisy->SetInput(output); noisy->SetMean(0.0); noisy->SetStandardDeviation(args_info.noise_arg); diff --git a/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.py b/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.py index a50a522e3..76b7ea5e7 100644 --- a/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.py +++ b/applications/rtkdrawgeometricphantom/rtkdrawgeometricphantom.py @@ -100,7 +100,7 @@ def process(args_info: argparse.Namespace): # Add noise output = dq.GetOutput() if args_info.noise: - noisy = rtk.AdditiveGaussianNoiseImageFilter[OutputImageType].New() + noisy = itk.AdditiveGaussianNoiseImageFilter[OutputImageType].New() noisy.SetInput(output) noisy.SetMean(0.0) noisy.SetStandardDeviation(args_info.noise) diff --git a/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.cxx b/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.cxx index 352e14c43..9e93fb883 100644 --- a/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.cxx +++ b/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.cxx @@ -19,11 +19,11 @@ #include "rtkdrawshepploganphantom_ggo.h" #include "rtkGgoFunctions.h" -#include "rtkAdditiveGaussianNoiseImageFilter.h" #include "rtkConstantImageSource.h" #include "rtkDrawSheppLoganFilter.h" #include "rtkSheppLoganPhantomFilter.h" +#include #include #include @@ -62,7 +62,7 @@ main(int argc, char * argv[]) OutputImageType::Pointer output = dsl->GetOutput(); if (args_info.noise_given) { - auto noisy = rtk::AdditiveGaussianNoiseImageFilter::New(); + auto noisy = itk::AdditiveGaussianNoiseImageFilter::New(); noisy->SetInput(output); noisy->SetMean(0.0); noisy->SetStandardDeviation(args_info.noise_arg); diff --git a/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.py b/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.py index 5cc0e2749..815dc3fd8 100644 --- a/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.py +++ b/applications/rtkdrawshepploganphantom/rtkdrawshepploganphantom.py @@ -77,7 +77,7 @@ def process(args_info: argparse.Namespace): # Add noise output = dsl.GetOutput() if args_info.noise: - noisy = rtk.AdditiveGaussianNoiseImageFilter[OutputImageType].New() + noisy = itk.AdditiveGaussianNoiseImageFilter[OutputImageType].New() noisy.SetInput(output) noisy.SetMean(0.0) noisy.SetStandardDeviation(args_info.noise) diff --git a/applications/rtkprojectshepploganphantom/rtkprojectshepploganphantom.cxx b/applications/rtkprojectshepploganphantom/rtkprojectshepploganphantom.cxx index 2f3be8bce..75badac3f 100644 --- a/applications/rtkprojectshepploganphantom/rtkprojectshepploganphantom.cxx +++ b/applications/rtkprojectshepploganphantom/rtkprojectshepploganphantom.cxx @@ -17,7 +17,6 @@ *=========================================================================*/ #include "rtkprojectshepploganphantom_ggo.h" -#include "rtkAdditiveGaussianNoiseImageFilter.h" #include "rtkGgoFunctions.h" #include "rtkRayEllipsoidIntersectionImageFilter.h" #include "rtkSheppLoganPhantomFilter.h" diff --git a/include/rtkAdditiveGaussianNoiseImageFilter.h b/include/rtkAdditiveGaussianNoiseImageFilter.h deleted file mode 100644 index a29529e13..000000000 --- a/include/rtkAdditiveGaussianNoiseImageFilter.h +++ /dev/null @@ -1,324 +0,0 @@ -/*========================================================================= - * - * Copyright RTK Consortium - * - * 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 - * - * https://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. - * - *=========================================================================*/ - -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://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. - * - *=========================================================================*/ -#ifndef rtkAdditiveGaussianNoiseImageFilter_h -#define rtkAdditiveGaussianNoiseImageFilter_h - -#include -#include -#include - -#include "rtkMacro.h" - -namespace rtk -{ - -/** \class NormalVariateNoiseFunctor - * - * \brief Pixel functor that adds Gaussian noise. - * - * \author Gavin Baker: gavinb at cs_mu_oz_au - * - * \ingroup RTK - */ -template -class ITK_TEMPLATE_EXPORT NormalVariateNoiseFunctor -{ -public: - NormalVariateNoiseFunctor() - { - m_Mean = 0.0; - m_StandardDeviation = 1.0; - - m_Generator = itk::Statistics::NormalVariateGenerator::New(); - - this->SetSeed(42); - } - - [[nodiscard]] float - GetMean() const - { - return m_Mean; - } - - void - SetMean(float mean) - { - m_Mean = mean; - } - - [[nodiscard]] float - GetStandardDeviation() const - { - return m_StandardDeviation; - } - - void - SetStandardDeviation(float stddev) - { - m_StandardDeviation = stddev; - } - - void - SetSeed(unsigned long seed) - { - m_Generator->Initialize(seed); - } - - void - SetOutputMinimum(TPixel min) - { - m_OutputMinimum = min; - } - - void - SetOutputMaximum(TPixel max) - { - m_OutputMaximum = max; - } - - TPixel - GetOutputMinimum() const - { - return m_OutputMinimum; - } - - TPixel - GetOutputMaximum() const - { - return m_OutputMaximum; - } - - TPixel - operator()(TPixel input) - { - // Get the minimum and maximum output values - static const auto min = static_cast(m_OutputMinimum); - static const auto max = static_cast(m_OutputMaximum); - - // Compute the output - float output = static_cast(input) + m_Mean + m_StandardDeviation * m_Generator->GetVariate(); - - // Clamp the output value in valid range - output = (output < min ? min : output); - output = (output > max ? max : output); - - return static_cast(output); - } - -private: - TPixel m_OutputMinimum; - TPixel m_OutputMaximum; - float m_Mean; - float m_StandardDeviation; - itk::Statistics::NormalVariateGenerator::Pointer m_Generator; -}; - - -/** \class AdditiveGaussianNoiseImageFilter - * \brief Adds Gaussian noise to the input image - * - * Adds noise to the input image according to a Gaussian normal variate - * distribution. The user supplies the mean \f$\bar{x}\f$ and standard - * deviation \f$\sigma\f$, such that the output is given by: - * - * \f[ - * v_{out} = v_{in} + \bar{x} + \sigma * G(d) - * \f] - * - * where G() is the Gaussian generator and d is the seed. A particular seed - * can be specified in order to perform repeatable tests. - * - * \test rtkrampfiltertest.cxx - * - * \author Gavin Baker: gavinb at cs_mu_oz_au - * - * \ingroup RTK ImageToImageFilter - */ -template -class ITK_TEMPLATE_EXPORT AdditiveGaussianNoiseImageFilter : public itk::ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_MOVE(AdditiveGaussianNoiseImageFilter); - - /** Standard class type alias. */ - using Self = AdditiveGaussianNoiseImageFilter; - using Superclass = itk::ImageToImageFilter; - using Pointer = itk::SmartPointer; - using ConstPointer = itk::SmartPointer; - - /** Method for creation through the object factory */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkOverrideGetNameOfClassMacro(AdditiveGaussianNoiseImageFilter); - - /** Superclass type alias. */ - using OutputImageRegionType = typename Superclass::OutputImageRegionType; - using OutputImagePointer = typename Superclass::OutputImagePointer; - - /** Some convenient type alias. */ - using InputImageType = TInputImage; - using InputImagePointer = typename InputImageType::Pointer; - using InputImageConstPointer = typename InputImageType::ConstPointer; - using InputImageRegionType = typename InputImageType::RegionType; - using InputImagePixelType = typename InputImageType::PixelType; - using InputPixelType = typename InputImageType::PixelType; - - /** ImageDimension constants */ - static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension; - - // virtual void GenerateOutputInformation(); - - void - GenerateData() override; - - // Accessor & Mutator methods - - /** - * Specifies the average noise added to the image per pixel. - * The default is 0. - */ - void - SetMean(float mean) - { - m_NoiseFilter->GetFunctor().SetMean(mean); - this->Modified(); - } - - /** - * Returns the average noise added to the image per pixel. - * The default is 0. - */ - [[nodiscard]] float - GetMean() const - { - return m_NoiseFilter->GetFunctor().GetMean(); - } - - /** - * Specifies the standard deviation of the noise added to the image. - * The default is 1. - */ - void - SetStandardDeviation(float stddev) - { - m_NoiseFilter->GetFunctor().SetStandardDeviation(stddev); - this->Modified(); - } - - /** - * Returns the standard deviation of the noise added to the image. - * The default is 1. - */ - [[nodiscard]] float - GetStandardDeviation() const - { - return m_NoiseFilter->GetFunctor().GetStandardDeviation(); - } - - /** - * Specifies the seed for the normal variate generator. The same seed - * will produce the same pseduo-random sequence, which can be used to - * reproduce results. For a higher dose of entropy, initialise with - * the current system time (in ms). - */ - void - SetSeed(unsigned long seed) - { - m_NoiseFilter->GetFunctor().SetSeed(seed); - this->Modified(); - } - - /** Set the minimum output value. */ - void - SetOutputMinimum(InputImagePixelType min) - { - if (min == m_NoiseFilter->GetFunctor().GetOutputMinimum()) - { - return; - } - m_NoiseFilter->GetFunctor().SetOutputMinimum(min); - this->Modified(); - } - - /** Get the minimum output value. */ - InputImagePixelType - GetOutputMinimum() - { - return m_NoiseFilter->GetFunctor().GetOutputMinimum(); - } - - /** Set the maximum output value. */ - void - SetOutputMaximum(InputImagePixelType max) - { - if (max == m_NoiseFilter->GetFunctor().GetOutputMaximum()) - { - return; - } - m_NoiseFilter->GetFunctor().SetOutputMaximum(max); - this->Modified(); - } - - /** Get the maximum output value. */ - InputImagePixelType - GetOutputMaximum() - { - return m_NoiseFilter->GetFunctor().GetOutputMaximum(); - } - -protected: - AdditiveGaussianNoiseImageFilter(); - - void - PrintSelf(std::ostream & os, itk::Indent indent) const override; - -public: - using NoiseFilterType = itk::UnaryFunctorImageFilter>; - -private: - typename NoiseFilterType::Pointer m_NoiseFilter; -}; - -} /* end namespace rtk */ - -#ifndef ITK_MANUAL_INSTANTIATION -# include "rtkAdditiveGaussianNoiseImageFilter.hxx" -#endif - -#endif /* rtkAdditiveGaussianNoiseImageFilter_h */ diff --git a/include/rtkAdditiveGaussianNoiseImageFilter.hxx b/include/rtkAdditiveGaussianNoiseImageFilter.hxx deleted file mode 100644 index c0f028909..000000000 --- a/include/rtkAdditiveGaussianNoiseImageFilter.hxx +++ /dev/null @@ -1,79 +0,0 @@ -/*========================================================================= - * - * Copyright RTK Consortium - * - * 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 - * - * https://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. - * - *=========================================================================*/ - -/*========================================================================= - * - * Copyright NumFOCUS - * - * 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 - * - * https://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. - * - *=========================================================================*/ -#ifndef rtkAdditiveGaussianNoiseImageFilter_hxx -#define rtkAdditiveGaussianNoiseImageFilter_hxx - - -namespace rtk -{ - -template -AdditiveGaussianNoiseImageFilter::AdditiveGaussianNoiseImageFilter() -{ - m_NoiseFilter = NoiseFilterType::New(); - m_NoiseFilter->GetFunctor().SetOutputMinimum(itk::NumericTraits::NonpositiveMin()); - m_NoiseFilter->GetFunctor().SetOutputMaximum(itk::NumericTraits::max()); -} - - -template -void -AdditiveGaussianNoiseImageFilter::GenerateData() -{ - this->AllocateOutputs(); - - // Set the global max number of threads to 1 - // NOTE: This is required because there is a bug with this filter, - // it appears the NormalVariateGenerate is single threaded only. - m_NoiseFilter->SetNumberOfWorkUnits(1); - - // Setup grafted pipeline for composite filter - m_NoiseFilter->SetInput(this->GetInput()); - m_NoiseFilter->Update(); - this->GraftOutput(m_NoiseFilter->GetOutput()); -} - -template -void -AdditiveGaussianNoiseImageFilter::PrintSelf(std::ostream & os, itk::Indent indent) const -{ - os << indent << "AdditiveGaussianNoiseImageFilter" - << "\n Mean: " << this->GetMean() << "\n StandardDeviation: " << this->GetStandardDeviation() << std::endl; -} - -} /* namespace rtk */ - -#endif // rtkAdditiveGaussianNoiseImageFilter_hxx diff --git a/include/rtkGgoFunctions.h b/include/rtkGgoFunctions.h index 0773b7cea..db5ca0702 100644 --- a/include/rtkGgoFunctions.h +++ b/include/rtkGgoFunctions.h @@ -33,7 +33,7 @@ #include #include #include -#include "rtkAdditiveGaussianNoiseImageFilter.h" +#include namespace rtk { @@ -326,7 +326,7 @@ AddNoiseFromGgo(typename TImageType::Pointer projections, const TArgsInfo & args auto multiply3 = itk::MultiplyImageFilter::New(); // Gaussian noise - auto gaussian = rtk::AdditiveGaussianNoiseImageFilter::New(); + auto gaussian = itk::AdditiveGaussianNoiseImageFilter::New(); if (args_info.gaussian_given) { gaussian->SetInput(threshold->GetOutput()); @@ -349,7 +349,7 @@ AddNoiseFromGgo(typename TImageType::Pointer projections, const TArgsInfo & args } else if (args_info.gaussian_given) { - auto gaussian = rtk::AdditiveGaussianNoiseImageFilter::New(); + auto gaussian = itk::AdditiveGaussianNoiseImageFilter::New(); gaussian->SetInput(newproj); gaussian->SetStandardDeviation(args_info.gaussian_arg); diff --git a/test/rtkrampfiltertest.cxx b/test/rtkrampfiltertest.cxx index a03a1701d..313183794 100644 --- a/test/rtkrampfiltertest.cxx +++ b/test/rtkrampfiltertest.cxx @@ -1,6 +1,6 @@ +#include #include -#include "rtkAdditiveGaussianNoiseImageFilter.h" #include "rtkConstantImageSource.h" #include "rtkDrawSheppLoganFilter.h" #include "rtkSheppLoganPhantomFilter.h" @@ -87,7 +87,7 @@ rtkrampfiltertest(int, char *[]) std::cout << "\n\n****** Test 1: add noise and test Hann window ******" << std::endl; // Add noise - auto noisy = rtk::AdditiveGaussianNoiseImageFilter::New(); + auto noisy = itk::AdditiveGaussianNoiseImageFilter::New(); noisy->SetInput(slp->GetOutput()); noisy->SetMean(0.0); noisy->SetStandardDeviation(1.);