From b45e75a649dbd2c66627680b08f61db4cdfd69b5 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 12 Nov 2017 21:07:45 -0700 Subject: [PATCH 001/150] DOC: Setup project from ITKModuleTemplate --- .../Filtering/BoneEnhancement/CMakeLists.txt | 5 + ...itkMinimalStandardRandomVariateGenerator.h | 94 +++++++++++++++++++ .../itkNormalDistributionImageSource.h | 92 ++++++++++++++++++ .../itkNormalDistributionImageSource.hxx | 79 ++++++++++++++++ .../BoneEnhancement/itk-module.cmake | 24 +++++ .../BoneEnhancement/src/CMakeLists.txt | 5 + ...kMinimalStandardRandomVariateGenerator.cxx | 52 ++++++++++ ...stributionImageSourceTestOutput.mha.sha512 | 1 + .../BoneEnhancement/test/CMakeLists.txt | 28 ++++++ ...imalStandardRandomVariateGeneratorTest.cxx | 37 ++++++++ .../itkNormalDistributionImageSourceTest.cxx | 67 +++++++++++++ .../BoneEnhancement/wrapping/CMakeLists.txt | 3 + ...MinimalStandardRandomVariateGenerator.wrap | 1 + .../itkNormalDistributionImageSource.wrap | 7 ++ 14 files changed, 495 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/CMakeLists.txt create mode 100644 Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx create mode 100644 Modules/Filtering/BoneEnhancement/itk-module.cmake create mode 100644 Modules/Filtering/BoneEnhancement/src/CMakeLists.txt create mode 100644 Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 create mode 100644 Modules/Filtering/BoneEnhancement/test/CMakeLists.txt create mode 100644 Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/CMakeLists.txt create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap diff --git a/Modules/Filtering/BoneEnhancement/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/CMakeLists.txt new file mode 100644 index 00000000000..24fc4f8865d --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/CMakeLists.txt @@ -0,0 +1,5 @@ +project(BoneEnhancement) + +set(BoneEnhancement_LIBRARIES BoneEnhancement) + +itk_module_impl() diff --git a/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h b/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h new file mode 100644 index 00000000000..c2da8080795 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h @@ -0,0 +1,94 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkMinimalStandardRandomVariateGenerator_h +#define itkMinimalStandardRandomVariateGenerator_h + +#include "itkIntTypes.h" +#include "itkObjectFactory.h" +#include "itkRandomVariateGeneratorBase.h" +#include "BoneEnhancementExport.h" +#include "itkNormalVariateGenerator.h" + +namespace itk +{ +namespace Statistics +{ +/** \class MinimalStandardRandomVariateGenerator + * \brief Linear congruential random random variate generator. + * + * This is a pseudo-random number generator for unsigned integers following + * + * \f[ + * X_{n+1} = (a X_n + c) \mod m + * \f] + * + * where \f$a\f$ is the Multiplier \f$c\f$ is the Increment and \f$m\f$ is + * the Modulus. + * + * http://en.wikipedia.com/wiki/Linear_congruential_generator + * + * The random numbers generated have a period \f$m\f$. + * + * This class uses \f$a = 48271\f$, \f$c = 0\f$, \f$m = 2^31 -1 = + * 2147483647\f$, the Minimial Standard configuration recommended by Park, + * Miller and Stockmeyer in 1993. + * + * \ingroup BoneEnhancement + */ +class BoneEnhancement_EXPORT MinimalStandardRandomVariateGenerator : public RandomVariateGeneratorBase +{ +public: + /** Standard class typedefs. */ + typedef MinimalStandardRandomVariateGenerator Self; + typedef RandomVariateGeneratorBase Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + typedef uint32_t IntegerType; + + typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType; + + /** Run-time type information (and related methods). */ + itkTypeMacro(MinimalStandardRandomVariateGenerator, RandomVariateGeneratorBase); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** initialize with a simple IntegerType */ + void + Initialize(int randomSeed); + + /** Get a variate in the range [0, 1] */ + virtual double + GetVariate() ITK_OVERRIDE; + +protected: + MinimalStandardRandomVariateGenerator(); + virtual ~MinimalStandardRandomVariateGenerator() {} + + virtual void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + NormalGeneratorType::Pointer m_NormalGenerator; +}; + +} // end of namespace Statistics +} // end of namespace itk + +#endif // itkMinimalStandardRandomVariateGenerator_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h new file mode 100644 index 00000000000..b2aa1df2ed7 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h @@ -0,0 +1,92 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkNormalDistributionImageSource_h +#define itkNormalDistributionImageSource_h + +#include "itkGenerateImageSource.h" + +namespace itk +{ + +/** \class NormalDistributionImageSource + * + * \brief Generate a image of pixels sampled from a normal distribution. + * + * Real-valued pixels are sampled from a normal distribution. + * + * The pixels, \f$x > 0\f$ follow + * + * \f[ + * f(x) = \frac{1}{sx\sqrt{2 \pi}} e^{\left( \frac{-(ln x - m)^2}{2s^2} \right)} + * \f] + * + * where \f$s\f$ is the StandardDeviation and \f$m\f$ is the Mean of the + * underlying normal distribution. + * + * \ingroup BoneEnhancement + * + */ +template +class NormalDistributionImageSource : public GenerateImageSource +{ +public: + typedef TImage ImageType; + typedef typename ImageType::PixelType PixelType; + + /** Standard class typedefs. */ + typedef NormalDistributionImageSource Self; + typedef GenerateImageSource Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); + + /** Run-time type information. */ + itkTypeMacro(NormalDistributionImageSource, GenerateImageSource); + + /** Standard New macro. */ + itkNewMacro(Self); + +protected: + NormalDistributionImageSource(); + virtual ~NormalDistributionImageSource() {} + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + + typedef typename ImageType::RegionType OutputRegionType; + + virtual void + ThreadedGenerateData(const OutputRegionType & outputRegion, ThreadIdType threadId) ITK_OVERRIDE; + +private: + NormalDistributionImageSource(const Self &); // purposely not implemented + void + operator=(const Self &); // purposely not implemented + +#ifdef ITK_USE_CONCEPT_CHECKING + itkConceptMacro(FloatingPointPixel, (itk::Concept::IsFloatingPoint)); +#endif +}; +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkNormalDistributionImageSource.hxx" +#endif + +#endif // itkNormalDistributionImageSource_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx new file mode 100644 index 00000000000..d406348805d --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx @@ -0,0 +1,79 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkNormalDistributionImageSource_hxx +#define itkNormalDistributionImageSource_hxx + +#include "itkNormalDistributionImageSource.h" +#include "itkNormalVariateGenerator.h" + +#include "itkImageScanlineIterator.h" +#include "itkProgressReporter.h" + +namespace itk +{ + +template +NormalDistributionImageSource::NormalDistributionImageSource() +{} + + +template +void +NormalDistributionImageSource::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + + +template +void +NormalDistributionImageSource::ThreadedGenerateData(const OutputRegionType & outputRegion, + ThreadIdType threadId) +{ + ImageType * output = this->GetOutput(); + + typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType; + NormalGeneratorType::Pointer normalGenerator = NormalGeneratorType::New(); + normalGenerator->Initialize(101); + + const SizeValueType size0 = outputRegion.GetSize(0); + if (size0 == 0) + { + return; + } + const SizeValueType numberOfLinesToProcess = outputRegion.GetNumberOfPixels() / size0; + + typedef ImageScanlineIterator IteratorType; + IteratorType it(output, outputRegion); + ProgressReporter progress(this, threadId, numberOfLinesToProcess); + + while (!it.IsAtEnd()) + { + while (!it.IsAtEndOfLine()) + { + it.Set(normalGenerator->GetVariate()); + ++it; + } + it.NextLine(); + progress.CompletedPixel(); + } +} + +} // end namespace itk + +#endif // itkNormalDistributionImageSource_hxx diff --git a/Modules/Filtering/BoneEnhancement/itk-module.cmake b/Modules/Filtering/BoneEnhancement/itk-module.cmake new file mode 100644 index 00000000000..a197427dea2 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/itk-module.cmake @@ -0,0 +1,24 @@ +# the top-level README is used for describing this module, just +# re-used it for documentation here +# itk_module() defines the module dependencies in BoneEnhancement +# BoneEnhancement depends on ITKCommon +# The testing module in BoneEnhancement depends on ITKTestKernel +# and ITKMetaIO(besides BoneEnhancement and ITKCore) +# By convention those modules outside of ITK are not prefixed with +# ITK. + +# define the dependencies of the include module and the tests +itk_module( + BoneEnhancement + DEPENDS + ITKCommon + ITKStatistics + COMPILE_DEPENDS + ITKImageSources + TEST_DEPENDS + ITKTestKernel + ITKMetaIO + DESCRIPTION "Module ingested from upstream." + EXCLUDE_FROM_DEFAULT + ENABLE_SHARED +) diff --git a/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt new file mode 100644 index 00000000000..29e2f0bcd37 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt @@ -0,0 +1,5 @@ +set(BoneEnhancement_SRCS + itkMinimalStandardRandomVariateGenerator.cxx + ) + +itk_module_add_library(BoneEnhancement ${BoneEnhancement_SRCS}) diff --git a/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx b/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx new file mode 100644 index 00000000000..69d32cdd6f2 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx @@ -0,0 +1,52 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#include "itkMinimalStandardRandomVariateGenerator.h" + +namespace itk +{ +namespace Statistics +{ + +MinimalStandardRandomVariateGenerator ::MinimalStandardRandomVariateGenerator() +{ + this->m_NormalGenerator = NormalGeneratorType::New(); + this->Initialize(1); +} + +void +MinimalStandardRandomVariateGenerator ::Initialize(int randomSeed) +{ + this->m_NormalGenerator->Initialize(randomSeed); +} + + +double +MinimalStandardRandomVariateGenerator ::GetVariate() +{ + return this->m_NormalGenerator->GetVariate(); +} + + +void +MinimalStandardRandomVariateGenerator ::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace Statistics +} // end namespace itk diff --git a/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 b/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 new file mode 100644 index 00000000000..a4017ad18cd --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 @@ -0,0 +1 @@ +38a102c75d4e30f57834fd3dc1ba61e30943714da9a9d27e4b77ee5fb58c1e34269a44c2af3cfd3a0b738de0f5ea293f0f609b8a66eede3f299703548ed57608 diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt new file mode 100644 index 00000000000..b450ae4c639 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -0,0 +1,28 @@ +itk_module_test() + +set( + BoneEnhancementTests + itkMinimalStandardRandomVariateGeneratorTest.cxx + itkNormalDistributionImageSourceTest.cxx +) + +createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") + +itk_add_test( + NAME itkMinimalStandardRandomVariateGeneratorTest + COMMAND + BoneEnhancementTestDriver + itkMinimalStandardRandomVariateGeneratorTest +) + +itk_add_test( + NAME itkNormalDistributionImageSourceTest + COMMAND + BoneEnhancementTestDriver + --without-threads + --compare + ${ITK_TEST_OUTPUT_DIR}/itkNormalDistributionImageSourceTestOutput.mha + DATA{Baseline/itkNormalDistributionImageSourceTestOutput.mha} + itkNormalDistributionImageSourceTest + ${ITK_TEST_OUTPUT_DIR}/itkNormalDistributionImageSourceTestOutput.mha +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx new file mode 100644 index 00000000000..0ef8f379160 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx @@ -0,0 +1,37 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkMinimalStandardRandomVariateGenerator.h" + +#include "itkTestingMacros.h" +#include "itkMath.h" + +int +itkMinimalStandardRandomVariateGeneratorTest(int, char *[]) +{ + typedef itk::Statistics::MinimalStandardRandomVariateGenerator GeneratorType; + GeneratorType::Pointer generator = GeneratorType::New(); + + EXERCISE_BASIC_OBJECT_METHODS(generator, MinimalStandardRandomVariateGenerator, RandomVariateGeneratorBase); + + generator->Initialize(324); + + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(generator->GetVariate(), 1.35581, 4, 0.0001)); + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx new file mode 100644 index 00000000000..e2914a75273 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx @@ -0,0 +1,67 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkNormalDistributionImageSource.h" + +#include "itkImageFileWriter.h" +#include "itkTestingMacros.h" + +int +itkNormalDistributionImageSourceTest(int argc, char * argv[]) +{ + if (argc < 2) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << " outputImage"; + std::cerr << std::endl; + return EXIT_FAILURE; + } + const char * outputImageFileName = argv[1]; + + const unsigned int Dimension = 2; + typedef float PixelType; + typedef itk::Image ImageType; + + typedef itk::NormalDistributionImageSource DistributionSourceType; + DistributionSourceType::Pointer distributionSource = DistributionSourceType::New(); + + EXERCISE_BASIC_OBJECT_METHODS(distributionSource, NormalDistributionImageSource, GenerateImageSource); + + + ImageType::SizeType size; + size.Fill(128); + distributionSource->SetSize(size); + + std::cout << distributionSource << std::endl; + + typedef itk::ImageFileWriter WriterType; + WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(outputImageFileName); + writer->SetInput(distributionSource->GetOutput()); + try + { + writer->Update(); + } + catch (itk::ExceptionObject & error) + { + std::cerr << "Error: " << error << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/wrapping/CMakeLists.txt new file mode 100644 index 00000000000..4add287860a --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/CMakeLists.txt @@ -0,0 +1,3 @@ +itk_wrap_module(BoneEnhancement) +itk_auto_load_submodules() +itk_end_wrap_module() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap new file mode 100644 index 00000000000..e13dd73db38 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap @@ -0,0 +1 @@ +itk_wrap_simple_class("itk::Statistics::MinimalStandardRandomVariateGenerator" POINTER) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap new file mode 100644 index 00000000000..70e93ecf270 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap @@ -0,0 +1,7 @@ +itk_wrap_class("itk::NormalDistributionImageSource" POINTER) +foreach(d ${ITK_WRAP_IMAGE_DIMS}) + itk_wrap_template("${ITKM_I${ITKM_F}${d}}" + "${ITKT_I${ITKM_F}${d}}" + ) +endforeach() +itk_end_wrap_class() From 80a0fa4ec6f6992a484db1d737802811ffbe3cc6 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 14 Nov 2017 17:00:01 -0700 Subject: [PATCH 002/150] ENH: Added MaximumAbsoluteValueImageFilter from old repository --- .../itkMaximumAbsoluteValueImageFilter.h | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h new file mode 100644 index 00000000000..4672d2ec69a --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -0,0 +1,63 @@ +#ifndef __MaximumAbsoluteValueImageFilter_h_ +#define __MaximumAbsoluteValueImageFilter_h_ + +#include "itkBinaryFunctorImageFilter.h" + +namespace itk +{ +namespace Functor +{ +template +class MaximumAbsoluteValue +{ +public: + MaximumAbsoluteValue() {} + + ~MaximumAbsoluteValue() {} + + inline TOutputPixel + operator()(const TInputPixel1 A, const TInputPixel2 B) + { + return static_cast(vnl_math_abs(A) >= vnl_math_abs(B) ? A : B); + } +}; +} // namespace Functor + +template +class MaximumAbsoluteValueImageFilter + : public BinaryFunctorImageFilter> +{ +public: + // itk requirements + typedef MaximumAbsoluteValueImageFilter Self; + typedef BinaryFunctorImageFilter> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + itkNewMacro(Self); // create the smart pointers and register with ITKs object factory + itkTypeMacro(MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); // type information for runtime evaluation + +protected: + MaximumAbsoluteValueImageFilter() {}; + + virtual ~MaximumAbsoluteValueImageFilter() {}; + +private: + MaximumAbsoluteValueImageFilter(const Self &); // purposely not implemented + void + operator=(const Self &); // purposely not implemented +}; +} // namespace itk + +#endif //__MaximumAbsoluteValueImageFilter_h_ From 9b5d20ad0c023b367d623e5ee14da189262d953a Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 14 Nov 2017 17:19:17 -0700 Subject: [PATCH 003/150] ENH: Added concept checks for Functor::MaximumAbsoluteValue, changed to greater than to make concept checking easy, use Math::abs instead of vnl_math_abs --- .../itkMaximumAbsoluteValueImageFilter.h | 70 +++++++++++++++---- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 4672d2ec69a..713d6173247 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -1,13 +1,31 @@ -#ifndef __MaximumAbsoluteValueImageFilter_h_ -#define __MaximumAbsoluteValueImageFilter_h_ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef MaximumAbsoluteValueImageFilter_h +#define MaximumAbsoluteValueImageFilter_h #include "itkBinaryFunctorImageFilter.h" +#include "itkMath.h" namespace itk { namespace Functor { -template +template class MaximumAbsoluteValue { public: @@ -15,15 +33,33 @@ class MaximumAbsoluteValue ~MaximumAbsoluteValue() {} +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking TODO + itkConceptMacro(Input1ConvertableToOutputCheck, (Concept::Convertible)); + itkConceptMacro(Input2ConvertableToOutputCheck, (Concept::Convertible)); + itkConceptMacro(Input1GreaterThanInput2Check, (Concept::GreaterThanComparable)); + // End concept checking +#endif + inline TOutputPixel operator()(const TInputPixel1 A, const TInputPixel2 B) { - return static_cast(vnl_math_abs(A) >= vnl_math_abs(B) ? A : B); + return static_cast(Math::abs(A) > Math::abs(B) ? A : B); } -}; +}; // end of class } // namespace Functor -template +/** \class MaximumAbsoluteValueImageFilter + * \brief Compute the maximum (of the absolute value) between two images. + * + * TODO: See BoneMorphometry for an example DOXYGEN description + * https://github.com/InsightSoftwareConsortium/ITKBoneMorphometry/blob/master/include/itkBoneMorphometryFeaturesFilter.h + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + * + */ +template class MaximumAbsoluteValueImageFilter : public BinaryFunctorImageFilter> { public: - // itk requirements typedef MaximumAbsoluteValueImageFilter Self; typedef BinaryFunctorImageFilter Pointer; typedef SmartPointer ConstPointer; - itkNewMacro(Self); // create the smart pointers and register with ITKs object factory - itkTypeMacro(MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); // type information for runtime evaluation + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); protected: - MaximumAbsoluteValueImageFilter() {}; + MaximumAbsoluteValueImageFilter() { + + }; virtual ~MaximumAbsoluteValueImageFilter() {}; private: - MaximumAbsoluteValueImageFilter(const Self &); // purposely not implemented + MaximumAbsoluteValueImageFilter(const Self &); void - operator=(const Self &); // purposely not implemented -}; -} // namespace itk + operator=(const Self &); +}; // end of class +} // end namespace itk -#endif //__MaximumAbsoluteValueImageFilter_h_ +#endif // MaximumAbsoluteValueImageFilter_h From b195f06ea98ea97e627403b5c94dfe1e361e6d19 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 16 Nov 2017 11:45:43 -0700 Subject: [PATCH 004/150] ENH: Wrote initial test for itkMaximumAbsoluteValueImageFilter, fixed formatting in failed test --- .../itkMaximumAbsoluteValueImageFilter.h | 14 +-- .../BoneEnhancement/itk-module.cmake | 2 + .../BoneEnhancement/test/CMakeLists.txt | 8 ++ ...itkMaximumAbsoluteValueImageFilterTest.cxx | 102 ++++++++++++++++++ 4 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 713d6173247..741e7a50c1e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -15,8 +15,9 @@ * limitations under the License. * *=========================================================================*/ -#ifndef MaximumAbsoluteValueImageFilter_h -#define MaximumAbsoluteValueImageFilter_h + +#ifndef itkMaximumAbsoluteValueImageFilter_h +#define itkMaximumAbsoluteValueImageFilter_h #include "itkBinaryFunctorImageFilter.h" #include "itkMath.h" @@ -69,6 +70,7 @@ class MaximumAbsoluteValueImageFilter typename TOutputImage::PixelType>> { public: + /** Standard Self typedef */ typedef MaximumAbsoluteValueImageFilter Self; typedef BinaryFunctorImageFilter ImageType; + typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; + MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); + + /** Create an image and run a basic test */ + ImageType::RegionType region; + ImageType::IndexType start; + + start[0] = 0; + start[1] = 0; + + ImageType::SizeType size; + size[0] = 200; + size[1] = 300; + + region.SetSize(size); + region.SetIndex(start); + + ImageType::Pointer image1 = ImageType::New(); + image1->SetRegions(region); + image1->Allocate(); + + ImageType::Pointer image2 = ImageType::New(); + image2->SetRegions(region); + image2->Allocate(); + + typedef itk::ImageRegionIterator IteratorType; + IteratorType it1(image1, region); + IteratorType it2(image2, region); + it1.GoToBegin(); + it2.GoToBegin(); + int i = 0; + while (!it1.IsAtEnd()) + { + if ((i % 2) == 0) + { + it1.Set(1.0); + it2.Set(-2.0); + } + else + { + it1.Set(2.0); + it2.Set(-1.0); + } + ++it1; + ++it2; + } + + maxAbsFilter->SetInput1(image1); + maxAbsFilter->SetInput2(image2); + maxAbsFilter->Update(); + ImageType::Pointer outputImage = maxAbsFilter->GetOutput(); + + IteratorType ot(outputImage, region); + ot.GoToBegin(); + i = 0; + while (!ot.IsAtEnd()) + { + if ((i % 2) == 0) + { + TEST_EXPECT_EQUAL(ot.Get(), -2); + } + else + { + TEST_EXPECT_EQUAL(ot.Get(), 2); + } + ++ot; + } + + /** TODO: Write an integration test */ + + return EXIT_SUCCESS; +} From 0bfb37c6b479ece9108c194abcc41e9157a611f2 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 16 Nov 2017 16:12:48 -0700 Subject: [PATCH 005/150] STYLE: Added documentation, transfered to ITK_DISALLOW_COPY_AND_ASSIGN macro --- .../include/itkMaximumAbsoluteValueImageFilter.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 741e7a50c1e..84c82ae00e6 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -53,12 +53,12 @@ class MaximumAbsoluteValue /** \class MaximumAbsoluteValueImageFilter * \brief Compute the maximum (of the absolute value) between two images. * - * TODO: See BoneMorphometry for an example DOXYGEN description - * https://github.com/InsightSoftwareConsortium/ITKBoneMorphometry/blob/master/include/itkBoneMorphometryFeaturesFilter.h + * This class takes two images as arguments and takes + * + * \sa MultiScaleHessianEnhancementImageFilter * * \author: Thomas Fitze * \ingroup BoneEnhancement - * */ template class MaximumAbsoluteValueImageFilter @@ -94,9 +94,7 @@ class MaximumAbsoluteValueImageFilter virtual ~MaximumAbsoluteValueImageFilter() {} private: - MaximumAbsoluteValueImageFilter(const Self &); - void - operator=(const Self &); + ITK_DISALLOW_COPY_AND_ASSIGN(MaximumAbsoluteValueImageFilter); }; // end of class } // end namespace itk From 46277c3fb299b5d8ec1ea918b38701b1844ab9b3 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 16 Nov 2017 16:27:51 -0700 Subject: [PATCH 006/150] ENH: Added abstract class EigenvalueToScalarImageFilter --- .../itkEigenvalueToScalarImageFilter.h | 85 +++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 ++ ...ueToScalarImageFilterTestStaticMethods.cxx | 36 ++++++++ 3 files changed, 129 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h new file mode 100644 index 00000000000..417ccbd1ca4 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h @@ -0,0 +1,85 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenvalueToScalarImageFilter_h +#define itkEigenvalueToScalarImageFilter_h + +#include "itkImageToImageFilter.h" + +namespace itk +{ +/** \class EigenvalueToScalarImageFilter + * \brief Abstract class for converting eigenvalue image to scalar image. + * + * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. + * Other classes should inherit from this class so they can be used in the BoneEnhancement framework. This abstract + * class guarantees that the variable EigenValueOrder has a valid type and enforces some concept checking + * on the class template parameters: TInputImage and TOutputImage . + * + * \sa MultiScaleHessianEnhancementImageFilter. + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT EigenvalueToScalarImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef EigenvalueToScalarImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EigenvalueToScalarImageFilter, ImageToImageFilter); + + /** Template the EigenValueOrderType. Methods that inherit from this class can override this function + * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from + * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial + * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type + * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. + * */ + typedef enum + { + OrderByValue = 1, + OrderByMagnitude, + DoNotOrder + } EigenValueOrderType; + itkStaticConstMacro(EigenValueOrder, EigenValueOrderType, OrderByMagnitude); + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, + (Concept::SameDimension)); + // End concept checking +protected: + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE + { + Superclass::PrintSelf(os, indent); + os << indent << "EigenValueOrder: " << this->GetEigenValueOrder() << std::endl; + } + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenvalueToScalarImageFilter); +#endif +}; // end class +} // namespace itk + +#endif // itkEigenvalueToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 540a8998c84..523d777e4b4 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -5,6 +5,7 @@ set( itkMinimalStandardRandomVariateGeneratorTest.cxx itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx + itkEigenvalueToScalarImageFilterTestStaticMethods.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -34,3 +35,10 @@ itk_add_test( BoneEnhancementTestDriver itkMaximumAbsoluteValueImageFilterTest ) + +itk_add_test( + NAME itkEigenvalueToScalarImageFilterTestStaticMethods + COMMAND + BoneEnhancementTestDriver + itkEigenvalueToScalarImageFilterTestStaticMethods +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx b/Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx new file mode 100644 index 00000000000..2fabbe75705 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx @@ -0,0 +1,36 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkEigenvalueToScalarImageFilter.h" +#include "itkTestingMacros.h" + +int +itkEigenvalueToScalarImageFilterTestStaticMethods(int, char *[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + + typedef itk::EigenvalueToScalarImageFilter EigenvalueToScalarImageFilterType; + + /* Test that the default is order by magnitude */ + TEST_EXPECT_EQUAL(EigenvalueToScalarImageFilterType::EigenValueOrder, + EigenvalueToScalarImageFilterType::OrderByMagnitude); + + return EXIT_SUCCESS; +} From 85d0b4a5f56cac9dde0b4346c35679c26c44d933 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 16 Nov 2017 16:29:12 -0700 Subject: [PATCH 007/150] ENH: Added the MultiScaleHessianEnhancementImageFilter class with static method tests --- ...kMultiScaleHessianEnhancementImageFilter.h | 173 ++++++++++++ ...ultiScaleHessianEnhancementImageFilter.hxx | 254 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 10 + ...nhancementImageFilterTestStaticMethods.cxx | 135 ++++++++++ 4 files changed, 572 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h new file mode 100644 index 00000000000..fff024f2f40 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -0,0 +1,173 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkMultiScaleHessianEnhancementImageFilter_h +#define itkMultiScaleHessianEnhancementImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkHessianRecursiveGaussianImageFilter.h" +#include "itkSymmetricEigenAnalysisImageFilter.h" +#include "itkMaximumAbsoluteValueImageFilter.h" +#include "itkNumericTraits.h" +#include "itkArray.h" +#include "itkEigenvalueToScalarImageFilter.h" + +namespace itk +{ +/** \class MultiScaleHessianEnhancementImageFilter + * \brief Compute an image enhancement using eigenvalues of the local hessian matrix over many scales. + * + * This class enhances an image using many of the bone image enhancement filters. Other filters based + * on a functional of the eigenvalues can be written using this class by extending EigenvalueToScalarImageFilter. + * This class works by computing the second derivative and cross derivatives usign HessianRecursiveGaussianImageFilter. + * The hessian matrix is decomposed into the eigenvalues using SymmetricEigenAnalysisImageFilter. By setting a filter + * using SetEigenToScalarImageFilter( ), a filter is used to convert eigenvalues back into a scalar values. This is + * repeated at multiple scales and the maximum response (in an absolute sense) is taken over all scales. + * + * To enhance the bone image, call SetEigenToScalarImageFilter( ) with an appropriate class derived from the + * EigenvalueToScalarImageFilter. This filter should be constructed outside of this class. You will also need + * to set the number of scales by which the image is enhanced using SetSigmaArray( ). Convenient static methods + * GenerateSigmaArray( ), GenerateEquispacedSigmaArray( ), and GenerateLogarithmicSigmaArray( ) can be used to + * generate naturally spaced sigma values. Note that you still need to pass the array to SetSigmaArray( ). + * Otherwise, an explicit SigmaArrayType can be passed to SetSigmaArray( ). + * + * The maximum response from SetEigenToScalarImageFilter( ) is taken over all sigma values using + * MaximumAbsoluteValueImageFilter. This is valid for filters which enhance both the positive and negative + * second derivatives. + * + * This class is heavily derived from \see MultiScaleHessianBasedMeasureImageFilter + * + * \sa MaximumAbsoluteValueImageFilter + * \sa EigenvalueToScalarImageFilter + * \sa SymmetricEigenAnalysisImageFilter + * \sa HessianRecursiveGaussianImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef MultiScaleHessianEnhancementImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(MultiScaleHessianEnhancementImageFilter, ImageToImageFilter); + + /** Image related typedefs. */ + typedef typename TInputImage::PixelType PixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Hessian related typedefs. */ + typedef HessianRecursiveGaussianImageFilter HessianFilterType; + typedef typename HessianFilterType::OutputImageType HessianImageType; + typedef typename HessianImageType::PixelType HessianPixelType; + + /** Eigenvalue analysis related typedefs. */ + typedef typename NumericTraits::RealType RealType; + typedef FixedArray EigenValueArrayType; + typedef Image EigenValueImageType; + typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; + + /** Maximum over scale related typedefs. */ + typedef MaximumAbsoluteValueImageFilter MaximumAbsoluteValueFilterType; + + /** Eigenvalue image to scalar image related typedefs */ + typedef EigenvalueToScalarImageFilter EigenToScalarImageFilterType; + + /** Set/Get the EigenToScalarImageFilter. */ + itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); + itkGetModifiableObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); + + /** Sigma values. */ + typedef RealType SigmaType; + typedef Array SigmaArrayType; + typedef unsigned int SigmaStepsType; + typedef enum + { + EquispacedSigmaSteps = 0, + LogarithmicSigmaSteps = 1 + } SigmaStepMethodEnum; + + /** Set/Get macros for SigmaArray */ + itkSetMacro(SigmaArray, SigmaType); + itkGetConstMacro(SigmaArray, SigmaType); + + /** + * Static methods for generating an array of sigma values. Note that these still need to be passed + * into the class using TODO: link to SetSigmaArray. Implementation taken from + * itkMultiScaleHessianBasedMeasureImageFilter. Note that these methods cannot throw exceptions according to the + * standard itkExceptionMacro since they are static methods. Instead, they will return an empty sigma array on error. + */ + static Self::SigmaArrayType + GenerateSigmaArray(SigmaType SigmaMinimum, + SigmaType SigmaMaximum, + SigmaStepsType NumberOfSigmaSteps, + SigmaStepMethodEnum SigmaStepMethod); + static Self::SigmaArrayType + GenerateEquispacedSigmaArray(SigmaType SigmaMinimum, SigmaType SigmaMaximum, SigmaStepsType NumberOfSigmaSteps); + static Self::SigmaArrayType + GenerateLogarithmicSigmaArray(SigmaType SigmaMinimum, SigmaType SigmaMaximum, SigmaStepsType NumberOfSigmaSteps); + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, + (Concept::SameDimension)); + // End concept checking +#endif + +protected: + MultiScaleHessianEnhancementImageFilter(); + virtual ~MultiScaleHessianEnhancementImageFilter() {} + + /** Single threaded since we are connecting data */ + void + GenerateData() ITK_OVERRIDE; + + /** Internal function to generate the response at a scale */ + typename TOutputImage::Pointer + generateResponseAtScale(SigmaStepsType scaleLevel); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + /** Internal filters. */ + typename HessianFilterType::Pointer m_HessianFilter; + typename EigenAnalysisFilterType::Pointer m_EigenAnalysisFilter; + typename MaximumAbsoluteValueFilterType::Pointer m_MaximumAbsoluteValueFilter; + typename EigenToScalarImageFilterType::Pointer m_EigenToScalarImageFilter; + + /** Sigma member variables. */ + SigmaType m_SigmaArray; + + ITK_DISALLOW_COPY_AND_ASSIGN(MultiScaleHessianEnhancementImageFilter); +}; // end of class +} // end namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkMultiScaleHessianEnhancementImageFilter.hxx" +#endif + +#endif // itkMultiScaleHessianEnhancementImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx new file mode 100644 index 00000000000..9b6603b92e6 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -0,0 +1,254 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkMultiScaleHessianEnhancementImageFilter_hxx +#define itkMultiScaleHessianEnhancementImageFilter_hxx + +#include "itkMultiScaleHessianEnhancementImageFilter.h" +#include "itkMath.h" +#include "itkProgressAccumulator.h" + +namespace itk +{ +template +MultiScaleHessianEnhancementImageFilter::MultiScaleHessianEnhancementImageFilter() +{ + /* Sigma member variables */ + m_SigmaArray.SetSize(0); + + /* Instantiate filters. */ + m_HessianFilter = HessianFilterType::New(); + m_EigenAnalysisFilter = EigenAnalysisFilterType::New(); + m_MaximumAbsoluteValueFilter = MaximumAbsoluteValueFilterType::New(); + m_EigenToScalarImageFilter = ITK_NULLPTR; // has to be provided by the user. + + /* We require an input image */ + this->SetNumberOfRequiredInputs(1); +} + +template +void +MultiScaleHessianEnhancementImageFilter::GenerateData() +{ + /* Test all inputs are set */ + if (!m_EigenToScalarImageFilter) + { + itkExceptionMacro(<< "EigenToScalarImageFilter is not present"); + } + + if (m_SigmaArray.GetSize() < 1) + { + itkExceptionMacro(<< "SigmaArray must have at least one sigma value. Given array of size " + << m_SigmaArray.GetSize()); + } + + /* Set filters parameters */ + m_HessianFilter->SetNormalizeAcrossScale(true); + m_EigenAnalysisFilter->SetDimension(ImageDimension); + m_EigenAnalysisFilter->OrderEigenValuesBy(m_EigenToScalarImageFilter->EigenValueOrder); + + /* Connect filters */ + m_HessianFilter->SetInput(this->GetInput()); + m_EigenAnalysisFilter->SetInput(m_HessianFilter->GetOutput()); + m_EigenToScalarImageFilter->SetInput(m_EigenAnalysisFilter->GetOutput()); + + /* After executing we want to release data to save memory */ + m_HessianFilter->ReleaseDataFlagOn(); + m_EigenAnalysisFilter->ReleaseDataFlagOn(); + m_EigenToScalarImageFilter->ReleaseDataFlagOn(); + + /* Setup progress reporter */ + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + + /* + * We checked that m_SigmaArray.GetSize() > 0 above and do not need to repeat the check. However, + * if we are only given one sigma value we do not need to take the maximum over scales. + */ + if (m_SigmaArray.GetSize() > 1) + { + /* + * Three filters, ran m_SigmaArray.GetSize() times + * One filter, ran (m_SigmaArray.GetSize() - 1) times + */ + float numberOfFiltersToProcess = 3 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); + float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; + itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); + + progress->RegisterInternalFilter(m_HessianFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenAnalysisFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToScalarImageFilter, perFilterProccessPercentage); + + /* Check if we need to run the MaximumAbsoluteValueFilter at all */ + if (m_SigmaArray.GetSize() > 1) + { + progress->RegisterInternalFilter(m_MaximumAbsoluteValueFilter, perFilterProccessPercentage); + } + else + { + itkDebugMacro(<< "maximumAbsoluteValueFilter is not being used"); + } + } + + /* We store a single pointer that we will graft to the output */ + typename TOutputImage::Pointer outputImageTypePointer; + + /* Process the first scale */ + outputImageTypePointer = generateResponseAtScale((SigmaType)0); + + /* Process the remaining sigma values */ + for (SigmaStepsType scaleLevel = 1; scaleLevel < m_SigmaArray.GetSize(); ++scaleLevel) + { + /* Calculate next response value */ + typename TOutputImage::Pointer tempResponseOutputImageTypePointer = generateResponseAtScale(scaleLevel); + + /* Take absolute value maximum */ + m_MaximumAbsoluteValueFilter->SetInput1(outputImageTypePointer); + m_MaximumAbsoluteValueFilter->SetInput2(tempResponseOutputImageTypePointer); + m_MaximumAbsoluteValueFilter->Update(); + + /* Save max and go to next sigma value */ + outputImageTypePointer = m_MaximumAbsoluteValueFilter->GetOutput(); + } + + /* Graft output and we're done! */ + this->GraftOutput(outputImageTypePointer); +} + +template +typename TOutputImage::Pointer +MultiScaleHessianEnhancementImageFilter::generateResponseAtScale(SigmaStepsType scaleLevel) +{ + /* Get this sigma value */ + SigmaType thisSigma = m_SigmaArray.GetElement(scaleLevel); + + /* Process pipeline and return */ + m_HessianFilter->SetSigma(thisSigma); + m_EigenToScalarImageFilter->Update(); + return m_EigenToScalarImageFilter->GetOutput(); +} + +template +typename MultiScaleHessianEnhancementImageFilter::SigmaArrayType +MultiScaleHessianEnhancementImageFilter::GenerateSigmaArray( + SigmaType SigmaMinimum, + SigmaType SigmaMaximum, + SigmaStepsType NumberOfSigmaSteps, + SigmaStepMethodEnum SigmaStepMethod) +{ + /* Quick check to make sure value is correct */ + if (NumberOfSigmaSteps < 1) + { + /* + * Since this is a static class, we have no "this" pointer so we cannot throw an exception. Instead + * we will return an empty sigma array. + */ + // itkExceptionMacro(<< "NumberOfSigmaSteps (" << NumberOfSigmaSteps << ") must be one or greater"); + SigmaArrayType sigmaArrayEmpty; + sigmaArrayEmpty.SetSize(0); + return sigmaArrayEmpty; + } + + /* If we have min greater than max just swap */ + if (SigmaMinimum > SigmaMaximum) + { + std::swap(SigmaMinimum, SigmaMaximum); + } + + /* If min equals max, just generate one step size */ + if (SigmaMinimum == SigmaMaximum) + { + NumberOfSigmaSteps = 1; + } + + /* Create array and resize */ + SigmaArrayType sigmaArray; + sigmaArray.SetSize(NumberOfSigmaSteps); + + /* Populate that array */ + SigmaType thisSigma; + for (SigmaStepsType scaleLevel = 0; scaleLevel < sigmaArray.GetSize(); ++scaleLevel) + { + switch (SigmaStepMethod) + { + case Self::EquispacedSigmaSteps: + { + const RealType stepSize = std::max(1e-10, (SigmaMaximum - SigmaMinimum) / (NumberOfSigmaSteps - 1)); + thisSigma = SigmaMinimum + stepSize * scaleLevel; + break; + } + case Self::LogarithmicSigmaSteps: + { + const RealType stepSize = + std::max(1e-10, (std::log(SigmaMaximum) - std::log(SigmaMinimum)) / (NumberOfSigmaSteps - 1)); + thisSigma = std::exp(std::log(SigmaMinimum) + stepSize * scaleLevel); + break; + } + default: + /* + * Since this is a static class, we have no "this" pointer so we cannot throw an exception. Instead + * we will return an empty sigma array. + */ + // itkExceptionMacro ("Invalid SigmaStepMethod: " << SigmaStepMethod); + SigmaArrayType sigmaArrayEmpty; + sigmaArrayEmpty.SetSize(0); + return sigmaArrayEmpty; + break; + } + + /* Assign to array */ + sigmaArray.SetElement(scaleLevel, thisSigma); + } + + return sigmaArray; +} + +template +typename MultiScaleHessianEnhancementImageFilter::SigmaArrayType +MultiScaleHessianEnhancementImageFilter::GenerateEquispacedSigmaArray( + SigmaType SigmaMinimum, + SigmaType SigmaMaximum, + SigmaStepsType NumberOfSigmaSteps) +{ + return GenerateSigmaArray(SigmaMinimum, SigmaMaximum, NumberOfSigmaSteps, Self::EquispacedSigmaSteps); +} + +template +typename MultiScaleHessianEnhancementImageFilter::SigmaArrayType +MultiScaleHessianEnhancementImageFilter::GenerateLogarithmicSigmaArray( + SigmaType SigmaMinimum, + SigmaType SigmaMaximum, + SigmaStepsType NumberOfSigmaSteps) +{ + return GenerateSigmaArray(SigmaMinimum, SigmaMaximum, NumberOfSigmaSteps, Self::LogarithmicSigmaSteps); +} + +template +void +MultiScaleHessianEnhancementImageFilter::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "HessianFilter: " << m_HessianFilter.GetPointer() << std::endl; + os << indent << "EigenAnalysisFilter: " << m_EigenAnalysisFilter.GetPointer() << std::endl; + os << indent << "MaximumAbsoluteValueFilter: " << m_MaximumAbsoluteValueFilter.GetPointer() << std::endl; + os << indent << "EigenToScalarImageFilter: " << m_EigenToScalarImageFilter.GetPointer() << std::endl; + os << indent << "SigmaArray: " << m_SigmaArray << std::endl; +} + +} // end namespace itk + +#endif // itkMultiScaleHessianEnhancementImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 523d777e4b4..874adbedb27 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -5,6 +5,7 @@ set( itkMinimalStandardRandomVariateGeneratorTest.cxx itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx + itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx itkEigenvalueToScalarImageFilterTestStaticMethods.cxx ) @@ -36,6 +37,15 @@ itk_add_test( itkMaximumAbsoluteValueImageFilterTest ) +itk_add_test( + NAME itkMultiScaleHessianEnhancementImageFilterTestStaticMethods + COMMAND + BoneEnhancementTestDriver + itkMultiScaleHessianEnhancementImageFilterTestStaticMethods + itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateLogarithmicSigmaArray + itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateEquispacedSigmaArray +) + itk_add_test( NAME itkEigenvalueToScalarImageFilterTestStaticMethods COMMAND diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx new file mode 100644 index 00000000000..87de6f88dfe --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx @@ -0,0 +1,135 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkMultiScaleHessianEnhancementImageFilter.h" +#include "itkArray.h" +#include "itkTestingMacros.h" +#include "itkMath.h" + +int +itkMultiScaleHessianEnhancementImageFilterTestStaticMethods(int, char *[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Test that we get zero sized arrays for bad inputs */ + ArrayType expectedZeroSigmaArray; + expectedZeroSigmaArray.SetSize(0); + ArrayType sigmaArray; + + /* Test the two cases of step size zero */ + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0); + TEST_EXPECT_EQUAL(expectedZeroSigmaArray, sigmaArray); + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0); + TEST_EXPECT_EQUAL(expectedZeroSigmaArray, sigmaArray); + + /* Test that we get one when min equals max */ + ArrayType expectedOneSigmaArray; + expectedOneSigmaArray.SetSize(1); + expectedOneSigmaArray.SetElement(0, 1); + + /* Test the two cases of min equals max with a large number of values */ + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); + TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); + TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); + + return EXIT_SUCCESS; +} + +int +itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateLogarithmicSigmaArray(int, char *[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Test the Logarithmic method */ + ArrayType expectedLogarithmicArray; + expectedLogarithmicArray.SetSize(5); + expectedLogarithmicArray.SetElement(0, 1); + expectedLogarithmicArray.SetElement(1, 1.4953487812212205); + expectedLogarithmicArray.SetElement(2, 2.23606797749979); + expectedLogarithmicArray.SetElement(3, 3.3437015248821096); + expectedLogarithmicArray.SetElement(4, 5); + + ArrayType logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); + /* Here we need to do some floating point comparisons */ + TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) + for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) + { + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); + } + + logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); + /* Should be the same if we flip min and max */ + TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) + for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) + { + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); + } + + return EXIT_SUCCESS; +} + +int +itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateEquispacedSigmaArray(int, char *[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Test the Equidistance method */ + ArrayType expectedEquidistanceArray; + expectedEquidistanceArray.SetSize(5); + expectedEquidistanceArray.SetElement(0, 1.0); + expectedEquidistanceArray.SetElement(1, 2.0); + expectedEquidistanceArray.SetElement(2, 3.0); + expectedEquidistanceArray.SetElement(3, 4.0); + expectedEquidistanceArray.SetElement(4, 5.0); + + ArrayType equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); + /* Here we need to do some floating point comparisons. These are exact, but we should still do a floating point + * comparison to be sure */ + TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) + for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( + expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); + } + + equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); + /* Should be the same if we flip min and max */ + TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) + for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( + expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); + } + + return EXIT_SUCCESS; +} From 61e7e028ade55655bb2b36c27a107f471d21e1de Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 17 Nov 2017 12:37:46 -0700 Subject: [PATCH 008/150] STYLE: Renamed EigenvalueToScalarImageFilter to EigenToScalarImageFilter --- ...eFilter.h => itkEigenToScalarImageFilter.h} | 18 +++++++++--------- ...tkMultiScaleHessianEnhancementImageFilter.h | 10 +++++----- .../BoneEnhancement/test/CMakeLists.txt | 6 +++--- ...enToScalarImageFilterTestStaticMethods.cxx} | 9 ++++----- 4 files changed, 21 insertions(+), 22 deletions(-) rename Modules/Filtering/BoneEnhancement/include/{itkEigenvalueToScalarImageFilter.h => itkEigenToScalarImageFilter.h} (86%) rename Modules/Filtering/BoneEnhancement/test/{itkEigenvalueToScalarImageFilterTestStaticMethods.cxx => itkEigenToScalarImageFilterTestStaticMethods.cxx} (74%) diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h similarity index 86% rename from Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h rename to Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 417ccbd1ca4..02b41d3a10c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenvalueToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -16,14 +16,14 @@ * *=========================================================================*/ -#ifndef itkEigenvalueToScalarImageFilter_h -#define itkEigenvalueToScalarImageFilter_h +#ifndef itkEigenToScalarImageFilter_h +#define itkEigenToScalarImageFilter_h #include "itkImageToImageFilter.h" namespace itk { -/** \class EigenvalueToScalarImageFilter +/** \class EigenToScalarImageFilter * \brief Abstract class for converting eigenvalue image to scalar image. * * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. @@ -37,24 +37,24 @@ namespace itk * \ingroup BoneEnhancement */ template -class ITK_TEMPLATE_EXPORT EigenvalueToScalarImageFilter : public ImageToImageFilter +class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter { public: /** Standard Self typedef */ - typedef EigenvalueToScalarImageFilter Self; + typedef EigenToScalarImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ - itkTypeMacro(EigenvalueToScalarImageFilter, ImageToImageFilter); + itkTypeMacro(EigenToScalarImageFilter, ImageToImageFilter); /** Template the EigenValueOrderType. Methods that inherit from this class can override this function * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. - * */ + */ typedef enum { OrderByValue = 1, @@ -77,9 +77,9 @@ class ITK_TEMPLATE_EXPORT EigenvalueToScalarImageFilter : public ImageToImageFil } private: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenvalueToScalarImageFilter); + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToScalarImageFilter); #endif }; // end class } // namespace itk -#endif // itkEigenvalueToScalarImageFilter_h +#endif // itkEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index fff024f2f40..99d62bd5c6e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -24,7 +24,7 @@ #include "itkMaximumAbsoluteValueImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" -#include "itkEigenvalueToScalarImageFilter.h" +#include "itkEigenToScalarImageFilter.h" namespace itk { @@ -32,14 +32,14 @@ namespace itk * \brief Compute an image enhancement using eigenvalues of the local hessian matrix over many scales. * * This class enhances an image using many of the bone image enhancement filters. Other filters based - * on a functional of the eigenvalues can be written using this class by extending EigenvalueToScalarImageFilter. + * on a functional of the eigenvalues can be written using this class by extending EigenToScalarImageFilter. * This class works by computing the second derivative and cross derivatives usign HessianRecursiveGaussianImageFilter. * The hessian matrix is decomposed into the eigenvalues using SymmetricEigenAnalysisImageFilter. By setting a filter * using SetEigenToScalarImageFilter( ), a filter is used to convert eigenvalues back into a scalar values. This is * repeated at multiple scales and the maximum response (in an absolute sense) is taken over all scales. * * To enhance the bone image, call SetEigenToScalarImageFilter( ) with an appropriate class derived from the - * EigenvalueToScalarImageFilter. This filter should be constructed outside of this class. You will also need + * EigenToScalarImageFilter. This filter should be constructed outside of this class. You will also need * to set the number of scales by which the image is enhanced using SetSigmaArray( ). Convenient static methods * GenerateSigmaArray( ), GenerateEquispacedSigmaArray( ), and GenerateLogarithmicSigmaArray( ) can be used to * generate naturally spaced sigma values. Note that you still need to pass the array to SetSigmaArray( ). @@ -52,7 +52,7 @@ namespace itk * This class is heavily derived from \see MultiScaleHessianBasedMeasureImageFilter * * \sa MaximumAbsoluteValueImageFilter - * \sa EigenvalueToScalarImageFilter + * \sa EigenToScalarImageFilter * \sa SymmetricEigenAnalysisImageFilter * \sa HessianRecursiveGaussianImageFilter * @@ -94,7 +94,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image typedef MaximumAbsoluteValueImageFilter MaximumAbsoluteValueFilterType; /** Eigenvalue image to scalar image related typedefs */ - typedef EigenvalueToScalarImageFilter EigenToScalarImageFilterType; + typedef EigenToScalarImageFilter EigenToScalarImageFilterType; /** Set/Get the EigenToScalarImageFilter. */ itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 874adbedb27..ee16b2bdffb 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -6,7 +6,7 @@ set( itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx - itkEigenvalueToScalarImageFilterTestStaticMethods.cxx + itkEigenToScalarImageFilterTestStaticMethods.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -47,8 +47,8 @@ itk_add_test( ) itk_add_test( - NAME itkEigenvalueToScalarImageFilterTestStaticMethods + NAME itkEigenToScalarImageFilterTestStaticMethods COMMAND BoneEnhancementTestDriver - itkEigenvalueToScalarImageFilterTestStaticMethods + itkEigenToScalarImageFilterTestStaticMethods ) diff --git a/Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx b/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx similarity index 74% rename from Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx rename to Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx index 2fabbe75705..2cdec85e71f 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkEigenvalueToScalarImageFilterTestStaticMethods.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx @@ -16,21 +16,20 @@ * *=========================================================================*/ -#include "itkEigenvalueToScalarImageFilter.h" +#include "itkEigenToScalarImageFilter.h" #include "itkTestingMacros.h" int -itkEigenvalueToScalarImageFilterTestStaticMethods(int, char *[]) +itkEigenToScalarImageFilterTestStaticMethods(int, char *[]) { const unsigned int Dimension = 2; typedef int PixelType; typedef itk::Image ImageType; - typedef itk::EigenvalueToScalarImageFilter EigenvalueToScalarImageFilterType; + typedef itk::EigenToScalarImageFilter EigenToScalarImageFilterType; /* Test that the default is order by magnitude */ - TEST_EXPECT_EQUAL(EigenvalueToScalarImageFilterType::EigenValueOrder, - EigenvalueToScalarImageFilterType::OrderByMagnitude); + TEST_EXPECT_EQUAL(EigenToScalarImageFilterType::EigenValueOrder, EigenToScalarImageFilterType::OrderByMagnitude); return EXIT_SUCCESS; } From d3beb34aa16ddafefb36879856afa9f0c3476366 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 17 Nov 2017 12:43:07 -0700 Subject: [PATCH 009/150] BUG: Fixed bad #endif preprocessor directive for ITK_USE_CONCEPT_CHECKING --- .../BoneEnhancement/include/itkEigenToScalarImageFilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 02b41d3a10c..4c65c478528 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -68,6 +68,7 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter)); // End concept checking +#endif protected: void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE @@ -78,7 +79,6 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter Date: Fri, 17 Nov 2017 16:37:51 -0700 Subject: [PATCH 010/150] STYLE: Changed test cases to end in Test.cxx, put all test cases in one function --- .../BoneEnhancement/test/CMakeLists.txt | 14 +++++----- ...nToScalarImageFilterStaticMethodsTest.cxx} | 2 +- ...hancementImageFilterStaticMethodsTest.cxx} | 26 +------------------ 3 files changed, 8 insertions(+), 34 deletions(-) rename Modules/Filtering/BoneEnhancement/test/{itkEigenToScalarImageFilterTestStaticMethods.cxx => itkEigenToScalarImageFilterStaticMethodsTest.cxx} (95%) rename Modules/Filtering/BoneEnhancement/test/{itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx => itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx} (81%) diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index ee16b2bdffb..51e9271c1a5 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -5,8 +5,8 @@ set( itkMinimalStandardRandomVariateGeneratorTest.cxx itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx - itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx - itkEigenToScalarImageFilterTestStaticMethods.cxx + itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx + itkEigenToScalarImageFilterStaticMethodsTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -38,17 +38,15 @@ itk_add_test( ) itk_add_test( - NAME itkMultiScaleHessianEnhancementImageFilterTestStaticMethods + NAME itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest COMMAND BoneEnhancementTestDriver - itkMultiScaleHessianEnhancementImageFilterTestStaticMethods - itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateLogarithmicSigmaArray - itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateEquispacedSigmaArray + itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest ) itk_add_test( - NAME itkEigenToScalarImageFilterTestStaticMethods + NAME itkEigenToScalarImageFilterStaticMethodsTest COMMAND BoneEnhancementTestDriver - itkEigenToScalarImageFilterTestStaticMethods + itkEigenToScalarImageFilterStaticMethodsTest ) diff --git a/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx b/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx similarity index 95% rename from Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx rename to Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx index 2cdec85e71f..d225d0627bc 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterTestStaticMethods.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx @@ -20,7 +20,7 @@ #include "itkTestingMacros.h" int -itkEigenToScalarImageFilterTestStaticMethods(int, char *[]) +itkEigenToScalarImageFilterStaticMethodsTest(int, char *[]) { const unsigned int Dimension = 2; typedef int PixelType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx similarity index 81% rename from Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx rename to Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index 87de6f88dfe..645e3dd74d7 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterTestStaticMethods.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -22,7 +22,7 @@ #include "itkMath.h" int -itkMultiScaleHessianEnhancementImageFilterTestStaticMethods(int, char *[]) +itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) { const unsigned int Dimension = 2; typedef int PixelType; @@ -52,18 +52,6 @@ itkMultiScaleHessianEnhancementImageFilterTestStaticMethods(int, char *[]) sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); - return EXIT_SUCCESS; -} - -int -itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateLogarithmicSigmaArray(int, char *[]) -{ - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; - /* Test the Logarithmic method */ ArrayType expectedLogarithmicArray; expectedLogarithmicArray.SetSize(5); @@ -91,18 +79,6 @@ itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateLogarithmicSig itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); } - return EXIT_SUCCESS; -} - -int -itkMultiScaleHessianEnhancementImageFilterTestStaticMethodGenerateEquispacedSigmaArray(int, char *[]) -{ - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; - /* Test the Equidistance method */ ArrayType expectedEquidistanceArray; expectedEquidistanceArray.SetSize(5); From 4172c4a8ead02a0d7b05c1e9a55be326712ed92c Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:12:28 -0700 Subject: [PATCH 011/150] ENH: EigenvalueToScalarImageFilter no longer controlled by static member variable. Instead, implement the pure virtual function GetEigenValueOrder() --- .../include/itkEigenToScalarImageFilter.h | 3 +- ...ultiScaleHessianEnhancementImageFilter.hxx | 2 +- .../BoneEnhancement/test/CMakeLists.txt | 8 ----- ...enToScalarImageFilterStaticMethodsTest.cxx | 35 ------------------- 4 files changed, 3 insertions(+), 45 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 4c65c478528..886e0c6e8eb 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -61,7 +61,8 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter::GenerateData /* Set filters parameters */ m_HessianFilter->SetNormalizeAcrossScale(true); m_EigenAnalysisFilter->SetDimension(ImageDimension); - m_EigenAnalysisFilter->OrderEigenValuesBy(m_EigenToScalarImageFilter->EigenValueOrder); + m_EigenAnalysisFilter->OrderEigenValuesBy(m_EigenToScalarImageFilter->GetEigenValueOrder()); /* Connect filters */ m_HessianFilter->SetInput(this->GetInput()); diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 51e9271c1a5..cc57656a92c 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -6,7 +6,6 @@ set( itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx - itkEigenToScalarImageFilterStaticMethodsTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -43,10 +42,3 @@ itk_add_test( BoneEnhancementTestDriver itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest ) - -itk_add_test( - NAME itkEigenToScalarImageFilterStaticMethodsTest - COMMAND - BoneEnhancementTestDriver - itkEigenToScalarImageFilterStaticMethodsTest -) diff --git a/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx deleted file mode 100644 index d225d0627bc..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkEigenToScalarImageFilterStaticMethodsTest.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkEigenToScalarImageFilter.h" -#include "itkTestingMacros.h" - -int -itkEigenToScalarImageFilterStaticMethodsTest(int, char *[]) -{ - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - - typedef itk::EigenToScalarImageFilter EigenToScalarImageFilterType; - - /* Test that the default is order by magnitude */ - TEST_EXPECT_EQUAL(EigenToScalarImageFilterType::EigenValueOrder, EigenToScalarImageFilterType::OrderByMagnitude); - - return EXIT_SUCCESS; -} From 0bc6bf429a1f7c8c3eccdd06a2a1efb44301d3ad Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:20:22 -0700 Subject: [PATCH 012/150] STYLE: Fixed left over TODO statement in itkMultiScaleHessianEnhancementImageF ilter.h --- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 99d62bd5c6e..46038ff0111 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -116,9 +116,9 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** * Static methods for generating an array of sigma values. Note that these still need to be passed - * into the class using TODO: link to SetSigmaArray. Implementation taken from - * itkMultiScaleHessianBasedMeasureImageFilter. Note that these methods cannot throw exceptions according to the - * standard itkExceptionMacro since they are static methods. Instead, they will return an empty sigma array on error. + * into the class using SetSigmaArray . Implementation taken from itkMultiScaleHessianBasedMeasureImageFilter. + * Note that these methods cannot throw exceptions according to the standard itkExceptionMacro since they are static + * methods. Instead, they will return an empty sigma array on error. */ static Self::SigmaArrayType GenerateSigmaArray(SigmaType SigmaMinimum, From 138d0a8fb349b8c1db7cea77b5fd906c1fc4ba34 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:25:17 -0700 Subject: [PATCH 013/150] STYLE: Fixed redundant check for m_SigmaArray.GetSize() --- ...ultiScaleHessianEnhancementImageFilter.hxx | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 35af2dc8de3..e62715a8c42 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -78,30 +78,26 @@ MultiScaleHessianEnhancementImageFilter::GenerateData /* * We checked that m_SigmaArray.GetSize() > 0 above and do not need to repeat the check. However, * if we are only given one sigma value we do not need to take the maximum over scales. + * + * Three filters, ran m_SigmaArray.GetSize() times + * One filter, ran (m_SigmaArray.GetSize() - 1) times */ - if (m_SigmaArray.GetSize() > 1) - { - /* - * Three filters, ran m_SigmaArray.GetSize() times - * One filter, ran (m_SigmaArray.GetSize() - 1) times - */ - float numberOfFiltersToProcess = 3 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); - float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; - itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); + float numberOfFiltersToProcess = 3 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); + float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; + itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); - progress->RegisterInternalFilter(m_HessianFilter, perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenAnalysisFilter, perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenToScalarImageFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_HessianFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenAnalysisFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToScalarImageFilter, perFilterProccessPercentage); - /* Check if we need to run the MaximumAbsoluteValueFilter at all */ - if (m_SigmaArray.GetSize() > 1) - { - progress->RegisterInternalFilter(m_MaximumAbsoluteValueFilter, perFilterProccessPercentage); - } - else - { - itkDebugMacro(<< "maximumAbsoluteValueFilter is not being used"); - } + /* Check if we need to run the MaximumAbsoluteValueFilter at all */ + if (m_SigmaArray.GetSize() > 1) + { + progress->RegisterInternalFilter(m_MaximumAbsoluteValueFilter, perFilterProccessPercentage); + } + else + { + itkDebugMacro(<< "maximumAbsoluteValueFilter is not being used"); } /* We store a single pointer that we will graft to the output */ From 0a4a86e07b8841ac5967ba93df1bba742d293cc6 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:29:06 -0700 Subject: [PATCH 014/150] BUG: Small casting error between SigmaType and SigmaStepsType fixed --- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index e62715a8c42..396cefe20c3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -104,7 +104,7 @@ MultiScaleHessianEnhancementImageFilter::GenerateData typename TOutputImage::Pointer outputImageTypePointer; /* Process the first scale */ - outputImageTypePointer = generateResponseAtScale((SigmaType)0); + outputImageTypePointer = generateResponseAtScale((SigmaStepsType)0); /* Process the remaining sigma values */ for (SigmaStepsType scaleLevel = 1; scaleLevel < m_SigmaArray.GetSize(); ++scaleLevel) From 26294d22579103be5f4d843a5658e666606ab457 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:48:51 -0700 Subject: [PATCH 015/150] ENH: MultiScaleHessianEnhancementImageFilter static methods now throw exceptions instead of returning empty sigma arrays --- ...ultiScaleHessianEnhancementImageFilter.hxx | 20 ++----------- ...nhancementImageFilterStaticMethodsTest.cxx | 30 +++++++++++++------ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 396cefe20c3..acce1c6d88e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -21,6 +21,7 @@ #include "itkMultiScaleHessianEnhancementImageFilter.h" #include "itkMath.h" #include "itkProgressAccumulator.h" +#include "itkExceptionObject.h" namespace itk { @@ -149,14 +150,7 @@ MultiScaleHessianEnhancementImageFilter::GenerateSigm /* Quick check to make sure value is correct */ if (NumberOfSigmaSteps < 1) { - /* - * Since this is a static class, we have no "this" pointer so we cannot throw an exception. Instead - * we will return an empty sigma array. - */ - // itkExceptionMacro(<< "NumberOfSigmaSteps (" << NumberOfSigmaSteps << ") must be one or greater"); - SigmaArrayType sigmaArrayEmpty; - sigmaArrayEmpty.SetSize(0); - return sigmaArrayEmpty; + throw ExceptionObject(__FILE__, __LINE__, "Number of sigma values requested is less than 1", ITK_LOCATION); } /* If we have min greater than max just swap */ @@ -195,15 +189,7 @@ MultiScaleHessianEnhancementImageFilter::GenerateSigm break; } default: - /* - * Since this is a static class, we have no "this" pointer so we cannot throw an exception. Instead - * we will return an empty sigma array. - */ - // itkExceptionMacro ("Invalid SigmaStepMethod: " << SigmaStepMethod); - SigmaArrayType sigmaArrayEmpty; - sigmaArrayEmpty.SetSize(0); - return sigmaArrayEmpty; - break; + throw ExceptionObject(__FILE__, __LINE__, "Requested sigma step method does not exist", ITK_LOCATION); } /* Assign to array */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index 645e3dd74d7..81dee7c62f9 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -30,16 +30,28 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; - /* Test that we get zero sized arrays for bad inputs */ - ArrayType expectedZeroSigmaArray; - expectedZeroSigmaArray.SetSize(0); - ArrayType sigmaArray; - /* Test the two cases of step size zero */ - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0); - TEST_EXPECT_EQUAL(expectedZeroSigmaArray, sigmaArray); - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0); - TEST_EXPECT_EQUAL(expectedZeroSigmaArray, sigmaArray); + ArrayType sigmaArray; + bool exceptionCaught = false; + try + { + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0); + } + catch (itk::ExceptionObject & err) + { + exceptionCaught = true; + } + TEST_EXPECT_TRUE(exceptionCaught); + exceptionCaught = false; + try + { + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0); + } + catch (itk::ExceptionObject & err) + { + exceptionCaught = true; + } + TEST_EXPECT_TRUE(exceptionCaught); /* Test that we get one when min equals max */ ArrayType expectedOneSigmaArray; From e72977b336aaef029b3c8b3adc8a286d8b41a5fa Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 10:58:38 -0700 Subject: [PATCH 016/150] BUG: Fixed division by zero error in static methods of MultiScaleHessianEnhancementImageFilter --- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index acce1c6d88e..aa6397ac19b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -169,9 +169,12 @@ MultiScaleHessianEnhancementImageFilter::GenerateSigm SigmaArrayType sigmaArray; sigmaArray.SetSize(NumberOfSigmaSteps); - /* Populate that array */ + /* Populate first element to avoid division by zero */ + sigmaArray.SetElement(0, SigmaMinimum); + + /* Populate the remaining array */ SigmaType thisSigma; - for (SigmaStepsType scaleLevel = 0; scaleLevel < sigmaArray.GetSize(); ++scaleLevel) + for (SigmaStepsType scaleLevel = 1; scaleLevel < sigmaArray.GetSize(); ++scaleLevel) { switch (SigmaStepMethod) { From aa7f4ab5e5947778dada51046bcc21f9e2d92143 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 17:13:35 -0700 Subject: [PATCH 017/150] BUG: Fixed error about setting eigenvalues --- ...kMultiScaleHessianEnhancementImageFilter.h | 16 +++++++++++++--- ...ultiScaleHessianEnhancementImageFilter.hxx | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 46038ff0111..46ee96f49d5 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -21,6 +21,7 @@ #include "itkImageToImageFilter.h" #include "itkHessianRecursiveGaussianImageFilter.h" #include "itkSymmetricEigenAnalysisImageFilter.h" +#include "itkSymmetricEigenAnalysis.h" #include "itkMaximumAbsoluteValueImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" @@ -96,6 +97,11 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Eigenvalue image to scalar image related typedefs */ typedef EigenToScalarImageFilter EigenToScalarImageFilterType; + /** Need some types to determine how to order the eigenvalues */ + // typedef typename Functor::SymmetricEigenAnalysisFunction::EigenValueOrderType InternalEigenValueOrderType; + typedef typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType InternalEigenValueOrderType; + typedef typename EigenToScalarImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; + /** Set/Get the EigenToScalarImageFilter. */ itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); itkGetModifiableObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); @@ -111,8 +117,8 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image } SigmaStepMethodEnum; /** Set/Get macros for SigmaArray */ - itkSetMacro(SigmaArray, SigmaType); - itkGetConstMacro(SigmaArray, SigmaType); + itkSetMacro(SigmaArray, SigmaArrayType); + itkGetConstMacro(SigmaArray, SigmaArrayType); /** * Static methods for generating an array of sigma values. Note that these still need to be passed @@ -149,6 +155,10 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image typename TOutputImage::Pointer generateResponseAtScale(SigmaStepsType scaleLevel); + /** Internal function to convert types for EigenValueOrder */ + InternalEigenValueOrderType + ConvertType(ExternalEigenValueOrderType order); + void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; @@ -160,7 +170,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image typename EigenToScalarImageFilterType::Pointer m_EigenToScalarImageFilter; /** Sigma member variables. */ - SigmaType m_SigmaArray; + SigmaArrayType m_SigmaArray; ITK_DISALLOW_COPY_AND_ASSIGN(MultiScaleHessianEnhancementImageFilter); }; // end of class diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index aa6397ac19b..80be2497fbb 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -60,7 +60,7 @@ MultiScaleHessianEnhancementImageFilter::GenerateData /* Set filters parameters */ m_HessianFilter->SetNormalizeAcrossScale(true); m_EigenAnalysisFilter->SetDimension(ImageDimension); - m_EigenAnalysisFilter->OrderEigenValuesBy(m_EigenToScalarImageFilter->GetEigenValueOrder()); + m_EigenAnalysisFilter->OrderEigenValuesBy(this->ConvertType(m_EigenToScalarImageFilter->GetEigenValueOrder())); /* Connect filters */ m_HessianFilter->SetInput(this->GetInput()); @@ -222,6 +222,23 @@ MultiScaleHessianEnhancementImageFilter::GenerateLoga return GenerateSigmaArray(SigmaMinimum, SigmaMaximum, NumberOfSigmaSteps, Self::LogarithmicSigmaSteps); } +template +typename MultiScaleHessianEnhancementImageFilter::InternalEigenValueOrderType +MultiScaleHessianEnhancementImageFilter::ConvertType(ExternalEigenValueOrderType order) +{ + switch (order) + { + case EigenToScalarImageFilterType::OrderByValue: + return EigenAnalysisFilterType::FunctorType::OrderByValue; + case EigenToScalarImageFilterType::OrderByMagnitude: + return EigenAnalysisFilterType::FunctorType::OrderByMagnitude; + case EigenToScalarImageFilterType::DoNotOrder: + return EigenAnalysisFilterType::FunctorType::DoNotOrder; + default: + itkExceptionMacro(<< "Trying to convert bad order " << order); + } +} + template void MultiScaleHessianEnhancementImageFilter::PrintSelf(std::ostream & os, Indent indent) const From bca397f60224af5f34fc6fdc680656865efd5dd6 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 16:00:38 -0700 Subject: [PATCH 018/150] ENH: END: Added Krcah parameter estimation filter --- ...entoScalarParameterEstimationImageFilter.h | 234 +++++++++++++++++ ...toScalarParameterEstimationImageFilter.hxx | 237 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + ...alarParameterEstimationImageFilterTest.cxx | 171 +++++++++++++ 4 files changed, 650 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h new file mode 100644 index 00000000000..4d9beeb0ff8 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h @@ -0,0 +1,234 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigentoScalarParameterEstimationImageFilter_h +#define itkKrcahEigentoScalarParameterEstimationImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkNumericTraits.h" +#include "itkSimpleDataObjectDecorator.h" +#include "itkArray.h" + +namespace itk +{ +/** \class KrcahEigentoScalarParameterEstimationImageFilter + * \brief Abstract class for converting eigenvalue image to scalar image. + * + * This class takes an image of eigenvalues and estimates the parameters for the Krcah + * bone enhanced filter. According to the original paper, + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.25 + * \f} + * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. + * The trace of the matrix can be computed directly from the eigenvalues as the sum + * of the eigenvalues. + * + * In this implementation, the average of the trace is moved into the constant + * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary + * functor. The modification is very simple. If the average of the trace is + * denoted \f$ T \f$ the new parameter becomes: + * \f{ + * \gamma &=& 0.25 \cdot T + * \f} + * + * However, the code was implemented different than described in the original + * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum + * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. + * Furthermore, all parameters were scaled by a factor of 2 in the implementation + * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the + * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType + * can be set which enables the implementation parameters: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 \cdot T + * \f} + * Default is to use parameters from the implementation, not the paper. + * + * Finally, a mask can be provided. Metal or non-standard objects in the field + * of view may throw off the parameter estimation. In those cases, a mask can + * be provided so those voxels are not factored into the calculation of \f$ T \f$. + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter + : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef KrcahEigentoScalarParameterEstimationImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(KrcahEigentoScalarParameterEstimationImageFilter, ImageToImageFilter); + + /** Image related typedefs. */ + typedef typename TInputImage::Pointer InputImagePointer; + typedef typename TInputImage::ConstPointer InputImageConstPointer; + typedef typename TInputImage::RegionType InputRegionType; + typedef typename TInputImage::SizeType InputSizeType; + typedef typename TInputImage::IndexType InputIndexType; + typedef typename TInputImage::PixelType InputPixelType; + typedef typename InputPixelType::ValueType InputPixelValueType; + + /** Output region definitions */ + typedef InputRegionType OutputRegionType; + + /** Mask related typedefs. */ + typedef typename TMaskImage::Pointer MaskImagePointer; + typedef typename TMaskImage::ConstPointer MaskImageConstPointer; + typedef typename TMaskImage::PixelType MaskPixelType; + typedef typename TMaskImage::RegionType MaskRegionType; + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskImage, TMaskImage); + itkGetInputMacro(MaskImage, TMaskImage); + + /** Iterator types */ + itkSetMacro(BackgroundValue, MaskPixelType); + itkGetConstMacro(BackgroundValue, MaskPixelType); + + typedef enum + { + UseImplementationParameters = 1, + UseJournalParameters + } KrcahImplementationType; + itkSetMacro(ParameterSet, KrcahImplementationType); + itkGetConstMacro(ParameterSet, KrcahImplementationType); + + /* Set parameter set */ + void + SetParameterSetToImplementation() + { + this->SetParameterSet(UseImplementationParameters); + } + + void + SetParameterSetToJournalArticle() + { + this->SetParameterSet(UseJournalParameters); + } + + /** Parameters */ + typedef typename NumericTraits::RealType RealType; + typedef SimpleDataObjectDecorator RealTypeDecoratedType; + + itkGetConstMacro(Alpha, RealType); + itkGetConstMacro(Beta, RealType); + itkGetConstMacro(Gamma, RealType); + + RealTypeDecoratedType * + GetAlphaOutput() + { + typename RealTypeDecoratedType::Pointer decoratedAlpha = RealTypeDecoratedType::New(); + decoratedAlpha->Set(this->GetAlpha()); + return decoratedAlpha.GetPointer(); + } + + RealTypeDecoratedType * + GetBetaOutput() + { + typename RealTypeDecoratedType::Pointer decoratedBeta = RealTypeDecoratedType::New(); + decoratedBeta->Set(this->GetBeta()); + return decoratedBeta.GetPointer(); + } + + RealTypeDecoratedType * + GetGammaOutput() + { + typename RealTypeDecoratedType::Pointer decoratedGamma = RealTypeDecoratedType::New(); + decoratedGamma->Set(this->GetGamma()); + return decoratedGamma.GetPointer(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + KrcahEigentoScalarParameterEstimationImageFilter(); + virtual ~KrcahEigentoScalarParameterEstimationImageFilter() {} + + /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ + void + AllocateOutputs() ITK_OVERRIDE; + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + /** Override since the filter needs all the data for the algorithm */ + void + GenerateInputRequestedRegion() ITK_OVERRIDE; + + /** Override since the filter produces all of its output */ + void + EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + + /** Calculation of \f$ T \f$ changes depending on the implementation */ + inline RealType + CalculateNormAccordingToImplementation(InputPixelType pixel); + inline RealType + CalculateNormAccordingToJournalArticle(InputPixelType pixel); + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigentoScalarParameterEstimationImageFilter); + + /* Parameters */ + RealType m_Alpha; + RealType m_Beta; + RealType m_Gamma; + KrcahImplementationType m_ParameterSet; + + /* Inputs */ + MaskPixelType m_BackgroundValue; + + /* Arrays for threads */ + Array m_AccumulatedFrobeniusNorm; + Array m_NumVoxels; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahEigentoScalarParameterEstimationImageFilter.hxx" +#endif + +#endif // itkKrcahEigentoScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx new file mode 100644 index 00000000000..5a6c6dc2a18 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx @@ -0,0 +1,237 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigentoScalarParameterEstimationImageFilter_hxx +#define itkKrcahEigentoScalarParameterEstimationImageFilter_hxx + +#include "itkKrcahEigentoScalarParameterEstimationImageFilter.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkProgressReporter.h" +#include "itkMath.h" + +namespace itk +{ +template +KrcahEigentoScalarParameterEstimationImageFilter::KrcahEigentoScalarParameterEstimationImageFilter() + : m_Alpha(0.5f) + , m_Beta(0.5f) + , m_Gamma(0.5f) + , m_ParameterSet(UseImplementationParameters) + , m_BackgroundValue(NumericTraits::Zero) + , m_NumVoxels(1) + , m_AccumulatedFrobeniusNorm(1) +{ + this->SetNumberOfRequiredInputs(1); +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::AllocateOutputs() +{ + // Pass the input through as the output + InputImagePointer image = const_cast(this->GetInput()); + + this->GraftOutput(image); +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) + { + InputImagePointer image = const_cast(this->GetInput()); + image->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( + DataObject * data) +{ + Superclass::EnlargeOutputRequestedRegion(data); + data->SetRequestedRegionToLargestPossibleRegion(); +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() +{ + ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + /* Resize threads */ + m_AccumulatedFrobeniusNorm.SetSize(numberOfThreads); + m_NumVoxels.SetSize(numberOfThreads); + + m_AccumulatedFrobeniusNorm.Fill(NumericTraits::ZeroValue()); + m_NumVoxels.Fill(NumericTraits::ZeroValue()); +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::AfterThreadedGenerateData() +{ + ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + /* Determine default parameters */ + switch (m_ParameterSet) + { + case UseImplementationParameters: + m_Alpha = 0.5f; + m_Beta = 0.5f; + m_Gamma = 0.5f; + break; + case UseJournalParameters: + m_Alpha = 0.5f; + m_Beta = 0.5f; + m_Gamma = 0.25f; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Accumulate over threads */ + SizeValueType numVoxels = NumericTraits::ZeroValue(); + RealType accumulatedFrobeniusNorm = NumericTraits::ZeroValue(); + + for (unsigned int i = 0; i < numberOfThreads; ++i) + { + numVoxels += m_NumVoxels[i]; + accumulatedFrobeniusNorm += m_AccumulatedFrobeniusNorm[i]; + } + + /* Do derived measure */ + if (numVoxels > 0) + { + RealType averageFrobeniusNorm = (RealType)accumulatedFrobeniusNorm / (RealType)numVoxels; + m_Gamma = m_Gamma * averageFrobeniusNorm; + } +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::ThreadedGenerateData( + const OutputRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Determine which function to call */ + RealType (Self::*normFunction)(InputPixelType); + switch (m_ParameterSet) + { + case UseImplementationParameters: + normFunction = &Self::CalculateNormAccordingToImplementation; + break; + case UseJournalParameters: + normFunction = &Self::CalculateNormAccordingToJournalArticle; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Count starts zero */ + SizeValueType numVoxels = NumericTraits::ZeroValue(); + RealType accumulatedFrobeniusNorm = NumericTraits::ZeroValue(); + + /* Get input pointer */ + InputImagePointer inputPointer = const_cast(this->GetInput()); + + /* Get mask pointer */ + MaskImagePointer maskPointer = TMaskImage::New(); + maskPointer = const_cast(this->GetMaskImage()); + + /* Setup progress reporter */ + ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) + { + numVoxels++; + + /* Compute norm */ + accumulatedFrobeniusNorm += (this->*normFunction)(inputIt.Get()); + } + ++inputIt; + progress.CompletedPixel(); + } + + /* Store this thread */ + m_AccumulatedFrobeniusNorm[threadId] = accumulatedFrobeniusNorm; + m_NumVoxels[threadId] = numVoxels; +} + +template +typename KrcahEigentoScalarParameterEstimationImageFilter::RealType +KrcahEigentoScalarParameterEstimationImageFilter::CalculateNormAccordingToImplementation( + InputPixelType pixel) +{ + /* Sum of the absolute value of the eigenvalues */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += Math::abs(pixel[i]); + } + return norm; +} + +template +typename KrcahEigentoScalarParameterEstimationImageFilter::RealType +KrcahEigentoScalarParameterEstimationImageFilter::CalculateNormAccordingToJournalArticle( + InputPixelType pixel) +{ + /* Sum of the eigenvalues */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i]; + } + return norm; +} + +template +void +KrcahEigentoScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "m_Alpha: " << m_Alpha << std::endl; + os << indent << "m_Beta: " << m_Beta << std::endl; + os << indent << "m_Gamma: " << m_Gamma << std::endl; + os << indent << "m_BackgroundValue: " << m_BackgroundValue << std::endl; + os << indent << "m_ParameterSet: " << m_ParameterSet << std::endl; +} + +} // end namespace itk + +#endif // itkKrcahEigentoScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index cc57656a92c..16b6ef18a07 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -6,6 +6,7 @@ set( itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx + itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -42,3 +43,10 @@ itk_add_test( BoneEnhancementTestDriver itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest ) + +itk_add_test( + NAME itkKrcahEigenToScalarParameterEstimationImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkKrcahEigenToScalarParameterEstimationImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx new file mode 100644 index 00000000000..d0e1919432f --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -0,0 +1,171 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkKrcahEigentoScalarParameterEstimationImageFilter.h" +#include "itkTestingMacros.h" +#include "itkMath.h" +#include "itkImageRegionIteratorWithIndex.h" + +int +itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) +{ + const unsigned int Dimension = 3; + typedef unsigned int MaskPixelType; + typedef itk::Image MaskType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::KrcahEigentoScalarParameterEstimationImageFilter + KrcahEigentoScalarParameterEstimationImageFilterType; + + KrcahEigentoScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = + KrcahEigentoScalarParameterEstimationImageFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS( + krcahParameterEstimator, KrcahEigentoScalarParameterEstimationImageFilter, ImageToImageFilter); + + /* Test defaults */ + TEST_EXPECT_EQUAL(krcahParameterEstimator->GetParameterSet(), + KrcahEigentoScalarParameterEstimationImageFilterType::UseImplementationParameters); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 0.5, 6, 0.000001)); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, -1); + } + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + image2->SetRegions(region); + image2->Allocate(); + image2->FillBuffer(simpleEigenPixel); + + EigenValueImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + EigenValueImageType::SizeType maskSize; + maskSize[0] = 8; + maskSize[1] = 8; + maskSize[2] = 8; + + MaskPixelType backgroundValue = 1; + MaskPixelType foregroundValue = 2; + MaskType::Pointer mask = MaskType::New(); + mask->SetRegions(region); + mask->Allocate(); + mask->FillBuffer(backgroundValue); + + EigenValueArrayType newEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + newEigenPixel.SetElement(i, 3); + } + + EigenValueImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + itk::ImageRegionIteratorWithIndex input2It(image2, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(mask, maskRegion); + + input2It.GoToBegin(); + maskIt.GoToBegin(); + while (!input2It.IsAtEnd()) + { + input2It.Set(newEigenPixel); + maskIt.Set(foregroundValue); + ++input2It; + ++maskIt; + } + + /* Test an empty pixel value */ + krcahParameterEstimator->SetInput(image); + krcahParameterEstimator->SetParameterSetToImplementation(); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 0.5, 6, 0.000001)); + + krcahParameterEstimator->SetParameterSetToJournalArticle(); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 0.25, 6, 0.000001)); + + /* Test with a mask */ + krcahParameterEstimator->SetParameterSetToImplementation(); + krcahParameterEstimator->SetInput(image2); + krcahParameterEstimator->SetMaskImage(mask); + krcahParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.5, 6, 0.000001)); + + krcahParameterEstimator->SetParameterSetToImplementation(); + krcahParameterEstimator->SetBackgroundValue(foregroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 1 * 0.5, 6, 0.000001)); + + krcahParameterEstimator->SetParameterSetToJournalArticle(); + krcahParameterEstimator->SetInput(image2); + krcahParameterEstimator->SetMaskImage(mask); + krcahParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 3 * 0.25, 6, 0.000001)); + + krcahParameterEstimator->SetParameterSetToJournalArticle(); + krcahParameterEstimator->SetBackgroundValue(foregroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_EQUAL(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); + + return EXIT_SUCCESS; +} From 653959af5075b7b6f0e64b6f4a0c2364830d16b9 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 21 Nov 2017 16:45:19 -0700 Subject: [PATCH 019/150] ENH: Completed the Krcah functor --- .../itkKrcahEigenToScalarFunctorImageFilter.h | 263 ++++++++++++++++++ ...cahEigenToScalarFunctorImageFilterTest.cxx | 96 +++++++ .../test/itkKrcahEigenToScalarFunctorTest.cxx | 155 +++++++++++ 3 files changed, 514 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h new file mode 100644 index 00000000000..7db53edcb1e --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -0,0 +1,263 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToScalarFunctorImageFilter_h +#define itkKrcahEigenToScalarFunctorImageFilter_h + +#include "itkUnaryFunctorImageFilter.h" +#include "itkNumericTraits.h" +#include "itkMath.h" + +namespace itk +{ +namespace Functor +{ +/** \class KrcahEigenToScalarFunctor + * \brief Eigenvalue to scalar functor as defined by Krcah et al. + * + * Computes the following equation for eigenvalues in a three + * dimensional fixed array: + * \f{eqnarray*}{ + * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ + * R_{tube} &=& \frac{\lambda_1|}{|\lambda_2| \cdot \lambda_3|} \\ + * R_{noise} &=& \lambda_1| + |\lambda_2| + \lambda_3| \\ + * s &=& sign(\lambda_3) \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \exp\left(- \frac{R_{tube}^2}{\beta^2} + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) + * \f} + * + * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. + * + * \sa KrcahEigentoScalarParameterEstimationImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ +template +class KrcahEigenToScalarFunctor +{ +public: + /* Basic type definitions */ + typedef typename NumericTraits::RealType RealType; + + KrcahEigenToScalarFunctor() + : m_Alpha(1.0) + , m_Beta(1.0) + , m_Gamma(1.0) + , m_Direction(-1.0) + {} + + inline TOutputPixel + operator()(const TInputPixel & A) + { + double sheetness = 0.0; + double a1 = static_cast(A[0]); + double a2 = static_cast(A[1]); + double a3 = static_cast(A[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Avoid divisions by zero (or close to zero) */ + if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) + { + return static_cast(sheetness); + } + + /** + * Compute sheet, noise, and tube like measures. Note that the average trace of the + * Hessian matrix is implicitly included in \f$ \gamma \f$ here. + */ + const double Rsheet = l2 / l3; + const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma + const double Rtube = l1 / (l2 * l3); + + /* Multiply together to get sheetness */ + sheetness = (m_Direction * a3 / l3); + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); + sheetness *= vcl_exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); + + return static_cast(sheetness); + } + + /** Macro definition for set/get of parameters */ + virtual void + SetAlpha(const RealType alpha) + { + this->m_Alpha = alpha; + } + virtual void + SetBeta(const RealType beta) + { + this->m_Beta = beta; + } + virtual void + SetGamma(const RealType gamma) + { + this->m_Gamma = gamma; + } + RealType + GetAlpha() const + { + return this->m_Alpha; + } + RealType + GetBeta() const + { + return this->m_Beta; + } + RealType + GetGamma() const + { + return this->m_Gamma; + } + + /** Set/get the type to enhance */ + void + SetEnhanceBrightObjects() + { + m_Direction = -1.0; + } + void + SetEnhanceDarkObjects() + { + m_Direction = 1.0; + } + RealType + GetEnhanceType() const + { + return m_Direction; + } + +private: + /* Private member variables */ + RealType m_Alpha; + RealType m_Beta; + RealType m_Gamma; + RealType m_Direction; +}; // end class +} // namespace Functor + +/** \class KrcahEigenToScalarFunctorImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. + * + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter + * + * \sa KrcahEigenToScalarFunctor + * \sa KrcahEigenToScalarImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ +template +class KrcahEigenToScalarFunctorImageFilter + : public UnaryFunctorImageFilter< + TInputImage, + TOutputImage, + Functor::KrcahEigenToScalarFunctor> +{ +public: + /** Standard Self typedef */ + typedef KrcahEigenToScalarFunctorImageFilter Self; + typedef UnaryFunctorImageFilter< + TInputImage, + TOutputImage, + Functor::KrcahEigenToScalarFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Useful typedefs for numerics */ + typedef typename Functor::KrcahEigenToScalarFunctor + KrcahFunctorType; + typedef typename KrcahFunctorType::RealType RealType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + + /** Member functions to set/get variables */ + void + SetAlpha(RealType value) + { + this->GetFunctor().SetAlpha(value); + } + void + SetBeta(RealType value) + { + this->GetFunctor().SetBeta(value); + } + void + SetGamma(RealType value) + { + this->GetFunctor().SetGamma(value); + } + RealType + GetAlpha() const + { + return this->GetFunctor().GetAlpha(); + } + RealType + GetBeta() const + { + return this->GetFunctor().GetBeta(); + } + RealType + GetGamma() const + { + return this->GetFunctor().GetGamma(); + } + void + SetEnhanceBrightObjects() + { + this->GetFunctor().SetEnhanceBrightObjects(); + } + void + SetEnhanceDarkObjects() + { + this->GetFunctor().SetEnhanceDarkObjects(); + } + RealType + GetEnhanceType() const + { + return this->GetFunctor().GetEnhanceType(); + } + +protected: + KrcahEigenToScalarFunctorImageFilter() {} + virtual ~KrcahEigenToScalarFunctorImageFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); + + void + PrintSelf(std::ostream & os, Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << indent << "Alpha: " << GetAlpha() << std::endl; + os << indent << "Beta: " << GetBeta() << std::endl; + os << indent << "Gamma: " << GetGamma() << std::endl; + os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; + } +}; // end class +} // namespace itk + +#endif // itkKrcahEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx new file mode 100644 index 00000000000..5ecceee58b4 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx @@ -0,0 +1,96 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkKrcahEigenToScalarFunctorImageFilter.h" +#include "itkUnaryFunctorImageFilter.h" +#include "itkTestingMacros.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkMath.h" + +int +itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) +{ + /* typedefs, instantiate filter */ + const unsigned int Dimension = 3; + typedef double ImagePixelType; + typedef itk::Image ImageType; + + typedef double EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::KrcahEigenToScalarFunctorImageFilter FilterType; + FilterType::Pointer krcahFilter = FilterType::New(); + + /* Basic tests */ + EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + + /* Exercise basic set/get methods */ + krcahFilter->SetAlpha(0.5); + TEST_SET_GET_VALUE(0.5, krcahFilter->GetAlpha()); + krcahFilter->SetBeta(0.5); + TEST_SET_GET_VALUE(0.5, krcahFilter->GetBeta()); + krcahFilter->SetGamma(0.25); + TEST_SET_GET_VALUE(0.25, krcahFilter->GetGamma()); + // Default should be -1 + TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); + krcahFilter->SetEnhanceDarkObjects(); + TEST_SET_GET_VALUE(1.0, krcahFilter->GetEnhanceType()); + krcahFilter->SetEnhanceBrightObjects(); + TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, 0); + } + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + krcahFilter->SetInput(image); + TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + + itk::ImageRegionIteratorWithIndex input(krcahFilter->GetOutput(), region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); + ++input; + } + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx new file mode 100644 index 00000000000..4a32f05c0ca --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx @@ -0,0 +1,155 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkKrcahEigenToScalarFunctorImageFilter.h" +#include "itkTestingMacros.h" + +int +itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) +{ + /* typedefs, instantiate functor */ + const unsigned int Dimension = 3; + typedef double ImagePixelType; + typedef itk::Image ImageType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::Functor::KrcahEigenToScalarFunctor FunctorType; + FunctorType functor = FunctorType(); + + /* Exercise basic set/get methods */ + functor.SetAlpha(0.5); + TEST_SET_GET_VALUE(0.5, functor.GetAlpha()); + functor.SetBeta(0.5); + TEST_SET_GET_VALUE(0.5, functor.GetBeta()); + functor.SetGamma(0.25); + TEST_SET_GET_VALUE(0.25, functor.GetGamma()); + // Default should be -1 + TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + functor.SetEnhanceDarkObjects(); + TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); + functor.SetEnhanceBrightObjects(); + TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + + /* Test a few calculations */ + EigenValueArrayType mEigenValueArray; + functor.SetAlpha(0.5); + functor.SetBeta(0.5); + functor.SetGamma(0.25); + functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = 0; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* lambda_2 zeros returns zero */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = 1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* lambda_1 zero */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.0183156368276, 6, 0.000001)); + + /* lambda_1 zero; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0183156368276, 6, 0.000001)); + + /* one, one, one */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = 1; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); + + /* one, one, one; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = 1; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); + + /* one, one, one negative */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = -1; + mEigenValueArray[1] = -1; + mEigenValueArray[2] = -1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); + + /* one, one, one negative; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = -1; + mEigenValueArray[1] = -1; + mEigenValueArray[2] = -1; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); + + /* -1, -2, 3 */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = -1; + mEigenValueArray[1] = -2; + mEigenValueArray[2] = 3; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.15123975969, 6, 0.000001)); + + /* -1, -2, 3; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = -1; + mEigenValueArray[1] = -2; + mEigenValueArray[2] = 3; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.15123975969, 6, 0.000001)); + + /* Perfect Joint */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 1000; + mEigenValueArray[2] = 100000000; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); + + /* Perfect Joint; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 1000; + mEigenValueArray[2] = 100000000; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); + + /* Perfect Bone */ + functor.SetEnhanceBrightObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = -1000; + mEigenValueArray[2] = -100000000; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); + + /* Perfect Bone; dark sheets */ + functor.SetEnhanceDarkObjects(); + mEigenValueArray[0] = 0; + mEigenValueArray[1] = -1000; + mEigenValueArray[2] = -100000000; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); + + return EXIT_SUCCESS; +} From 8f83ba5ce3086033593f36bd8c99cfd7256aec85 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 09:46:42 -0700 Subject: [PATCH 020/150] STYLE: Changed Krcah parameter estimation to use process outputs, fixed lower case t typo --- ...entoScalarParameterEstimationImageFilter.h | 74 ++++++----- ...toScalarParameterEstimationImageFilter.hxx | 120 +++++++++++++----- ...alarParameterEstimationImageFilterTest.cxx | 17 ++- 3 files changed, 137 insertions(+), 74 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h index 4d9beeb0ff8..7f6f1d9e6d2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h @@ -16,17 +16,23 @@ * *=========================================================================*/ -#ifndef itkKrcahEigentoScalarParameterEstimationImageFilter_h -#define itkKrcahEigentoScalarParameterEstimationImageFilter_h +#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_h +#define itkKrcahEigenToScalarParameterEstimationImageFilter_h #include "itkImageToImageFilter.h" #include "itkNumericTraits.h" #include "itkSimpleDataObjectDecorator.h" #include "itkArray.h" +/* +Need to use decorators +https://github.com/InsightSoftwareConsortium/ITK/blob/6883e0007ee69e0c8fd9afde79c56fa052e699d7/Modules/Filtering/ImageStatistics/include/itkStatisticsImageFilter.h +https://github.com/InsightSoftwareConsortium/ITK/blob/6883e0007ee69e0c8fd9afde79c56fa052e699d7/Modules/Filtering/ImageStatistics/include/itkStatisticsImageFilter.hxx +*/ + namespace itk { -/** \class KrcahEigentoScalarParameterEstimationImageFilter +/** \class KrcahEigenToScalarParameterEstimationImageFilter * \brief Abstract class for converting eigenvalue image to scalar image. * * This class takes an image of eigenvalues and estimates the parameters for the Krcah @@ -72,12 +78,12 @@ namespace itk * \ingroup BoneEnhancement */ template -class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter +class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter : public ImageToImageFilter { public: /** Standard Self typedef */ - typedef KrcahEigentoScalarParameterEstimationImageFilter Self; + typedef KrcahEigenToScalarParameterEstimationImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; @@ -86,7 +92,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigentoScalarParameterEstimationImageFilter, ImageToImageFilter); + itkTypeMacro(KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); /** Image related typedefs. */ typedef typename TInputImage::Pointer InputImagePointer; @@ -139,32 +145,35 @@ class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter typedef typename NumericTraits::RealType RealType; typedef SimpleDataObjectDecorator RealTypeDecoratedType; - itkGetConstMacro(Alpha, RealType); - itkGetConstMacro(Beta, RealType); - itkGetConstMacro(Gamma, RealType); - + /** Decorators for parameters so they can be passed as a process object */ + RealTypeDecoratedType * + GetAlphaOutput(); + const RealTypeDecoratedType * + GetAlphaOutput() const; RealTypeDecoratedType * - GetAlphaOutput() + GetBetaOutput(); + const RealTypeDecoratedType * + GetBetaOutput() const; + RealTypeDecoratedType * + GetGammaOutput(); + const RealTypeDecoratedType * + GetGammaOutput() const; + + /** Standard getters for the output parameters */ + RealType + GetAlpha() const { - typename RealTypeDecoratedType::Pointer decoratedAlpha = RealTypeDecoratedType::New(); - decoratedAlpha->Set(this->GetAlpha()); - return decoratedAlpha.GetPointer(); + return this->GetAlphaOutput()->Get(); } - - RealTypeDecoratedType * - GetBetaOutput() + RealType + GetBeta() const { - typename RealTypeDecoratedType::Pointer decoratedBeta = RealTypeDecoratedType::New(); - decoratedBeta->Set(this->GetBeta()); - return decoratedBeta.GetPointer(); + return this->GetBetaOutput()->Get(); } - - RealTypeDecoratedType * - GetGammaOutput() + RealType + GetGamma() const { - typename RealTypeDecoratedType::Pointer decoratedGamma = RealTypeDecoratedType::New(); - decoratedGamma->Set(this->GetGamma()); - return decoratedGamma.GetPointer(); + return this->GetGammaOutput()->Get(); } #ifdef ITK_USE_CONCEPT_CHECKING @@ -173,8 +182,8 @@ class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter // End concept checking #endif protected: - KrcahEigentoScalarParameterEstimationImageFilter(); - virtual ~KrcahEigentoScalarParameterEstimationImageFilter() {} + KrcahEigenToScalarParameterEstimationImageFilter(); + virtual ~KrcahEigenToScalarParameterEstimationImageFilter() {} /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ void @@ -210,12 +219,9 @@ class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter CalculateNormAccordingToJournalArticle(InputPixelType pixel); private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigentoScalarParameterEstimationImageFilter); + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); /* Parameters */ - RealType m_Alpha; - RealType m_Beta; - RealType m_Gamma; KrcahImplementationType m_ParameterSet; /* Inputs */ @@ -228,7 +234,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigentoScalarParameterEstimationImageFilter } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigentoScalarParameterEstimationImageFilter.hxx" +# include "itkKrcahEigenToScalarParameterEstimationImageFilter.hxx" #endif -#endif // itkKrcahEigentoScalarParameterEstimationImageFilter_h +#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx index 5a6c6dc2a18..d22b585353d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx @@ -16,10 +16,10 @@ * *=========================================================================*/ -#ifndef itkKrcahEigentoScalarParameterEstimationImageFilter_hxx -#define itkKrcahEigentoScalarParameterEstimationImageFilter_hxx +#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_hxx +#define itkKrcahEigenToScalarParameterEstimationImageFilter_hxx -#include "itkKrcahEigentoScalarParameterEstimationImageFilter.h" +#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkProgressReporter.h" #include "itkMath.h" @@ -27,32 +27,38 @@ namespace itk { template -KrcahEigentoScalarParameterEstimationImageFilter::KrcahEigentoScalarParameterEstimationImageFilter() - : m_Alpha(0.5f) - , m_Beta(0.5f) - , m_Gamma(0.5f) - , m_ParameterSet(UseImplementationParameters) +KrcahEigenToScalarParameterEstimationImageFilter::KrcahEigenToScalarParameterEstimationImageFilter() + : m_ParameterSet(UseImplementationParameters) , m_BackgroundValue(NumericTraits::Zero) , m_NumVoxels(1) , m_AccumulatedFrobeniusNorm(1) { + /* We require an input, optional mask */ this->SetNumberOfRequiredInputs(1); + + /* Allocate all decorators */ + for (int i = 1; i < 4; ++i) + { + this->ProcessObject::SetNthOutput(i, RealTypeDecoratedType::New().GetPointer()); + } + this->GetAlphaOutput()->Set(0.5); + this->GetBetaOutput()->Set(0.5); + this->GetGammaOutput()->Set(0.5); } template void -KrcahEigentoScalarParameterEstimationImageFilter::AllocateOutputs() +KrcahEigenToScalarParameterEstimationImageFilter::AllocateOutputs() { - // Pass the input through as the output + /* Pass the input through as the output */ InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); } template void -KrcahEigentoScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() +KrcahEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); if (this->GetInput()) @@ -64,7 +70,7 @@ KrcahEigentoScalarParameterEstimationImageFilter::Gener template void -KrcahEigentoScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( +KrcahEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( DataObject * data) { Superclass::EnlargeOutputRequestedRegion(data); @@ -73,7 +79,7 @@ KrcahEigentoScalarParameterEstimationImageFilter::Enlar template void -KrcahEigentoScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() +KrcahEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() { ThreadIdType numberOfThreads = this->GetNumberOfThreads(); @@ -87,22 +93,23 @@ KrcahEigentoScalarParameterEstimationImageFilter::Befor template void -KrcahEigentoScalarParameterEstimationImageFilter::AfterThreadedGenerateData() +KrcahEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() { ThreadIdType numberOfThreads = this->GetNumberOfThreads(); /* Determine default parameters */ + RealType alpha, beta, gamma; switch (m_ParameterSet) { case UseImplementationParameters: - m_Alpha = 0.5f; - m_Beta = 0.5f; - m_Gamma = 0.5f; + alpha = 0.5f; + beta = 0.5f; + gamma = 0.5f; break; case UseJournalParameters: - m_Alpha = 0.5f; - m_Beta = 0.5f; - m_Gamma = 0.25f; + alpha = 0.5f; + beta = 0.5f; + gamma = 0.25f; break; default: itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); @@ -123,13 +130,18 @@ KrcahEigentoScalarParameterEstimationImageFilter::After if (numVoxels > 0) { RealType averageFrobeniusNorm = (RealType)accumulatedFrobeniusNorm / (RealType)numVoxels; - m_Gamma = m_Gamma * averageFrobeniusNorm; + gamma = gamma * averageFrobeniusNorm; } + + /* Assign outputs */ + this->GetAlphaOutput()->Set(alpha); + this->GetBetaOutput()->Set(beta); + this->GetGammaOutput()->Set(gamma); } template void -KrcahEigentoScalarParameterEstimationImageFilter::ThreadedGenerateData( +KrcahEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( const OutputRegionType & outputRegionForThread, ThreadIdType threadId) { @@ -192,8 +204,8 @@ KrcahEigentoScalarParameterEstimationImageFilter::Threa } template -typename KrcahEigentoScalarParameterEstimationImageFilter::RealType -KrcahEigentoScalarParameterEstimationImageFilter::CalculateNormAccordingToImplementation( +typename KrcahEigenToScalarParameterEstimationImageFilter::RealType +KrcahEigenToScalarParameterEstimationImageFilter::CalculateNormAccordingToImplementation( InputPixelType pixel) { /* Sum of the absolute value of the eigenvalues */ @@ -206,8 +218,8 @@ KrcahEigentoScalarParameterEstimationImageFilter::Calcu } template -typename KrcahEigentoScalarParameterEstimationImageFilter::RealType -KrcahEigentoScalarParameterEstimationImageFilter::CalculateNormAccordingToJournalArticle( +typename KrcahEigenToScalarParameterEstimationImageFilter::RealType +KrcahEigenToScalarParameterEstimationImageFilter::CalculateNormAccordingToJournalArticle( InputPixelType pixel) { /* Sum of the eigenvalues */ @@ -219,19 +231,61 @@ KrcahEigentoScalarParameterEstimationImageFilter::Calcu return norm; } +template +typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() +{ + return static_cast(this->ProcessObject::GetOutput(2)); +} + +template +const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(2)); +} + +template +typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() +{ + return static_cast(this->ProcessObject::GetOutput(3)); +} + +template +const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(3)); +} + template void -KrcahEigentoScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, +KrcahEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "m_Alpha: " << m_Alpha << std::endl; - os << indent << "m_Beta: " << m_Beta << std::endl; - os << indent << "m_Gamma: " << m_Gamma << std::endl; + os << indent << "m_Alpha: " << this->GetAlpha() << std::endl; + os << indent << "m_Beta: " << this->GetBeta() << std::endl; + os << indent << "m_Gamma: " << this->GetGamma() << std::endl; os << indent << "m_BackgroundValue: " << m_BackgroundValue << std::endl; os << indent << "m_ParameterSet: " << m_ParameterSet << std::endl; } } // end namespace itk -#endif // itkKrcahEigentoScalarParameterEstimationImageFilter_hxx +#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index d0e1919432f..60dd154d93e 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -16,7 +16,7 @@ * *=========================================================================*/ -#include "itkKrcahEigentoScalarParameterEstimationImageFilter.h" +#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" #include "itkTestingMacros.h" #include "itkMath.h" #include "itkImageRegionIteratorWithIndex.h" @@ -32,21 +32,24 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) typedef itk::FixedArray EigenValueArrayType; typedef itk::Image EigenValueImageType; - typedef itk::KrcahEigentoScalarParameterEstimationImageFilter - KrcahEigentoScalarParameterEstimationImageFilterType; + typedef itk::KrcahEigenToScalarParameterEstimationImageFilter + KrcahEigenToScalarParameterEstimationImageFilterType; - KrcahEigentoScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = - KrcahEigentoScalarParameterEstimationImageFilterType::New(); + KrcahEigenToScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = + KrcahEigenToScalarParameterEstimationImageFilterType::New(); EXERCISE_BASIC_OBJECT_METHODS( - krcahParameterEstimator, KrcahEigentoScalarParameterEstimationImageFilter, ImageToImageFilter); + krcahParameterEstimator, KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); /* Test defaults */ TEST_EXPECT_EQUAL(krcahParameterEstimator->GetParameterSet(), - KrcahEigentoScalarParameterEstimationImageFilterType::UseImplementationParameters); + KrcahEigenToScalarParameterEstimationImageFilterType::UseImplementationParameters); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGammaOutput()->Get(), 0.5, 6, 0.000001)); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; From f478190981be9ec76e6d970cfa1b9d4dac1ba9fe Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 10:19:03 -0700 Subject: [PATCH 021/150] ENH: Allow KrcahEigenToScalarFunctorImageFilter to accept decorated inputs --- .../itkKrcahEigenToScalarFunctorImageFilter.h | 58 ++++++++----------- .../BoneEnhancement/test/CMakeLists.txt | 16 +++++ 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 7db53edcb1e..32aef3ebac1 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -22,6 +22,7 @@ #include "itkUnaryFunctorImageFilter.h" #include "itkNumericTraits.h" #include "itkMath.h" +#include "itkSimpleDataObjectDecorator.h" namespace itk { @@ -55,10 +56,7 @@ class KrcahEigenToScalarFunctor typedef typename NumericTraits::RealType RealType; KrcahEigenToScalarFunctor() - : m_Alpha(1.0) - , m_Beta(1.0) - , m_Gamma(1.0) - , m_Direction(-1.0) + : m_Direction(-1.0) {} inline TOutputPixel @@ -194,37 +192,25 @@ class KrcahEigenToScalarFunctorImageFilter /** Runtime information support. */ itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - /** Member functions to set/get variables */ - void - SetAlpha(RealType value) - { - this->GetFunctor().SetAlpha(value); - } - void - SetBeta(RealType value) - { - this->GetFunctor().SetBeta(value); - } + /** Define decorator types */ + typedef SimpleDataObjectDecorator InputAlphaObjectType; + + /** Process object */ + itkSetGetDecoratedInputMacro(Alpha, RealType); + itkSetGetDecoratedInputMacro(Beta, RealType); + itkSetGetDecoratedInputMacro(Gamma, RealType); + + /** Need to access the input parameters at execution time */ void - SetGamma(RealType value) - { - this->GetFunctor().SetGamma(value); - } - RealType - GetAlpha() const + BeforeThreadedGenerateData() ITK_OVERRIDE { - return this->GetFunctor().GetAlpha(); - } - RealType - GetBeta() const - { - return this->GetFunctor().GetBeta(); - } - RealType - GetGamma() const - { - return this->GetFunctor().GetGamma(); + this->GetFunctor().SetAlpha(this->GetAlpha()); + this->GetFunctor().SetBeta(this->GetBeta()); + this->GetFunctor().SetGamma(this->GetGamma()); + Superclass::BeforeThreadedGenerateData(); } + + /** setter/getter methods for setting type of object to enhance */ void SetEnhanceBrightObjects() { @@ -242,7 +228,13 @@ class KrcahEigenToScalarFunctorImageFilter } protected: - KrcahEigenToScalarFunctorImageFilter() {} + KrcahEigenToScalarFunctorImageFilter() + { + /* Need to set initial values */ + this->SetAlpha(1.0); + this->SetBeta(1.0); + this->SetGamma(1.0); + } virtual ~KrcahEigenToScalarFunctorImageFilter() {} private: diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 16b6ef18a07..43df94eda5d 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -7,6 +7,8 @@ set( itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx + itkKrcahEigenToScalarFunctorTest.cxx + itkKrcahEigenToScalarFunctorImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -50,3 +52,17 @@ itk_add_test( BoneEnhancementTestDriver itkKrcahEigenToScalarParameterEstimationImageFilterTest ) + +itk_add_test( + NAME itkKrcahEigenToScalarFunctorTest + COMMAND + BoneEnhancementTestDriver + itkKrcahEigenToScalarFunctorTest +) + +itk_add_test( + NAME itkKrcahEigenToScalarFunctorImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkKrcahEigenToScalarFunctorImageFilterTest +) From b5b917e292724aa0cafffae872da98e081cb5570 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 13:55:54 -0700 Subject: [PATCH 022/150] BUG: Fixed constructor in EigenToScalarImageFilter --- .../BoneEnhancement/include/itkEigenToScalarImageFilter.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 886e0c6e8eb..6910bc2cbf4 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -62,7 +62,7 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter Date: Mon, 27 Nov 2017 13:59:58 -0700 Subject: [PATCH 023/150] ENH: Implemented KrcahEigenToScalarImageFilter --- .../itkKrcahEigenToScalarImageFilter.h | 186 ++++++++++++++++++ .../itkKrcahEigenToScalarImageFilter.hxx | 74 +++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + .../itkKrcahEigenToScalarImageFilterTest.cxx | 96 +++++++++ 4 files changed, 364 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h new file mode 100644 index 00000000000..ea691fc12f6 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -0,0 +1,186 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToScalarImageFilter_h +#define itkKrcahEigenToScalarImageFilter_h + +#include "itkEigenToScalarImageFilter.h" +#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" +#include "itkKrcahEigenToScalarFunctorImageFilter.h" + +namespace itk +{ +/** \class KrcahEigenToScalarImageFilter + * \brief Abstract class for converting eigenvalue image to scalar image. + * + * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. + * Other classes should inherit from this class so they can be used in the BoneEnhancement framework. This abstract + * class guarantees that the variable EigenValueOrder has a valid type and enforces some concept checking + * on the class template parameters: TInputImage and TOutputImage . TODO + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa EigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template > +class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarImageFilter +{ +public: + /** Standard Self typedef */ + typedef KrcahEigenToScalarImageFilter Self; + typedef EigenToScalarImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); + + /** Mask related typedefs. */ + typedef typename TMaskImage::PixelType MaskPixelType; + + /** Procesing filters */ + typedef KrcahEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; + typedef typename ParameterEstimationFilterType::KrcahImplementationType KrcahImplementationType; + typedef KrcahEigenToScalarFunctorImageFilter UnaryFunctorFilterType; + + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + + /** Methods to set/get the mask image */ + void + SetMaskImage(const TMaskImage * mask) + { + this->m_ParameterEstimationFilter->SetMaskImage(mask); + } + virtual const TMaskImage * + GetMaskImage() const + { + return this->m_ParameterEstimationFilter->GetMaskImage(); + } + + /** Methods to set/get the background value */ + virtual void + SetBackgroundValue(const MaskPixelType back) + { + this->m_ParameterEstimationFilter->SetBackgroundValue(back); + } + virtual MaskPixelType + GetBackgroundValue() const + { + return this->m_ParameterEstimationFilter->GetBackgroundValue(); + } + + /** Methods to set/get the parameter set type */ + virtual void + SetParameterSet(const KrcahImplementationType back) + { + this->m_ParameterEstimationFilter->SetParameterSet(back); + } + virtual KrcahImplementationType + GetParameterSet() const + { + return this->m_ParameterEstimationFilter->GetParameterSet(); + } + virtual void + SetParameterSetToImplementation() + { + this->m_ParameterEstimationFilter->SetParameterSetToImplementation(); + } + virtual void + SetParameterSetToJournalArticle() + { + this->m_ParameterEstimationFilter->SetParameterSetToJournalArticle(); + } + + /** Methods to get the computed parameters */ + typename UnaryFunctorFilterType::RealType + GetAlpha() const + { + return m_UnaryFunctorFilter->GetAlpha(); + } + typename UnaryFunctorFilterType::RealType + GetBeta() const + { + return m_UnaryFunctorFilter->GetBeta(); + } + typename UnaryFunctorFilterType::RealType + GetGamma() const + { + return m_UnaryFunctorFilter->GetGamma(); + } + + /** Methods to set/get the enhancment method */ + void + SetEnhanceBrightObjects() + { + this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); + } + void + SetEnhanceDarkObjects() + { + this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); + } + typename UnaryFunctorFilterType::RealType + GetEnhanceType() const + { + return this->m_UnaryFunctorFilter->GetEnhanceType(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + KrcahEigenToScalarImageFilter(); + virtual ~KrcahEigenToScalarImageFilter() {} + + /** Single threaded since we are connecting data */ + void + GenerateData() ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); + + /* Filter pipeline */ + typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; + typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahEigenToScalarImageFilter.hxx" +#endif + +#endif // itkKrcahEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx new file mode 100644 index 00000000000..e1fe9a63818 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx @@ -0,0 +1,74 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkKrcahEigenToScalarImageFilter_hxx +#define itkKrcahEigenToScalarImageFilter_hxx + +#include "itkKrcahEigenToScalarImageFilter.h" +#include "itkProgressAccumulator.h" + +namespace itk +{ +template +KrcahEigenToScalarImageFilter::KrcahEigenToScalarImageFilter() +{ + /* Instantiate filters. */ + m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); + m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); + + /* We require an input image */ + this->SetNumberOfRequiredInputs(1); +} + +template +void +KrcahEigenToScalarImageFilter::GenerateData() +{ + /* Get input */ + typename TInputImage::Pointer input = TInputImage::New(); + input->Graft(const_cast(this->GetInput())); + + /* Connect filters */ + m_ParameterEstimationFilter->SetInput(input); + m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); + m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); + m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); + m_UnaryFunctorFilter->SetGammaInput(m_ParameterEstimationFilter->GetGammaOutput()); + + /* Setup progress reporter */ + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); + progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); + + /* Graft output and we're done! */ + m_UnaryFunctorFilter->Update(); + this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); +} + +template +void +KrcahEigenToScalarImageFilter::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; + os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; +} + +} // namespace itk + +#endif // itkKrcahEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 43df94eda5d..4c7a0767edd 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -9,6 +9,7 @@ set( itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx itkKrcahEigenToScalarFunctorTest.cxx itkKrcahEigenToScalarFunctorImageFilterTest.cxx + itkKrcahEigenToScalarImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -66,3 +67,10 @@ itk_add_test( BoneEnhancementTestDriver itkKrcahEigenToScalarFunctorImageFilterTest ) + +itk_add_test( + NAME itkKrcahEigenToScalarImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkKrcahEigenToScalarImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx new file mode 100644 index 00000000000..ebd40560e29 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx @@ -0,0 +1,96 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkKrcahEigenToScalarImageFilter.h" +#include "itkTestingMacros.h" +#include "itkMath.h" +#include "itkImageRegionIteratorWithIndex.h" + +int +itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) +{ + const unsigned int Dimension = 3; + typedef unsigned int MaskPixelType; + typedef itk::Image MaskType; + + typedef double OutputPixelType; + typedef itk::Image OutputType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::KrcahEigenToScalarImageFilter + KrcahEigenToScalarImageFilterType; + + KrcahEigenToScalarImageFilterType::Pointer krcahFilter = KrcahEigenToScalarImageFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); + + /* Test defaults */ + TEST_EXPECT_EQUAL(krcahFilter->GetEigenValueOrder(), KrcahEigenToScalarImageFilterType::Superclass::OrderByMagnitude); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, -1); + } + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + /* Run with no exceptions */ + krcahFilter->SetParameterSetToImplementation(); + krcahFilter->SetEnhanceBrightObjects(); + krcahFilter->SetInput(image); + TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + + /* Make sure process for setting parameters works */ + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), 3 * 0.5, 6, 0.000001)); + + itk::ImageRegionIteratorWithIndex it(krcahFilter->GetOutput(), region); + + it.GoToBegin(); + while (!it.IsAtEnd()) + { + // TODO: Why is this not 0.000335462627903 as before? + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.000329318, 6, 0.000001)); + ++it; + } + + return EXIT_SUCCESS; +} From f9d94cefbc9763c0bc15a940811f1462de0825f6 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 14:00:25 -0700 Subject: [PATCH 024/150] BUG: Fixed error in rcahEigenToScalarFunctorImageFilter and KrcahEigentoScalarParameterEstimationImageFilter --- .../itkKrcahEigenToScalarFunctorImageFilter.h | 18 ++++-------- ...entoScalarParameterEstimationImageFilter.h | 6 ---- ...toScalarParameterEstimationImageFilter.hxx | 10 +++---- ...cahEigenToScalarFunctorImageFilterTest.cxx | 28 ++++++++++++++++++- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 32aef3ebac1..e21f1029c46 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -193,7 +193,7 @@ class KrcahEigenToScalarFunctorImageFilter itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /** Define decorator types */ - typedef SimpleDataObjectDecorator InputAlphaObjectType; + typedef SimpleDataObjectDecorator InputParameterDecoratorType; /** Process object */ itkSetGetDecoratedInputMacro(Alpha, RealType); @@ -204,10 +204,10 @@ class KrcahEigenToScalarFunctorImageFilter void BeforeThreadedGenerateData() ITK_OVERRIDE { - this->GetFunctor().SetAlpha(this->GetAlpha()); - this->GetFunctor().SetBeta(this->GetBeta()); - this->GetFunctor().SetGamma(this->GetGamma()); - Superclass::BeforeThreadedGenerateData(); + /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ + this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); + this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); + this->GetFunctor().SetGamma(this->GetGammaInput()->Get()); } /** setter/getter methods for setting type of object to enhance */ @@ -228,13 +228,7 @@ class KrcahEigenToScalarFunctorImageFilter } protected: - KrcahEigenToScalarFunctorImageFilter() - { - /* Need to set initial values */ - this->SetAlpha(1.0); - this->SetBeta(1.0); - this->SetGamma(1.0); - } + KrcahEigenToScalarFunctorImageFilter() {} virtual ~KrcahEigenToScalarFunctorImageFilter() {} private: diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h index 7f6f1d9e6d2..ba318046982 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h @@ -24,12 +24,6 @@ #include "itkSimpleDataObjectDecorator.h" #include "itkArray.h" -/* -Need to use decorators -https://github.com/InsightSoftwareConsortium/ITK/blob/6883e0007ee69e0c8fd9afde79c56fa052e699d7/Modules/Filtering/ImageStatistics/include/itkStatisticsImageFilter.h -https://github.com/InsightSoftwareConsortium/ITK/blob/6883e0007ee69e0c8fd9afde79c56fa052e699d7/Modules/Filtering/ImageStatistics/include/itkStatisticsImageFilter.hxx -*/ - namespace itk { /** \class KrcahEigenToScalarParameterEstimationImageFilter diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx index d22b585353d..abd31dcf150 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx @@ -36,15 +36,15 @@ KrcahEigenToScalarParameterEstimationImageFilterSetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(4); /* Allocate all decorators */ for (int i = 1; i < 4; ++i) { - this->ProcessObject::SetNthOutput(i, RealTypeDecoratedType::New().GetPointer()); + typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); + output->Set(0.5); + this->ProcessObject::SetNthOutput(i, output.GetPointer()); } - this->GetAlphaOutput()->Set(0.5); - this->GetBetaOutput()->Set(0.5); - this->GetGammaOutput()->Set(0.5); } template @@ -133,7 +133,7 @@ KrcahEigenToScalarParameterEstimationImageFilter::After gamma = gamma * averageFrobeniusNorm; } - /* Assign outputs */ + /* Assign outputs parameters */ this->GetAlphaOutput()->Set(alpha); this->GetBetaOutput()->Set(beta); this->GetGammaOutput()->Set(gamma); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx index 5ecceee58b4..05e9f5839d2 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx @@ -37,7 +37,10 @@ itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) typedef itk::KrcahEigenToScalarFunctorImageFilter FilterType; FilterType::Pointer krcahFilter = FilterType::New(); - /* Basic tests */ + /* Basic tests. Need to set parameters first. */ + krcahFilter->SetAlpha(0.5); + krcahFilter->SetBeta(0.5); + krcahFilter->SetGamma(0.25); EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /* Exercise basic set/get methods */ @@ -92,5 +95,28 @@ itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) ++input; } + /* Create some test data which is computable */ + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, -1); + } + + EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + image2->SetRegions(region); + image2->Allocate(); + image2->FillBuffer(simpleEigenPixel); + + krcahFilter->SetInput(image2); + TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + + itk::ImageRegionIteratorWithIndex input2(krcahFilter->GetOutput(), region); + + input2.GoToBegin(); + while (!input2.IsAtEnd()) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.000335462627903, 6, 0.000001)); + ++input2; + } + return EXIT_SUCCESS; } From a2b8b6abc2b4fd5b164049d910439b3e900d601a Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 27 Nov 2017 15:52:57 -0700 Subject: [PATCH 025/150] ENH: Added Krcah preprocessing --- ...nToScalarPreprocessingImageToImageFilter.h | 109 ++++++++++++++++++ ...oScalarPreprocessingImageToImageFilter.hxx | 107 +++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 ++ ...larPreprocessingImageToImageFilterTest.cxx | 43 +++++++ 4 files changed, 267 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h new file mode 100644 index 00000000000..8984f898900 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -0,0 +1,109 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_h +#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkDiscreteGaussianImageFilter.h" +#include "itkSubtractImageFilter.h" +#include "itkMultiplyImageFilter.h" +#include "itkAddImageFilter.h" + +namespace itk +{ +/** \class KrcahEigenToScalarPreprocessingImageToImageFilter + * \brief TODO + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter + : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef KrcahEigenToScalarPreprocessingImageToImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); + + /** Image related typedefs. */ + typedef typename TInputImage::PixelType PixelType; + typedef typename NumericTraits::RealType RealType; + + /** Typedefs for internal filters */ + typedef DiscreteGaussianImageFilter GaussianFilterType; + typedef SubtractImageFilter SubstractFilterType; + typedef MultiplyImageFilter MultiplyFilterType; + typedef AddImageFilter AddFilterType; + + /** Flag to release data or not */ + itkSetMacro(ReleaseInternalFilterData, bool); + itkGetConstMacro(ReleaseInternalFilterData, bool); + itkBooleanMacro(ReleaseInternalFilterData); + + /** Flag to release data or not */ + itkSetMacro(Sigma, RealType); + itkGetConstMacro(Sigma, RealType); + + /** Flag to release data or not */ + itkSetMacro(ScalingConstant, RealType); + itkGetConstMacro(ScalingConstant, RealType); + +protected: + KrcahEigenToScalarPreprocessingImageToImageFilter(); + virtual ~KrcahEigenToScalarPreprocessingImageToImageFilter() {} + + /** Single threaded since we are connecting data */ + void + GenerateData() ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); + + /* Internal member variables */ + RealType m_Sigma; + RealType m_ScalingConstant; + bool m_ReleaseInternalFilterData; + + /* Filter member variables */ + typename GaussianFilterType::Pointer m_GaussianFilter; + typename SubstractFilterType::Pointer m_SubtractFilter; + typename MultiplyFilterType::Pointer m_MultiplyFilter; + typename AddFilterType::Pointer m_AddFilter; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx" +#endif + +#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx new file mode 100644 index 00000000000..d178434aa0c --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx @@ -0,0 +1,107 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx +#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx + +#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" +#include "itkMath.h" + +namespace itk +{ +template +KrcahEigenToScalarPreprocessingImageToImageFilter::KrcahEigenToScalarPreprocessingImageToImageFilter() + : m_Sigma(1.0f) + , m_ScalingConstant(10.0f) + , m_ReleaseInternalFilterData(true) +{ + /* Only need the input image */ + this->SetNumberOfRequiredInputs(1); + + /* Instantiate all filters */ + m_GaussianFilter = GaussianFilterType::New(); + m_SubtractFilter = SubstractFilterType::New(); + m_MultiplyFilter = MultiplyFilterType::New(); + m_AddFilter = AddFilterType::New(); +} + +template +void +KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateData() +{ + /* Get Input */ + typename TInputImage::Pointer input = TInputImage::New(); + input->Graft(const_cast(this->GetInput())); + + /* I*G */ + m_GaussianFilter->SetInput(input); + m_GaussianFilter->SetVariance(Math::squared_magnitude(this->GetSigma())); + + /* I - I*G */ + m_SubtractFilter->SetInput1(input); + m_SubtractFilter->SetInput2(m_GaussianFilter->GetOutput()); + + /* k(I-(I*G)) */ + m_MultiplyFilter->SetInput(m_SubtractFilter->GetOutput()); + m_MultiplyFilter->SetConstant(this->GetScalingConstant()); + + /* I+k*(I-(I*G)) */ + m_AddFilter->SetInput1(input); + m_AddFilter->SetInput2(m_MultiplyFilter->GetOutput()); + + /* Release data if asked */ + if (this->GetReleaseInternalFilterData()) + { + m_GaussianFilter->ReleaseDataFlagOn(); + m_SubtractFilter->ReleaseDataFlagOn(); + m_MultiplyFilter->ReleaseDataFlagOn(); + m_AddFilter->ReleaseDataFlagOn(); + } + + /* Setup progress reporter */ + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + progress->RegisterInternalFilter(m_GaussianFilter, 0.25); + progress->RegisterInternalFilter(m_SubtractFilter, 0.25); + progress->RegisterInternalFilter(m_MultiplyFilter, 0.25); + progress->RegisterInternalFilter(m_AddFilter, 0.25); + + /* Graft Output */ + m_AddFilter->Update(); + this->GraftOutput(m_AddFilter->GetOutput()); +} + +template +void +KrcahEigenToScalarPreprocessingImageToImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "GaussianFilter: " << m_GaussianFilter.GetPointer() << std::endl; + os << indent << "SubtractFilter: " << m_SubtractFilter.GetPointer() << std::endl; + os << indent << "MultiplyFilter: " << m_MultiplyFilter.GetPointer() << std::endl; + os << indent << "AddFilter: " << m_AddFilter.GetPointer() << std::endl; + os << indent << "Sigma: " << GetSigma() << std::endl; + os << indent << "ScalingConstant: " << GetScalingConstant() << std::endl; + os << indent << "ReleaseInternalFilterData: " << GetReleaseInternalFilterData() << std::endl; +} + +} // namespace itk + +#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 4c7a0767edd..b62e01639f5 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -10,6 +10,7 @@ set( itkKrcahEigenToScalarFunctorTest.cxx itkKrcahEigenToScalarFunctorImageFilterTest.cxx itkKrcahEigenToScalarImageFilterTest.cxx + itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -74,3 +75,10 @@ itk_add_test( BoneEnhancementTestDriver itkKrcahEigenToScalarImageFilterTest ) + +itk_add_test( + NAME itkKrcahEigenToScalarPreprocessingImageToImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkKrcahEigenToScalarPreprocessingImageToImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx new file mode 100644 index 00000000000..70e75c2cf74 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx @@ -0,0 +1,43 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" +#include "itkTestingMacros.h" + +int +itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) +{ + const unsigned int Dimension = 3; + typedef char InputPixelType; + typedef itk::Image InputImageType; + + typedef itk::KrcahEigenToScalarPreprocessingImageToImageFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + + /* Basic test */ + EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); + + /* Default parameters */ + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetScalingConstant(), 10.0, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetSigma(), 1.0, 6, 0.000001)); + TEST_EXPECT_TRUE(filter->GetReleaseInternalFilterData()); + + /* TODO: Regression test */ + + return EXIT_SUCCESS; +} From dae7f7c25c3ecfa117ded83e920cf39f98db0bb6 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 00:37:56 -0700 Subject: [PATCH 026/150] BUG: Fixed implementation parameters to be correct --- ...entoScalarParameterEstimationImageFilter.h | 6 ++--- ...toScalarParameterEstimationImageFilter.hxx | 6 ++--- .../itkKrcahEigenToScalarImageFilterTest.cxx | 9 +++---- ...alarParameterEstimationImageFilterTest.cxx | 27 ++++++++++++------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h index ba318046982..8468a22ff87 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h @@ -56,9 +56,9 @@ namespace itk * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType * can be set which enables the implementation parameters: * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.5 \cdot T + * \alpha &=& \sqrt{2} \cdot 0.5 \\ + * \beta &=& \sqrt{2} \cdot 0.5 \\ + * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T * \f} * Default is to use parameters from the implementation, not the paper. * diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx index abd31dcf150..d9f3bbe9cea 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx @@ -102,9 +102,9 @@ KrcahEigenToScalarParameterEstimationImageFilter::After switch (m_ParameterSet) { case UseImplementationParameters: - alpha = 0.5f; - beta = 0.5f; - gamma = 0.5f; + alpha = Math::sqrt2 * 0.5f; + beta = Math::sqrt2 * 0.5f; + gamma = Math::sqrt2 * 0.5f; break; case UseJournalParameters: alpha = 0.5f; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx index ebd40560e29..0e9f9cf6c97 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx @@ -78,17 +78,16 @@ itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), 3 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); itk::ImageRegionIteratorWithIndex it(krcahFilter->GetOutput(), region); it.GoToBegin(); while (!it.IsAtEnd()) { - // TODO: Why is this not 0.000335462627903 as before? - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.000329318, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.0158368867121, 6, 0.000001)); ++it; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index 60dd154d93e..80bdc0b66b5 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -126,9 +126,12 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) krcahParameterEstimator->SetInput(image); krcahParameterEstimator->SetParameterSetToImplementation(); TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); @@ -142,16 +145,22 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) krcahParameterEstimator->SetMaskImage(mask); krcahParameterEstimator->SetBackgroundValue(backgroundValue); TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 3 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToImplementation(); krcahParameterEstimator->SetBackgroundValue(foregroundValue); TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 1 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); krcahParameterEstimator->SetInput(image2); From 48b9e5cf222ebfee6cadccf38306fd011f55047d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 00:46:21 -0700 Subject: [PATCH 027/150] DOC: Enhanced documentation for Krcah methods and MaximumAbsoluteValueImageFilter --- .../itkKrcahEigenToScalarFunctorImageFilter.h | 4 +++- .../include/itkKrcahEigenToScalarImageFilter.h | 17 ++++++++++++----- ...enToScalarPreprocessingImageToImageFilter.h | 18 +++++++++++++++++- ...gentoScalarParameterEstimationImageFilter.h | 2 +- .../itkMaximumAbsoluteValueImageFilter.h | 7 +++++-- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index e21f1029c46..bf71951c707 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -155,7 +155,9 @@ class KrcahEigenToScalarFunctor * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. * * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter + * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. + * + * See functor for mathematics. * * \sa KrcahEigenToScalarFunctor * \sa KrcahEigenToScalarImageFilter diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index ea691fc12f6..5bfab320b34 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -26,15 +26,22 @@ namespace itk { /** \class KrcahEigenToScalarImageFilter - * \brief Abstract class for converting eigenvalue image to scalar image. + * \brief Compute the Krcah sheetness measure from the eigenvalues * - * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. - * Other classes should inherit from this class so they can be used in the BoneEnhancement framework. This abstract - * class guarantees that the variable EigenValueOrder has a valid type and enforces some concept checking - * on the class template parameters: TInputImage and TOutputImage . TODO + * This is a convenience class implementing the EigenToScalarImageFilter + * abstract class. This class computes the Krcah sheetness measure for + * cortical bone. Internally, KrcahEigenToScalarParameterEstimationImageFilter + * and KrcahEigenToScalarFunctorImageFilter are used for automatic parameter + * estimation and implementation of the functor. + * + * Before passing an input to MultiScaleHessianEnhancementImageFilter, + * the KrcahEigenToScalarPreprocessingImageToImageFilter should be used. * * \sa MultiScaleHessianEnhancementImageFilter * \sa EigenToScalarImageFilter + * \sa KrcahEigenToScalarParameterEstimationImageFilter + * \sa KrcahEigenToScalarFunctorImageFilter + * \sa KrcahEigenToScalarPreprocessingImageToImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index 8984f898900..f83cb25fbca 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -28,7 +28,23 @@ namespace itk { /** \class KrcahEigenToScalarPreprocessingImageToImageFilter - * \brief TODO + * \brief Perform preprocessing as defined by Krcah et al + * + * This filters performs an unsharp filter as defined by Krcah + * et al. The unsharp filter is defined by: + * \f{ + * J = I+k*(I-(I*G)) + * \f} + * + * Where \f$ k \f$ is a scaling constant set to 5 and the Guassian + * filter has smoothing parameter \f$ s = 1 mm \f$. A user can modify + * these defaults using the appropriate setter methods. + * + * Additionally, this filter provides the ReleaseInternalFilterData + * flag. When this flag is set, the internal filters used to compute + * the unsharp filter will release their data after processing. This + * conserves memory at the expense of computation time if ScalingConstant + * or Sigma are changed. This flag is on by default. * * \sa KrcahEigenToScalarImageFilter * diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h index 8468a22ff87..34dcf2f759d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h @@ -27,7 +27,7 @@ namespace itk { /** \class KrcahEigenToScalarParameterEstimationImageFilter - * \brief Abstract class for converting eigenvalue image to scalar image. + * \brief Automatic parameter estimation for the Krcah method * * This class takes an image of eigenvalues and estimates the parameters for the Krcah * bone enhanced filter. According to the original paper, diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 84c82ae00e6..500745d39f1 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -35,7 +35,7 @@ class MaximumAbsoluteValue ~MaximumAbsoluteValue() {} #ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking TODO + // Begin concept checking itkConceptMacro(Input1ConvertableToOutputCheck, (Concept::Convertible)); itkConceptMacro(Input2ConvertableToOutputCheck, (Concept::Convertible)); itkConceptMacro(Input1GreaterThanInput2Check, (Concept::GreaterThanComparable)); @@ -53,7 +53,10 @@ class MaximumAbsoluteValue /** \class MaximumAbsoluteValueImageFilter * \brief Compute the maximum (of the absolute value) between two images. * - * This class takes two images as arguments and takes + * This class takes two images as arguments and returns the maximum + * of the absolute value pixel wise. For instance, two pixels with + * values 2 and -3 would return -3, since the absolute value of -3 + * is larger than 2. * * \sa MultiScaleHessianEnhancementImageFilter * From 014b1e17deea47bfd3ba107ddddd7b05429c9a9f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 00:57:42 -0700 Subject: [PATCH 028/150] BUG: Fixed bug with the progress accumulator for MultiScaleHessianEnhancementImageFilter --- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 2 +- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 46ee96f49d5..fb099df7efa 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -152,7 +152,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image GenerateData() ITK_OVERRIDE; /** Internal function to generate the response at a scale */ - typename TOutputImage::Pointer + inline typename TOutputImage::Pointer generateResponseAtScale(SigmaStepsType scaleLevel); /** Internal function to convert types for EigenValueOrder */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 80be2497fbb..b7efd929ff6 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -87,9 +87,9 @@ MultiScaleHessianEnhancementImageFilter::GenerateData float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); - progress->RegisterInternalFilter(m_HessianFilter, perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenAnalysisFilter, perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenToScalarImageFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_HessianFilter, 3 * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenAnalysisFilter, 3 * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToScalarImageFilter, 3 * perFilterProccessPercentage); /* Check if we need to run the MaximumAbsoluteValueFilter at all */ if (m_SigmaArray.GetSize() > 1) From c52e27dd2b7e3442e98438ec207a1ea274b43a79 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 01:10:15 -0700 Subject: [PATCH 029/150] BUG: Fixed bug where file names appear correct on local machine but incorrect when pushed remote --- ...er.h => itkKrcahEigenToScalarParameterEstimationImageFilter.h} | 0 ...xx => itkKrcahEigenToScalarParameterEstimationImageFilter.hxx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Modules/Filtering/BoneEnhancement/include/{itkKrcahEigentoScalarParameterEstimationImageFilter.h => itkKrcahEigenToScalarParameterEstimationImageFilter.h} (100%) rename Modules/Filtering/BoneEnhancement/include/{itkKrcahEigentoScalarParameterEstimationImageFilter.hxx => itkKrcahEigenToScalarParameterEstimationImageFilter.hxx} (100%) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h similarity index 100% rename from Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.h rename to Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx similarity index 100% rename from Modules/Filtering/BoneEnhancement/include/itkKrcahEigentoScalarParameterEstimationImageFilter.hxx rename to Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx From 4932a045e5d5c69d5a771958059ce2e9b7fc874f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 01:27:51 -0700 Subject: [PATCH 030/150] BUG: Fixed unit test for test/itkKrcahEigenToScalarParameterEstimationImageFil terTest.cxx --- .../itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index 80bdc0b66b5..ed6c6ba8d4e 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -169,7 +169,7 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 3 * 0.25, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.25, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); krcahParameterEstimator->SetBackgroundValue(foregroundValue); From 8beb53198bc6738a31b6dbd972f081fb4b57d70d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 28 Nov 2017 22:55:42 -0700 Subject: [PATCH 031/150] BUG: Fixed EnlargeOutputRequestedRegion for MultiScaleHessianEnhancementImageFilter and KrcahEigenToScalarImageFilter --- .../itkKrcahEigenToScalarImageFilter.h | 8 ++++++++ .../itkKrcahEigenToScalarImageFilter.hxx | 20 +++++++++++++++++++ ...kMultiScaleHessianEnhancementImageFilter.h | 8 ++++++++ ...ultiScaleHessianEnhancementImageFilter.hxx | 20 +++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index 5bfab320b34..fa65ddbacae 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -170,6 +170,14 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm KrcahEigenToScalarImageFilter(); virtual ~KrcahEigenToScalarImageFilter() {} + /** Override since the filter needs all the data for the algorithm */ + void + GenerateInputRequestedRegion() ITK_OVERRIDE; + + /** Override since the filter produces all of its output */ + void + EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + /** Single threaded since we are connecting data */ void GenerateData() ITK_OVERRIDE; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx index e1fe9a63818..c08c09dc77c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx @@ -34,6 +34,26 @@ KrcahEigenToScalarImageFilter::KrcahEigen this->SetNumberOfRequiredInputs(1); } +template +void +KrcahEigenToScalarImageFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) + { + typename TInputImage::Pointer image = const_cast(this->GetInput()); + image->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +KrcahEigenToScalarImageFilter::EnlargeOutputRequestedRegion(DataObject * data) +{ + Superclass::EnlargeOutputRequestedRegion(data); + data->SetRequestedRegionToLargestPossibleRegion(); +} + template void KrcahEigenToScalarImageFilter::GenerateData() diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index fb099df7efa..59f6485a709 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -159,6 +159,14 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image InternalEigenValueOrderType ConvertType(ExternalEigenValueOrderType order); + /** Override since the filter needs all the data for the algorithm */ + void + GenerateInputRequestedRegion() ITK_OVERRIDE; + + /** Override since the filter produces all of its output */ + void + EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index b7efd929ff6..97a61aead84 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -41,6 +41,26 @@ MultiScaleHessianEnhancementImageFilter::MultiScaleHe this->SetNumberOfRequiredInputs(1); } +template +void +MultiScaleHessianEnhancementImageFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) + { + typename TInputImage::Pointer image = const_cast(this->GetInput()); + image->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +MultiScaleHessianEnhancementImageFilter::EnlargeOutputRequestedRegion(DataObject * data) +{ + Superclass::EnlargeOutputRequestedRegion(data); + data->SetRequestedRegionToLargestPossibleRegion(); +} + template void MultiScaleHessianEnhancementImageFilter::GenerateData() From ca2e24a22dc1df3faee4d4d93ca838a2eb28d917 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 29 Nov 2017 13:19:15 -0700 Subject: [PATCH 032/150] STYLE: Fixed naming from Forbenius norm to average trace of Krcah parameter estimation --- ...enToScalarParameterEstimationImageFilter.h | 6 +-- ...ToScalarParameterEstimationImageFilter.hxx | 44 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index 34dcf2f759d..e166614cd32 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -208,9 +208,9 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter /** Calculation of \f$ T \f$ changes depending on the implementation */ inline RealType - CalculateNormAccordingToImplementation(InputPixelType pixel); + CalculateTraceAccordingToImplementation(InputPixelType pixel); inline RealType - CalculateNormAccordingToJournalArticle(InputPixelType pixel); + CalculateTraceAccordingToJournalArticle(InputPixelType pixel); private: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); @@ -222,7 +222,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter MaskPixelType m_BackgroundValue; /* Arrays for threads */ - Array m_AccumulatedFrobeniusNorm; + Array m_AccumulatedAverageTrace; Array m_NumVoxels; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index d9f3bbe9cea..1f05d308682 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -32,7 +32,7 @@ KrcahEigenToScalarParameterEstimationImageFilter::Zero) , m_NumVoxels(1) - , m_AccumulatedFrobeniusNorm(1) + , m_AccumulatedAverageTrace(1) { /* We require an input, optional mask */ this->SetNumberOfRequiredInputs(1); @@ -84,10 +84,10 @@ KrcahEigenToScalarParameterEstimationImageFilter::Befor ThreadIdType numberOfThreads = this->GetNumberOfThreads(); /* Resize threads */ - m_AccumulatedFrobeniusNorm.SetSize(numberOfThreads); + m_AccumulatedAverageTrace.SetSize(numberOfThreads); m_NumVoxels.SetSize(numberOfThreads); - m_AccumulatedFrobeniusNorm.Fill(NumericTraits::ZeroValue()); + m_AccumulatedAverageTrace.Fill(NumericTraits::ZeroValue()); m_NumVoxels.Fill(NumericTraits::ZeroValue()); } @@ -118,19 +118,19 @@ KrcahEigenToScalarParameterEstimationImageFilter::After /* Accumulate over threads */ SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedFrobeniusNorm = NumericTraits::ZeroValue(); + RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); for (unsigned int i = 0; i < numberOfThreads; ++i) { numVoxels += m_NumVoxels[i]; - accumulatedFrobeniusNorm += m_AccumulatedFrobeniusNorm[i]; + accumulatedAverageTrace += m_AccumulatedAverageTrace[i]; } /* Do derived measure */ if (numVoxels > 0) { - RealType averageFrobeniusNorm = (RealType)accumulatedFrobeniusNorm / (RealType)numVoxels; - gamma = gamma * averageFrobeniusNorm; + RealType averageTrace = (RealType)accumulatedAverageTrace / (RealType)numVoxels; + gamma = gamma * averageTrace; } /* Assign outputs parameters */ @@ -152,14 +152,14 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa } /* Determine which function to call */ - RealType (Self::*normFunction)(InputPixelType); + RealType (Self::*traceFunction)(InputPixelType); switch (m_ParameterSet) { case UseImplementationParameters: - normFunction = &Self::CalculateNormAccordingToImplementation; + traceFunction = &Self::CalculateTraceAccordingToImplementation; break; case UseJournalParameters: - normFunction = &Self::CalculateNormAccordingToJournalArticle; + traceFunction = &Self::CalculateTraceAccordingToJournalArticle; break; default: itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); @@ -168,7 +168,7 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa /* Count starts zero */ SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedFrobeniusNorm = NumericTraits::ZeroValue(); + RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); /* Get input pointer */ InputImagePointer inputPointer = const_cast(this->GetInput()); @@ -191,44 +191,44 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa { numVoxels++; - /* Compute norm */ - accumulatedFrobeniusNorm += (this->*normFunction)(inputIt.Get()); + /* Compute trace */ + accumulatedAverageTrace += (this->*traceFunction)(inputIt.Get()); } ++inputIt; progress.CompletedPixel(); } /* Store this thread */ - m_AccumulatedFrobeniusNorm[threadId] = accumulatedFrobeniusNorm; + m_AccumulatedAverageTrace[threadId] = accumulatedAverageTrace; m_NumVoxels[threadId] = numVoxels; } template typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateNormAccordingToImplementation( +KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToImplementation( InputPixelType pixel) { /* Sum of the absolute value of the eigenvalues */ - RealType norm = 0; + RealType trace = 0; for (unsigned int i = 0; i < pixel.Length; ++i) { - norm += Math::abs(pixel[i]); + trace += Math::abs(pixel[i]); } - return norm; + return trace; } template typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateNormAccordingToJournalArticle( +KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToJournalArticle( InputPixelType pixel) { /* Sum of the eigenvalues */ - RealType norm = 0; + RealType trace = 0; for (unsigned int i = 0; i < pixel.Length; ++i) { - norm += pixel[i]; + trace += pixel[i]; } - return norm; + return trace; } template From 3ef47609543282c668edfc3c8ec7c1f444cbe22d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 6 Dec 2017 15:50:15 -0700 Subject: [PATCH 033/150] ENH: Completed Descoteaux parameter estimation --- ...enToScalarParameterEstimationImageFilter.h | 185 +++++++++++++ ...ToScalarParameterEstimationImageFilter.hxx | 248 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + ...alarParameterEstimationImageFilterTest.cxx | 157 +++++++++++ 4 files changed, 598 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h new file mode 100644 index 00000000000..f704b9cff11 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h @@ -0,0 +1,185 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_h +#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkNumericTraits.h" +#include "itkSimpleDataObjectDecorator.h" +#include "itkArray.h" + +namespace itk +{ +/** \class DescoteauxEigenToScalarParameterEstimationImageFilter + * \brief Automatic parameter estimation for the Krcah method + * + * The default parameters are: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 max\( Frobenius norm \) + * \f} + * + * Where the Frobenius norm for a real, symmetric matrix is given by + * the square root of the sum of squares of the eigenvalues. + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter + : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToScalarParameterEstimationImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); + + /** Image related typedefs. */ + typedef typename TInputImage::Pointer InputImagePointer; + typedef typename TInputImage::ConstPointer InputImageConstPointer; + typedef typename TInputImage::RegionType InputRegionType; + typedef typename TInputImage::SizeType InputSizeType; + typedef typename TInputImage::IndexType InputIndexType; + typedef typename TInputImage::PixelType InputPixelType; + typedef typename InputPixelType::ValueType InputPixelValueType; + + /** Output region definitions */ + typedef InputRegionType OutputRegionType; + + /** Mask related typedefs. */ + typedef typename TMaskImage::Pointer MaskImagePointer; + typedef typename TMaskImage::ConstPointer MaskImageConstPointer; + typedef typename TMaskImage::PixelType MaskPixelType; + typedef typename TMaskImage::RegionType MaskRegionType; + + /** Parameters */ + typedef typename NumericTraits::RealType RealType; + typedef SimpleDataObjectDecorator RealTypeDecoratedType; + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskImage, TMaskImage); + itkGetInputMacro(MaskImage, TMaskImage); + + /** Setter/getter for background pixel value */ + itkSetMacro(BackgroundValue, MaskPixelType); + itkGetConstMacro(BackgroundValue, MaskPixelType); + + /** Method setter/getter for Frobenius Norm Weight */ + itkSetMacro(FrobeniusNormWeight, RealType); + itkGetConstMacro(FrobeniusNormWeight, RealType); + + /** Decorators for parameters so they can be passed as a process object */ + RealTypeDecoratedType * + GetAlphaOutput(); + const RealTypeDecoratedType * + GetAlphaOutput() const; + RealTypeDecoratedType * + GetBetaOutput(); + const RealTypeDecoratedType * + GetBetaOutput() const; + RealTypeDecoratedType * + GetCOutput(); + const RealTypeDecoratedType * + GetCOutput() const; + + /** Standard getters for the output parameters */ + RealType + GetAlpha() const + { + return this->GetAlphaOutput()->Get(); + } + RealType + GetBeta() const + { + return this->GetBetaOutput()->Get(); + } + RealType + GetC() const + { + return this->GetCOutput()->Get(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + DescoteauxEigenToScalarParameterEstimationImageFilter(); + virtual ~DescoteauxEigenToScalarParameterEstimationImageFilter() {} + + /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ + void + AllocateOutputs() ITK_OVERRIDE; + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + /** Override since the filter needs all the data for the algorithm */ + void + GenerateInputRequestedRegion() ITK_OVERRIDE; + + /** Override since the filter produces all of its output */ + void + EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + + /** Compute Frobenius norm from a fixed array of eigenvalues */ + inline RealType + CalculateFrobeniusNorm(InputPixelType pixel); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); + + /* Parameters */ + RealType m_FrobeniusNormWeight; + MaskPixelType m_BackgroundValue; + + /* Arrays for threads */ + Array m_MaxFrobeniusNorm; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx" +#endif + +#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx new file mode 100644 index 00000000000..3a1212d7783 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx @@ -0,0 +1,248 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx +#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx + +#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkProgressReporter.h" +#include "itkMath.h" + +namespace itk +{ +template +DescoteauxEigenToScalarParameterEstimationImageFilter:: + DescoteauxEigenToScalarParameterEstimationImageFilter() + : m_FrobeniusNormWeight(0.5f) + , m_BackgroundValue(NumericTraits::Zero) + , m_MaxFrobeniusNorm(1) +{ + /* We require an input, optional mask */ + this->SetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(4); + + /* Allocate all decorators */ + for (int i = 1; i < 4; ++i) + { + typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); + output->Set(0.5); + this->ProcessObject::SetNthOutput(i, output.GetPointer()); + } +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::AllocateOutputs() +{ + /* Pass the input through as the output */ + InputImagePointer image = const_cast(this->GetInput()); + this->GraftOutput(image); +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) + { + InputImagePointer image = const_cast(this->GetInput()); + image->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( + DataObject * data) +{ + Superclass::EnlargeOutputRequestedRegion(data); + data->SetRequestedRegionToLargestPossibleRegion(); +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() +{ + ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + /* Resize threads */ + m_MaxFrobeniusNorm.SetSize(numberOfThreads); + m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() +{ + ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + + /* Determine default parameters */ + RealType alpha, beta, c; + alpha = 0.5f; + beta = 0.5f; + c = m_FrobeniusNormWeight; + + /* Accumulate over threads */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + + for (unsigned int i = 0; i < numberOfThreads; ++i) + { + if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) + { + maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; + } + } + + /* Scale c */ + if (maxFrobeniusNorm > 0) + { + c = c * maxFrobeniusNorm; + } + + /* Assign outputs parameters */ + this->GetAlphaOutput()->Set(alpha); + this->GetBetaOutput()->Set(beta); + this->GetCOutput()->Set(c); +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( + const OutputRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Count starts zero */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + RealType thisFrobeniusNorm; + + /* Get input pointer */ + InputImagePointer inputPointer = const_cast(this->GetInput()); + + /* Get mask pointer */ + MaskImagePointer maskPointer = TMaskImage::New(); + maskPointer = const_cast(this->GetMaskImage()); + + /* Setup progress reporter */ + ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) + { + /* Compute max norm */ + thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); + if (thisFrobeniusNorm > maxFrobeniusNorm) + { + maxFrobeniusNorm = thisFrobeniusNorm; + } + } + ++inputIt; + progress.CompletedPixel(); + } + + /* Store this thread */ + m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; +} + +template +typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealType +DescoteauxEigenToScalarParameterEstimationImageFilter::CalculateFrobeniusNorm( + InputPixelType pixel) +{ + /* Forbenius norm is given by the square root of the sum of squares + * of the eigenvalues for real, symmetric matricies + */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i] * pixel[i]; + } + return sqrt(norm); +} + +template +typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() +{ + return static_cast(this->ProcessObject::GetOutput(2)); +} + +template +const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(2)); +} + +template +typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() +{ + return static_cast(this->ProcessObject::GetOutput(3)); +} + +template +const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * +DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(3)); +} + +template +void +DescoteauxEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "Alpha: " << this->GetAlpha() << std::endl; + os << indent << "Beta: " << this->GetBeta() << std::endl; + os << indent << "C: " << this->GetC() << std::endl; + os << indent << "BackgroundValue: " << GetBackgroundValue() << std::endl; + os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; +} + +} // namespace itk + +#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index b62e01639f5..f69fc0184d2 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -11,6 +11,7 @@ set( itkKrcahEigenToScalarFunctorImageFilterTest.cxx itkKrcahEigenToScalarImageFilterTest.cxx itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx + itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -82,3 +83,10 @@ itk_add_test( BoneEnhancementTestDriver itkKrcahEigenToScalarPreprocessingImageToImageFilterTest ) + +itk_add_test( + NAME itkDescoteauxEigenToScalarParameterEstimationImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkDescoteauxEigenToScalarParameterEstimationImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx new file mode 100644 index 00000000000..c17e3570f77 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx @@ -0,0 +1,157 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" +#include "itkTestingMacros.h" +#include "itkMath.h" +#include "itkImageRegionIteratorWithIndex.h" + +int +itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) +{ + const unsigned int Dimension = 3; + typedef unsigned int MaskPixelType; + typedef itk::Image MaskType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::DescoteauxEigenToScalarParameterEstimationImageFilter + DescoteauxEigenToScalarParameterEstimationImageFilterType; + + DescoteauxEigenToScalarParameterEstimationImageFilterType::Pointer descoteauxParameterEstimator = + DescoteauxEigenToScalarParameterEstimationImageFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS( + descoteauxParameterEstimator, DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); + + /* Test defaults */ + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetCOutput()->Get(), 0.5, 6, 0.000001)); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, -1); + } + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + image2->SetRegions(region); + image2->Allocate(); + image2->FillBuffer(simpleEigenPixel); + + EigenValueImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + EigenValueImageType::SizeType maskSize; + maskSize[0] = 8; + maskSize[1] = 8; + maskSize[2] = 8; + + MaskPixelType backgroundValue = 1; + MaskPixelType foregroundValue = 2; + MaskType::Pointer mask = MaskType::New(); + mask->SetRegions(region); + mask->Allocate(); + mask->FillBuffer(backgroundValue); + + EigenValueArrayType newEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + newEigenPixel.SetElement(i, 3); + } + + EigenValueImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + itk::ImageRegionIteratorWithIndex input2It(image2, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(mask, maskRegion); + + input2It.GoToBegin(); + maskIt.GoToBegin(); + while (!input2It.IsAtEnd()) + { + input2It.Set(newEigenPixel); + maskIt.Set(foregroundValue); + ++input2It; + ++maskIt; + } + + /* Test an empty pixel value */ + descoteauxParameterEstimator->SetInput(image); + TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + + /* Test an empty pixel value */ + descoteauxParameterEstimator->SetFrobeniusNormWeight(0.25); + TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.25, 6, 0.000001)); + + /* Test with a mask */ + descoteauxParameterEstimator->SetInput(image2); + descoteauxParameterEstimator->SetMaskImage(mask); + descoteauxParameterEstimator->SetBackgroundValue(foregroundValue); + descoteauxParameterEstimator->SetFrobeniusNormWeight(0.5); + TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + + descoteauxParameterEstimator->SetInput(image2); + descoteauxParameterEstimator->SetMaskImage(mask); + descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); + + return EXIT_SUCCESS; +} From 14eae81a0db461f687d2cf71cbc38d26555c1ab7 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 6 Dec 2017 16:07:16 -0700 Subject: [PATCH 034/150] ENH: Implemented DescoteauxEigenToScalarFunctorImageFilter --- ...escoteauxEigenToScalarFunctorImageFilter.h | 260 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 16 ++ ...escoteauxEigenToScalarFunctorImageTest.cxx | 121 ++++++++ .../itkDescoteauxEigenToScalarFunctorTest.cxx | 121 ++++++++ 4 files changed, 518 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h new file mode 100644 index 00000000000..d3eae432a61 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -0,0 +1,260 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToScalarFunctorImageFilter_h +#define itkDescoteauxEigenToScalarFunctorImageFilter_h + +#include "itkUnaryFunctorImageFilter.h" +#include "itkNumericTraits.h" +#include "itkMath.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace itk +{ +namespace Functor +{ +/** \class DescoteauxEigenToScalarFunctor + * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. + * + * Computes the following equation for eigenvalues in a three + * dimensional fixed array: + * \f{eqnarray*}{ + * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ + * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ + * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ + * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) + * \f} + * + * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. + * + * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter + * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. + * + * \sa DescoteauxEigentoScalarParameterEstimationImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToScalarFunctor +{ +public: + /* Basic type definitions */ + typedef typename NumericTraits::RealType RealType; + + DescoteauxEigenToScalarFunctor() + : m_Direction(-1.0) + {} + + inline TOutputPixel + operator()(const TInputPixel & A) + { + double sheetness = 0.0; + double a1 = static_cast(A[0]); + double a2 = static_cast(A[1]); + double a3 = static_cast(A[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Deal with l3 > 0 */ + if (m_Direction * a3 < 0) + { + return static_cast(0.0); + } + + /* Avoid divisions by zero (or close to zero) */ + if (l3 < Math::eps) + { + return static_cast(0.0); + } + + /* Compute measures */ + const double Rsheet = l2 / l3; + const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; + const double Rnoise = Math::sqr(l1 * l1 + l2 * l2 + l3 * l3); + + /* Multiply together to get sheetness */ + sheetness = 1.0; + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); + sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); + + return static_cast(sheetness); + } + + /** Macro definition for set/get of parameters */ + virtual void + SetAlpha(const RealType alpha) + { + this->m_Alpha = alpha; + } + virtual void + SetBeta(const RealType beta) + { + this->m_Beta = beta; + } + virtual void + SetC(const RealType c) + { + this->m_C = c; + } + RealType + GetAlpha() const + { + return this->m_Alpha; + } + RealType + GetBeta() const + { + return this->m_Beta; + } + RealType + GetC() const + { + return this->m_C; + } + + /** Set/get the type to enhance */ + void + SetEnhanceBrightObjects() + { + m_Direction = -1.0; + } + void + SetEnhanceDarkObjects() + { + m_Direction = 1.0; + } + + RealType + GetEnhanceType() const + { + return m_Direction; + } + +private: + /* Private member variables */ + RealType m_Alpha; + RealType m_Beta; + RealType m_C; + RealType m_Direction; +}; // end class +} // namespace Functor + +/** \class DescoteauxEigenToScalarFunctorImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. + * + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Descoteaux et al. The parameters of the filter should be set using + * DescoteauxEigentoScalarParameterEstimationImageFilter. + * + * See functor DescoteauxEigenToScalarFunctor for mathematics. + * + * \sa DescoteauxEigenToScalarFunctor + * \sa DescoteauxEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToScalarFunctorImageFilter + : public UnaryFunctorImageFilter< + TInputImage, + TOutputImage, + Functor::DescoteauxEigenToScalarFunctor> +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToScalarFunctorImageFilter Self; + typedef UnaryFunctorImageFilter< + TInputImage, + TOutputImage, + Functor::DescoteauxEigenToScalarFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Useful typedefs for numerics */ + typedef + typename Functor::DescoteauxEigenToScalarFunctor + DescoteauxFunctorType; + typedef typename DescoteauxFunctorType::RealType RealType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + + /** Define decorator types */ + typedef SimpleDataObjectDecorator InputParameterDecoratorType; + + /** Process object */ + itkSetGetDecoratedInputMacro(Alpha, RealType); + itkSetGetDecoratedInputMacro(Beta, RealType); + itkSetGetDecoratedInputMacro(C, RealType); + + /** Need to access the input parameters at execution time */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE + { + /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ + this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); + this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); + this->GetFunctor().SetC(this->GetCInput()->Get()); + } + + /** setter/getter methods for setting type of object to enhance */ + void + SetEnhanceBrightObjects() + { + this->GetFunctor().SetEnhanceBrightObjects(); + } + void + SetEnhanceDarkObjects() + { + this->GetFunctor().SetEnhanceDarkObjects(); + } + RealType + GetEnhanceType() const + { + return this->GetFunctor().GetEnhanceType(); + } + +protected: + DescoteauxEigenToScalarFunctorImageFilter() {} + virtual ~DescoteauxEigenToScalarFunctorImageFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); + + void + PrintSelf(std::ostream & os, Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << indent << "Alpha: " << GetAlpha() << std::endl; + os << indent << "Beta: " << GetBeta() << std::endl; + os << indent << "C: " << GetC() << std::endl; + os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; + } +}; // end class +} // namespace itk + +#endif // itkDescoteauxEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index f69fc0184d2..db72012e23c 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -12,6 +12,8 @@ set( itkKrcahEigenToScalarImageFilterTest.cxx itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx + itkDescoteauxEigenToScalarFunctorTest.cxx + itkDescoteauxEigenToScalarFunctorImageTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -90,3 +92,17 @@ itk_add_test( BoneEnhancementTestDriver itkDescoteauxEigenToScalarParameterEstimationImageFilterTest ) + +itk_add_test( + NAME itkDescoteauxEigenToScalarFunctorTest + COMMAND + BoneEnhancementTestDriver + itkDescoteauxEigenToScalarFunctorTest +) + +itk_add_test( + NAME itkDescoteauxEigenToScalarFunctorImageTest + COMMAND + BoneEnhancementTestDriver + itkDescoteauxEigenToScalarFunctorImageTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx new file mode 100644 index 00000000000..a19558ef20e --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx @@ -0,0 +1,121 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" +#include "itkUnaryFunctorImageFilter.h" +#include "itkTestingMacros.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkMath.h" + +int +itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) +{ + /* typedefs, instantiate filter */ + const unsigned int Dimension = 3; + typedef double ImagePixelType; + typedef itk::Image ImageType; + + typedef double EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::DescoteauxEigenToScalarFunctorImageFilter FilterType; + FilterType::Pointer descoFilter = FilterType::New(); + + /* Basic tests. Need to set parameters first. */ + descoFilter->SetAlpha(0.5); + descoFilter->SetBeta(0.5); + descoFilter->SetC(0.25); + EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + + /* Exercise basic set/get methods */ + descoFilter->SetAlpha(0.5); + TEST_SET_GET_VALUE(0.5, descoFilter->GetAlpha()); + descoFilter->SetBeta(0.5); + TEST_SET_GET_VALUE(0.5, descoFilter->GetBeta()); + descoFilter->SetC(0.25); + TEST_SET_GET_VALUE(0.25, descoFilter->GetC()); + // Default should be 1 + TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); + descoFilter->SetEnhanceDarkObjects(); + TEST_SET_GET_VALUE(1.0, descoFilter->GetEnhanceType()); + descoFilter->SetEnhanceBrightObjects(); + TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + for (unsigned int i = 0; i < Dimension; ++i) + { + simpleEigenPixel.SetElement(i, 0); + } + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + descoFilter->SetInput(image); + TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + + itk::ImageRegionIteratorWithIndex input(descoFilter->GetOutput(), region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); + ++input; + } + + /* Create some test data which is computable */ + simpleEigenPixel.SetElement(0, 0.25); + simpleEigenPixel.SetElement(1, 1); + simpleEigenPixel.SetElement(2, -1); + + EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + image2->SetRegions(region); + image2->Allocate(); + image2->FillBuffer(simpleEigenPixel); + + descoFilter->SetInput(image2); + TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + + itk::ImageRegionIteratorWithIndex input2(descoFilter->GetOutput(), region); + + input2.GoToBegin(); + while (!input2.IsAtEnd()) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.0913983433747, 6, 0.000001)); + ++input2; + } + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx new file mode 100644 index 00000000000..5f8655d174c --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx @@ -0,0 +1,121 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" +#include "itkTestingMacros.h" + +int +itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) +{ + /* typedefs, instantiate functor */ + const unsigned int Dimension = 3; + typedef double ImagePixelType; + typedef itk::Image ImageType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::Functor::DescoteauxEigenToScalarFunctor FunctorType; + FunctorType functor = FunctorType(); + + /* Exercise basic set/get methods */ + functor.SetAlpha(0.25); + TEST_SET_GET_VALUE(0.25, functor.GetAlpha()); + functor.SetBeta(0.25); + TEST_SET_GET_VALUE(0.25, functor.GetBeta()); + functor.SetC(0.25); + TEST_SET_GET_VALUE(0.25, functor.GetC()); + // Default should be -1 + TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + functor.SetEnhanceDarkObjects(); + TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); + functor.SetEnhanceBrightObjects(); + TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + + /* Test a few calculations */ + EigenValueArrayType mEigenValueArray; + functor.SetAlpha(0.5); + functor.SetBeta(0.5); + functor.SetC(0.25); + functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = 0; + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* Return zero on positive l3 with bright sheets */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = 1; + functor.SetEnhanceBrightObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* Return zero on positive l3 with dark sheets */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = -1; + functor.SetEnhanceDarkObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* 0, 0, -1; bright sheets */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = -1; + functor.SetEnhanceBrightObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); + + /* 0, 0, 1; dark sheets */ + mEigenValueArray[0] = 0; + mEigenValueArray[1] = 0; + mEigenValueArray[2] = 1; + functor.SetEnhanceDarkObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); + + /* 1, 1, -1; bright sheets */ + mEigenValueArray[0] = 1; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = -1; + functor.SetEnhanceBrightObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* 1, 1, 1; dark sheets */ + mEigenValueArray[0] = 1; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + functor.SetEnhanceDarkObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + + /* 0.25, 1, -1; bright sheets */ + mEigenValueArray[0] = 0.25; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = -1; + functor.SetEnhanceBrightObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); + + /* 0.25, 1, 1; dark sheets */ + mEigenValueArray[0] = 0.25; + mEigenValueArray[1] = 1; + mEigenValueArray[2] = 1; + functor.SetEnhanceDarkObjects(); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); + + return EXIT_SUCCESS; +} From 713c531c4d1d773ab56e8919dff49af08c6ae13d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 6 Dec 2017 16:57:16 -0700 Subject: [PATCH 035/150] BUG: Replaced Math::sqr with sqrt --- .../include/itkDescoteauxEigenToScalarFunctorImageFilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index d3eae432a61..cbfa81ce46b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -88,7 +88,7 @@ class DescoteauxEigenToScalarFunctor /* Compute measures */ const double Rsheet = l2 / l3; const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = Math::sqr(l1 * l1 + l2 * l2 + l3 * l3); + const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); /* Multiply together to get sheetness */ sheetness = 1.0; From 21d88a2c28d9869ba7bb25c5064ff9e171abf25e Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 6 Dec 2017 16:58:45 -0700 Subject: [PATCH 036/150] ENH: Implemented DescoteauxEigenToScalarImageFilter --- .../itkDescoteauxEigenToScalarImageFilter.h | 195 ++++++++++++++++++ .../itkDescoteauxEigenToScalarImageFilter.hxx | 96 +++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + ...DescoteauxEigenToScalarImageFilterTest.cxx | 94 +++++++++ 4 files changed, 393 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h new file mode 100644 index 00000000000..b5a80882116 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h @@ -0,0 +1,195 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToScalarImageFilter_h +#define itkDescoteauxEigenToScalarImageFilter_h + +#include "itkEigenToScalarImageFilter.h" +#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" +#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" + +namespace itk +{ +/** \class DescoteauxEigenToScalarImageFilter + * \brief Compute the Descoteaux sheetness measure from the eigenvalues + * + * This is a convenience class implementing the EigenToScalarImageFilter + * abstract class. This class computes the Descoteaux sheetness measure for + * cortical bone. Internally, DescoteauxEigenToScalarParameterEstimationImageFilter + * and DescoteauxEigenToScalarFunctorImageFilter are used for automatic parameter + * estimation and implementation of the functor. + * + * Before passing an input to MultiScaleHessianEnhancementImageFilter, + * the DescoteauxEigenToScalarPreprocessingImageToImageFilter should be used. + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa EigenToScalarImageFilter + * \sa DescoteauxEigenToScalarParameterEstimationImageFilter + * \sa DescoteauxEigenToScalarFunctorImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template > +class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter + : public EigenToScalarImageFilter +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToScalarImageFilter Self; + typedef EigenToScalarImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); + + /** Mask related typedefs. */ + typedef typename TMaskImage::PixelType MaskPixelType; + + /** Procesing filters */ + typedef DescoteauxEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; + typedef DescoteauxEigenToScalarFunctorImageFilter UnaryFunctorFilterType; + + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + + /** Methods to set/get the mask image */ + void + SetMaskImage(const TMaskImage * mask) + { + this->m_ParameterEstimationFilter->SetMaskImage(mask); + this->Modified(); + } + virtual const TMaskImage * + GetMaskImage() const + { + return this->m_ParameterEstimationFilter->GetMaskImage(); + } + + /** Methods to set/get the background value */ + virtual void + SetBackgroundValue(const MaskPixelType back) + { + this->m_ParameterEstimationFilter->SetBackgroundValue(back); + this->Modified(); + } + virtual MaskPixelType + GetBackgroundValue() const + { + return this->m_ParameterEstimationFilter->GetBackgroundValue(); + } + + /** Methods to set/get the FrobeniusNormWeight */ + virtual void + SetFrobeniusNormWeight(const typename ParameterEstimationFilterType::RealType weight) + { + this->m_ParameterEstimationFilter->SetFrobeniusNormWeight(weight); + this->Modified(); + } + typename ParameterEstimationFilterType::RealType + GetFrobeniusNormWeight() const + { + return this->m_ParameterEstimationFilter->GetFrobeniusNormWeight(); + } + + /** Methods to get the computed parameters */ + typename UnaryFunctorFilterType::RealType + GetAlpha() const + { + return m_UnaryFunctorFilter->GetAlpha(); + } + typename UnaryFunctorFilterType::RealType + GetBeta() const + { + return m_UnaryFunctorFilter->GetBeta(); + } + typename UnaryFunctorFilterType::RealType + GetC() const + { + return m_UnaryFunctorFilter->GetC(); + } + + /** Methods to set/get the enhancment method */ + void + SetEnhanceBrightObjects() + { + this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); + this->Modified(); + } + void + SetEnhanceDarkObjects() + { + this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); + this->Modified(); + } + typename UnaryFunctorFilterType::RealType + GetEnhanceType() const + { + return this->m_UnaryFunctorFilter->GetEnhanceType(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + DescoteauxEigenToScalarImageFilter(); + virtual ~DescoteauxEigenToScalarImageFilter() {} + + /** Override since the filter needs all the data for the algorithm */ + void + GenerateInputRequestedRegion() ITK_OVERRIDE; + + /** Override since the filter produces all of its output */ + void + EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + + /** Single threaded since we are connecting data */ + void + GenerateData() ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); + + /* Filter pipeline */ + typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; + typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToScalarImageFilter.hxx" +#endif + +#endif // itkDescoteauxEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx new file mode 100644 index 00000000000..662619ae890 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx @@ -0,0 +1,96 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ +#ifndef itkDescoteauxEigenToScalarImageFilter_hxx +#define itkDescoteauxEigenToScalarImageFilter_hxx + +#include "itkDescoteauxEigenToScalarImageFilter.h" +#include "itkProgressAccumulator.h" + +namespace itk +{ +template +DescoteauxEigenToScalarImageFilter::DescoteauxEigenToScalarImageFilter() +{ + /* Instantiate filters. */ + m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); + m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); + + /* We require an input image */ + this->SetNumberOfRequiredInputs(1); +} + +template +void +DescoteauxEigenToScalarImageFilter::GenerateInputRequestedRegion() +{ + Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) + { + typename TInputImage::Pointer image = const_cast(this->GetInput()); + image->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +DescoteauxEigenToScalarImageFilter::EnlargeOutputRequestedRegion( + DataObject * data) +{ + Superclass::EnlargeOutputRequestedRegion(data); + data->SetRequestedRegionToLargestPossibleRegion(); +} + +template +void +DescoteauxEigenToScalarImageFilter::GenerateData() +{ + /* Get input */ + typename TInputImage::Pointer input = TInputImage::New(); + input->Graft(const_cast(this->GetInput())); + + /* Connect filters */ + m_ParameterEstimationFilter->SetInput(input); + m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); + m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); + m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); + m_UnaryFunctorFilter->SetCInput(m_ParameterEstimationFilter->GetCOutput()); + + /* Setup progress reporter */ + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); + progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); + + /* Graft output and we're done! */ + m_UnaryFunctorFilter->Update(); + this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); +} + +template +void +DescoteauxEigenToScalarImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; + os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; +} + +} // namespace itk + +#endif // itkDescoteauxEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index db72012e23c..6fbf43f9658 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -14,6 +14,7 @@ set( itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx itkDescoteauxEigenToScalarFunctorTest.cxx itkDescoteauxEigenToScalarFunctorImageTest.cxx + itkDescoteauxEigenToScalarImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -106,3 +107,10 @@ itk_add_test( BoneEnhancementTestDriver itkDescoteauxEigenToScalarFunctorImageTest ) + +itk_add_test( + NAME itkDescoteauxEigenToScalarImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkDescoteauxEigenToScalarImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx new file mode 100644 index 00000000000..2d88d8608a8 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx @@ -0,0 +1,94 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkDescoteauxEigenToScalarImageFilter.h" +#include "itkTestingMacros.h" +#include "itkMath.h" +#include "itkImageRegionIteratorWithIndex.h" + +int +itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) +{ + const unsigned int Dimension = 3; + typedef unsigned int MaskPixelType; + typedef itk::Image MaskType; + + typedef double OutputPixelType; + typedef itk::Image OutputType; + + typedef float EigenValueType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenValueImageType; + + typedef itk::DescoteauxEigenToScalarImageFilter + DescoteauxEigenToScalarImageFilterType; + + DescoteauxEigenToScalarImageFilterType::Pointer descoFilter = DescoteauxEigenToScalarImageFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); + + /* Test defaults */ + TEST_EXPECT_EQUAL(descoFilter->GetEigenValueOrder(), + DescoteauxEigenToScalarImageFilterType::Superclass::OrderByMagnitude); + + /* Create some test data which is computable */ + EigenValueArrayType simpleEigenPixel; + simpleEigenPixel.SetElement(0, 0.5); + simpleEigenPixel.SetElement(1, 1.25); + simpleEigenPixel.SetElement(2, -2); + + EigenValueImageType::RegionType region; + EigenValueImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + EigenValueImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + region.SetSize(size); + region.SetIndex(start); + + EigenValueImageType::Pointer image = EigenValueImageType::New(); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(simpleEigenPixel); + + /* Run with no exceptions */ + descoFilter->SetEnhanceBrightObjects(); + descoFilter->SetInput(image); + TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + + /* Make sure process for setting parameters works */ + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetC(), 2.41091269 * 0.5, 6, 0.000001)); + + itk::ImageRegionIteratorWithIndex it(descoFilter->GetOutput(), region); + + it.GoToBegin(); + while (!it.IsAtEnd()) + { + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.364376944099, 6, 0.000001)); + ++it; + } + + return EXIT_SUCCESS; +} From 6800673bfcfde177011692dceab0828632d0b392 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 9 Dec 2017 11:36:57 -0700 Subject: [PATCH 037/150] BUG: Fixed setters for KrcahEigenToScalarImageFilter to call Modified() --- .../include/itkKrcahEigenToScalarImageFilter.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index fa65ddbacae..53801f508a0 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -84,6 +84,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm SetMaskImage(const TMaskImage * mask) { this->m_ParameterEstimationFilter->SetMaskImage(mask); + this->Modified(); } virtual const TMaskImage * GetMaskImage() const @@ -96,6 +97,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm SetBackgroundValue(const MaskPixelType back) { this->m_ParameterEstimationFilter->SetBackgroundValue(back); + this->Modified(); } virtual MaskPixelType GetBackgroundValue() const @@ -108,6 +110,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm SetParameterSet(const KrcahImplementationType back) { this->m_ParameterEstimationFilter->SetParameterSet(back); + this->Modified(); } virtual KrcahImplementationType GetParameterSet() const @@ -118,11 +121,13 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm SetParameterSetToImplementation() { this->m_ParameterEstimationFilter->SetParameterSetToImplementation(); + this->Modified(); } virtual void SetParameterSetToJournalArticle() { this->m_ParameterEstimationFilter->SetParameterSetToJournalArticle(); + this->Modified(); } /** Methods to get the computed parameters */ @@ -147,11 +152,13 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm SetEnhanceBrightObjects() { this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); + this->Modified(); } void SetEnhanceDarkObjects() { this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); + this->Modified(); } typename UnaryFunctorFilterType::RealType GetEnhanceType() const From 8de140a35744a2939de86a9e3cdd3f0f3b4aaa22 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 9 Dec 2017 13:22:20 -0700 Subject: [PATCH 038/150] STYLE: Fixed ParameterEstimation to be const_correct --- .../include/itkDescoteauxEigenToScalarImageFilter.hxx | 5 ++--- ...DescoteauxEigenToScalarParameterEstimationImageFilter.hxx | 5 ++--- .../include/itkKrcahEigenToScalarImageFilter.hxx | 5 ++--- .../itkKrcahEigenToScalarParameterEstimationImageFilter.hxx | 5 ++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx index 662619ae890..09e43f289f1 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx @@ -59,9 +59,8 @@ template void DescoteauxEigenToScalarImageFilter::GenerateData() { - /* Get input */ - typename TInputImage::Pointer input = TInputImage::New(); - input->Graft(const_cast(this->GetInput())); + /* Get inputs */ + InputImageConstPointer input = this->GetInput(); /* Connect filters */ m_ParameterEstimationFilter->SetInput(input); diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx index 3a1212d7783..c0c38ae4be6 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx @@ -139,11 +139,10 @@ DescoteauxEigenToScalarParameterEstimationImageFilter:: RealType thisFrobeniusNorm; /* Get input pointer */ - InputImagePointer inputPointer = const_cast(this->GetInput()); + InputImageConstPointer inputPointer = this->GetInput(); /* Get mask pointer */ - MaskImagePointer maskPointer = TMaskImage::New(); - maskPointer = const_cast(this->GetMaskImage()); + MaskImageConstPointer maskPointer = this->GetMaskImage(); /* Setup progress reporter */ ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx index c08c09dc77c..aba19850167 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx @@ -58,9 +58,8 @@ template void KrcahEigenToScalarImageFilter::GenerateData() { - /* Get input */ - typename TInputImage::Pointer input = TInputImage::New(); - input->Graft(const_cast(this->GetInput())); + /* Get inputs */ + InputImageConstPointer input = this->GetInput(); /* Connect filters */ m_ParameterEstimationFilter->SetInput(input); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index 1f05d308682..1d3044d4eb2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -171,11 +171,10 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); /* Get input pointer */ - InputImagePointer inputPointer = const_cast(this->GetInput()); + InputImageConstPointer inputPointer = this->GetInput(); /* Get mask pointer */ - MaskImagePointer maskPointer = TMaskImage::New(); - maskPointer = const_cast(this->GetMaskImage()); + MaskImageConstPointer maskPointer = this->GetMaskImage(); /* Setup progress reporter */ ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); From 2132c52fbc140ff75309fe044d39dcf590ed1b42 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 9 Dec 2017 14:40:58 -0700 Subject: [PATCH 039/150] BUG: Fixed mask indexing bug from #4. --- .../itkDescoteauxEigenToScalarImageFilter.h | 8 +++-- .../itkDescoteauxEigenToScalarImageFilter.hxx | 8 ++++- ...enToScalarParameterEstimationImageFilter.h | 5 +++ ...ToScalarParameterEstimationImageFilter.hxx | 35 ++++++++++++++----- .../itkKrcahEigenToScalarImageFilter.h | 8 +++-- .../itkKrcahEigenToScalarImageFilter.hxx | 8 ++++- ...enToScalarParameterEstimationImageFilter.h | 5 +++ ...ToScalarParameterEstimationImageFilter.hxx | 35 ++++++++++++++----- ...alarParameterEstimationImageFilterTest.cxx | 13 +++++++ ...alarParameterEstimationImageFilterTest.cxx | 26 ++++++++++++++ 10 files changed, 129 insertions(+), 22 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h index b5a80882116..8046fd1a673 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h @@ -64,8 +64,12 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter /** Run-time type information (and related methods). */ itkTypeMacro(DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - /** Mask related typedefs. */ - typedef typename TMaskImage::PixelType MaskPixelType; + /** Useful template typedefs. */ + typedef typename TInputImage::Pointer InputImagePointer; + typedef typename TInputImage::ConstPointer InputImageConstPointer; + typedef typename TMaskImage::Pointer MaskImagePointer; + typedef typename TMaskImage::ConstPointer MaskImageConstPointer; + typedef typename TMaskImage::PixelType MaskPixelType; /** Procesing filters */ typedef DescoteauxEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx index 09e43f289f1..b7dd3e2ae51 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx @@ -39,11 +39,17 @@ void DescoteauxEigenToScalarImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) { - typename TInputImage::Pointer image = const_cast(this->GetInput()); + InputImagePointer image = const_cast(this->GetInput()); image->SetRequestedRegionToLargestPossibleRegion(); } + if (this->GetMaskImage()) + { + MaskImagePointer mask = const_cast(this->GetMaskImage()); + mask->SetRequestedRegionToLargestPossibleRegion(); + } } template diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h index f704b9cff11..00844b5b3da 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h @@ -39,6 +39,11 @@ namespace itk * Where the Frobenius norm for a real, symmetric matrix is given by * the square root of the sum of squares of the eigenvalues. * + * If the input image and mask have different regions over which they + * are defined, parameters are estimated only in the intersection of + * the two image regions. However, the mask region must be a proper sub + * subset (contained) in the image region. + * * \sa KrcahEigenToScalarImageFilter * * \author: Bryce Besler diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx index c0c38ae4be6..d835345a393 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx @@ -60,11 +60,17 @@ void DescoteauxEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) { InputImagePointer image = const_cast(this->GetInput()); image->SetRequestedRegionToLargestPossibleRegion(); } + if (this->GetMaskImage()) + { + MaskImagePointer mask = const_cast(this->GetMaskImage()); + mask->SetRequestedRegionToLargestPossibleRegion(); + } } template @@ -128,12 +134,6 @@ DescoteauxEigenToScalarParameterEstimationImageFilter:: const OutputRegionType & outputRegionForThread, ThreadIdType threadId) { - const SizeValueType size0 = outputRegionForThread.GetSize(0); - if (size0 == 0) - { - return; - } - /* Count starts zero */ RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); RealType thisFrobeniusNorm; @@ -144,11 +144,30 @@ DescoteauxEigenToScalarParameterEstimationImageFilter:: /* Get mask pointer */ MaskImageConstPointer maskPointer = this->GetMaskImage(); + /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ + InputRegionType croppedRegion = outputRegionForThread; + if (maskPointer) + { + croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); + /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() + * takes care of the case of the mask region being outside the image region. It's actually + * impossible to determine if the mask region is valid inside ThreadedGenerateData because + * outputRegionForThread is a sub region of the output region. + */ + } + + /* If size is zero, return */ + const SizeValueType size0 = croppedRegion.GetSize(0); + if (size0 == 0) + { + return; + } + /* Setup progress reporter */ - ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, outputRegionForThread); + ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); /* Iterate and count */ inputIt.GoToBegin(); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index 53801f508a0..f52aa4d762b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -64,8 +64,12 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm /** Run-time type information (and related methods). */ itkTypeMacro(KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); - /** Mask related typedefs. */ - typedef typename TMaskImage::PixelType MaskPixelType; + /** Useful template typedefs. */ + typedef typename TInputImage::Pointer InputImagePointer; + typedef typename TInputImage::ConstPointer InputImageConstPointer; + typedef typename TMaskImage::Pointer MaskImagePointer; + typedef typename TMaskImage::ConstPointer MaskImageConstPointer; + typedef typename TMaskImage::PixelType MaskPixelType; /** Procesing filters */ typedef KrcahEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx index aba19850167..68ab556a9a2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx @@ -39,11 +39,17 @@ void KrcahEigenToScalarImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) { - typename TInputImage::Pointer image = const_cast(this->GetInput()); + InputImagePointer image = const_cast(this->GetInput()); image->SetRequestedRegionToLargestPossibleRegion(); } + if (this->GetMaskImage()) + { + MaskImagePointer mask = const_cast(this->GetMaskImage()); + mask->SetRequestedRegionToLargestPossibleRegion(); + } } template diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index e166614cd32..d828dd9fbae 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -66,6 +66,11 @@ namespace itk * of view may throw off the parameter estimation. In those cases, a mask can * be provided so those voxels are not factored into the calculation of \f$ T \f$. * + * If the input image and mask have different regions over which they + * are defined, parameters are estimated only in the intersection of + * the two image regions. However, the mask region must be a proper sub + * subset (contained) in the image region. + * * \sa KrcahEigenToScalarImageFilter * * \author: Bryce Besler diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index 1d3044d4eb2..85a90c1b2a3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -61,11 +61,17 @@ void KrcahEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); + if (this->GetInput()) { InputImagePointer image = const_cast(this->GetInput()); image->SetRequestedRegionToLargestPossibleRegion(); } + if (this->GetMaskImage()) + { + MaskImagePointer mask = const_cast(this->GetMaskImage()); + mask->SetRequestedRegionToLargestPossibleRegion(); + } } template @@ -145,12 +151,6 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa const OutputRegionType & outputRegionForThread, ThreadIdType threadId) { - const SizeValueType size0 = outputRegionForThread.GetSize(0); - if (size0 == 0) - { - return; - } - /* Determine which function to call */ RealType (Self::*traceFunction)(InputPixelType); switch (m_ParameterSet) @@ -176,11 +176,30 @@ KrcahEigenToScalarParameterEstimationImageFilter::Threa /* Get mask pointer */ MaskImageConstPointer maskPointer = this->GetMaskImage(); + /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ + InputRegionType croppedRegion = outputRegionForThread; + if (maskPointer) + { + croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); + /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() + * takes care of the case of the mask region being outside the image region. It's actually + * impossible to determine if the mask region is valid inside ThreadedGenerateData because + * outputRegionForThread is a sub region of the output region. + */ + } + + /* If size is zero, return */ + const SizeValueType size0 = croppedRegion.GetSize(0); + if (size0 == 0) + { + return; + } + /* Setup progress reporter */ - ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, outputRegionForThread); + ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); /* Iterate and count */ inputIt.GoToBegin(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx index c17e3570f77..2d1ad1045c3 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx @@ -153,5 +153,18 @@ itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); + MaskType::Pointer mask2 = MaskType::New(); + mask2->SetRegions(maskRegion); + mask2->Allocate(); + mask2->FillBuffer(foregroundValue); + + descoteauxParameterEstimator->SetInput(image); + descoteauxParameterEstimator->SetMaskImage(mask2); + descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + return EXIT_SUCCESS; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index ed6c6ba8d4e..e0e710273d4 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -179,5 +179,31 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) TEST_EXPECT_EQUAL(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25); TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); + MaskType::Pointer mask2 = MaskType::New(); + mask2->SetRegions(maskRegion); + mask2->Allocate(); + mask2->FillBuffer(foregroundValue); + + krcahParameterEstimator->SetInput(image); + krcahParameterEstimator->SetParameterSetToImplementation(); + krcahParameterEstimator->SetMaskImage(mask2); + krcahParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); + + krcahParameterEstimator->SetInput(image); + krcahParameterEstimator->SetParameterSetToJournalArticle(); + krcahParameterEstimator->SetMaskImage(mask2); + krcahParameterEstimator->SetBackgroundValue(backgroundValue); + TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); + return EXIT_SUCCESS; } From 506accb228517504cec246bdf6f3f43ef7c9c081 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 10 Dec 2017 11:59:05 -0700 Subject: [PATCH 040/150] ENH: Removed MinimalStandardRandomVariateGenerator and NormalDistributionImageSource from template --- .../Filtering/BoneEnhancement/CMakeLists.txt | 2 - ...itkMinimalStandardRandomVariateGenerator.h | 94 ------------------- .../itkNormalDistributionImageSource.h | 92 ------------------ .../itkNormalDistributionImageSource.hxx | 79 ---------------- .../BoneEnhancement/src/CMakeLists.txt | 5 - ...kMinimalStandardRandomVariateGenerator.cxx | 52 ---------- ...stributionImageSourceTestOutput.mha.sha512 | 1 - .../BoneEnhancement/test/CMakeLists.txt | 21 ----- ...imalStandardRandomVariateGeneratorTest.cxx | 37 -------- .../itkNormalDistributionImageSourceTest.cxx | 67 ------------- ...MinimalStandardRandomVariateGenerator.wrap | 1 - .../itkNormalDistributionImageSource.wrap | 7 -- 12 files changed, 458 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/src/CMakeLists.txt delete mode 100644 Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap diff --git a/Modules/Filtering/BoneEnhancement/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/CMakeLists.txt index 24fc4f8865d..be6e51e0f5e 100644 --- a/Modules/Filtering/BoneEnhancement/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/CMakeLists.txt @@ -1,5 +1,3 @@ project(BoneEnhancement) -set(BoneEnhancement_LIBRARIES BoneEnhancement) - itk_module_impl() diff --git a/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h b/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h deleted file mode 100644 index c2da8080795..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkMinimalStandardRandomVariateGenerator.h +++ /dev/null @@ -1,94 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkMinimalStandardRandomVariateGenerator_h -#define itkMinimalStandardRandomVariateGenerator_h - -#include "itkIntTypes.h" -#include "itkObjectFactory.h" -#include "itkRandomVariateGeneratorBase.h" -#include "BoneEnhancementExport.h" -#include "itkNormalVariateGenerator.h" - -namespace itk -{ -namespace Statistics -{ -/** \class MinimalStandardRandomVariateGenerator - * \brief Linear congruential random random variate generator. - * - * This is a pseudo-random number generator for unsigned integers following - * - * \f[ - * X_{n+1} = (a X_n + c) \mod m - * \f] - * - * where \f$a\f$ is the Multiplier \f$c\f$ is the Increment and \f$m\f$ is - * the Modulus. - * - * http://en.wikipedia.com/wiki/Linear_congruential_generator - * - * The random numbers generated have a period \f$m\f$. - * - * This class uses \f$a = 48271\f$, \f$c = 0\f$, \f$m = 2^31 -1 = - * 2147483647\f$, the Minimial Standard configuration recommended by Park, - * Miller and Stockmeyer in 1993. - * - * \ingroup BoneEnhancement - */ -class BoneEnhancement_EXPORT MinimalStandardRandomVariateGenerator : public RandomVariateGeneratorBase -{ -public: - /** Standard class typedefs. */ - typedef MinimalStandardRandomVariateGenerator Self; - typedef RandomVariateGeneratorBase Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - typedef uint32_t IntegerType; - - typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType; - - /** Run-time type information (and related methods). */ - itkTypeMacro(MinimalStandardRandomVariateGenerator, RandomVariateGeneratorBase); - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** initialize with a simple IntegerType */ - void - Initialize(int randomSeed); - - /** Get a variate in the range [0, 1] */ - virtual double - GetVariate() ITK_OVERRIDE; - -protected: - MinimalStandardRandomVariateGenerator(); - virtual ~MinimalStandardRandomVariateGenerator() {} - - virtual void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - NormalGeneratorType::Pointer m_NormalGenerator; -}; - -} // end of namespace Statistics -} // end of namespace itk - -#endif // itkMinimalStandardRandomVariateGenerator_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h deleted file mode 100644 index b2aa1df2ed7..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.h +++ /dev/null @@ -1,92 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkNormalDistributionImageSource_h -#define itkNormalDistributionImageSource_h - -#include "itkGenerateImageSource.h" - -namespace itk -{ - -/** \class NormalDistributionImageSource - * - * \brief Generate a image of pixels sampled from a normal distribution. - * - * Real-valued pixels are sampled from a normal distribution. - * - * The pixels, \f$x > 0\f$ follow - * - * \f[ - * f(x) = \frac{1}{sx\sqrt{2 \pi}} e^{\left( \frac{-(ln x - m)^2}{2s^2} \right)} - * \f] - * - * where \f$s\f$ is the StandardDeviation and \f$m\f$ is the Mean of the - * underlying normal distribution. - * - * \ingroup BoneEnhancement - * - */ -template -class NormalDistributionImageSource : public GenerateImageSource -{ -public: - typedef TImage ImageType; - typedef typename ImageType::PixelType PixelType; - - /** Standard class typedefs. */ - typedef NormalDistributionImageSource Self; - typedef GenerateImageSource Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); - - /** Run-time type information. */ - itkTypeMacro(NormalDistributionImageSource, GenerateImageSource); - - /** Standard New macro. */ - itkNewMacro(Self); - -protected: - NormalDistributionImageSource(); - virtual ~NormalDistributionImageSource() {} - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - - typedef typename ImageType::RegionType OutputRegionType; - - virtual void - ThreadedGenerateData(const OutputRegionType & outputRegion, ThreadIdType threadId) ITK_OVERRIDE; - -private: - NormalDistributionImageSource(const Self &); // purposely not implemented - void - operator=(const Self &); // purposely not implemented - -#ifdef ITK_USE_CONCEPT_CHECKING - itkConceptMacro(FloatingPointPixel, (itk::Concept::IsFloatingPoint)); -#endif -}; -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkNormalDistributionImageSource.hxx" -#endif - -#endif // itkNormalDistributionImageSource_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx b/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx deleted file mode 100644 index d406348805d..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkNormalDistributionImageSource.hxx +++ /dev/null @@ -1,79 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkNormalDistributionImageSource_hxx -#define itkNormalDistributionImageSource_hxx - -#include "itkNormalDistributionImageSource.h" -#include "itkNormalVariateGenerator.h" - -#include "itkImageScanlineIterator.h" -#include "itkProgressReporter.h" - -namespace itk -{ - -template -NormalDistributionImageSource::NormalDistributionImageSource() -{} - - -template -void -NormalDistributionImageSource::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); -} - - -template -void -NormalDistributionImageSource::ThreadedGenerateData(const OutputRegionType & outputRegion, - ThreadIdType threadId) -{ - ImageType * output = this->GetOutput(); - - typedef itk::Statistics::NormalVariateGenerator NormalGeneratorType; - NormalGeneratorType::Pointer normalGenerator = NormalGeneratorType::New(); - normalGenerator->Initialize(101); - - const SizeValueType size0 = outputRegion.GetSize(0); - if (size0 == 0) - { - return; - } - const SizeValueType numberOfLinesToProcess = outputRegion.GetNumberOfPixels() / size0; - - typedef ImageScanlineIterator IteratorType; - IteratorType it(output, outputRegion); - ProgressReporter progress(this, threadId, numberOfLinesToProcess); - - while (!it.IsAtEnd()) - { - while (!it.IsAtEndOfLine()) - { - it.Set(normalGenerator->GetVariate()); - ++it; - } - it.NextLine(); - progress.CompletedPixel(); - } -} - -} // end namespace itk - -#endif // itkNormalDistributionImageSource_hxx diff --git a/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt deleted file mode 100644 index 29e2f0bcd37..00000000000 --- a/Modules/Filtering/BoneEnhancement/src/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(BoneEnhancement_SRCS - itkMinimalStandardRandomVariateGenerator.cxx - ) - -itk_module_add_library(BoneEnhancement ${BoneEnhancement_SRCS}) diff --git a/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx b/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx deleted file mode 100644 index 69d32cdd6f2..00000000000 --- a/Modules/Filtering/BoneEnhancement/src/itkMinimalStandardRandomVariateGenerator.cxx +++ /dev/null @@ -1,52 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#include "itkMinimalStandardRandomVariateGenerator.h" - -namespace itk -{ -namespace Statistics -{ - -MinimalStandardRandomVariateGenerator ::MinimalStandardRandomVariateGenerator() -{ - this->m_NormalGenerator = NormalGeneratorType::New(); - this->Initialize(1); -} - -void -MinimalStandardRandomVariateGenerator ::Initialize(int randomSeed) -{ - this->m_NormalGenerator->Initialize(randomSeed); -} - - -double -MinimalStandardRandomVariateGenerator ::GetVariate() -{ - return this->m_NormalGenerator->GetVariate(); -} - - -void -MinimalStandardRandomVariateGenerator ::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); -} - -} // end namespace Statistics -} // end namespace itk diff --git a/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 b/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 deleted file mode 100644 index a4017ad18cd..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/Baseline/itkNormalDistributionImageSourceTestOutput.mha.sha512 +++ /dev/null @@ -1 +0,0 @@ -38a102c75d4e30f57834fd3dc1ba61e30943714da9a9d27e4b77ee5fb58c1e34269a44c2af3cfd3a0b738de0f5ea293f0f609b8a66eede3f299703548ed57608 diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 6fbf43f9658..2aaa6475ca0 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -2,8 +2,6 @@ itk_module_test() set( BoneEnhancementTests - itkMinimalStandardRandomVariateGeneratorTest.cxx - itkNormalDistributionImageSourceTest.cxx itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -19,25 +17,6 @@ set( createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") -itk_add_test( - NAME itkMinimalStandardRandomVariateGeneratorTest - COMMAND - BoneEnhancementTestDriver - itkMinimalStandardRandomVariateGeneratorTest -) - -itk_add_test( - NAME itkNormalDistributionImageSourceTest - COMMAND - BoneEnhancementTestDriver - --without-threads - --compare - ${ITK_TEST_OUTPUT_DIR}/itkNormalDistributionImageSourceTestOutput.mha - DATA{Baseline/itkNormalDistributionImageSourceTestOutput.mha} - itkNormalDistributionImageSourceTest - ${ITK_TEST_OUTPUT_DIR}/itkNormalDistributionImageSourceTestOutput.mha -) - itk_add_test( NAME itkMaximumAbsoluteValueImageFilterTest COMMAND diff --git a/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx deleted file mode 100644 index 0ef8f379160..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkMinimalStandardRandomVariateGeneratorTest.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkMinimalStandardRandomVariateGenerator.h" - -#include "itkTestingMacros.h" -#include "itkMath.h" - -int -itkMinimalStandardRandomVariateGeneratorTest(int, char *[]) -{ - typedef itk::Statistics::MinimalStandardRandomVariateGenerator GeneratorType; - GeneratorType::Pointer generator = GeneratorType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(generator, MinimalStandardRandomVariateGenerator, RandomVariateGeneratorBase); - - generator->Initialize(324); - - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(generator->GetVariate(), 1.35581, 4, 0.0001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx deleted file mode 100644 index e2914a75273..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkNormalDistributionImageSourceTest.cxx +++ /dev/null @@ -1,67 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkNormalDistributionImageSource.h" - -#include "itkImageFileWriter.h" -#include "itkTestingMacros.h" - -int -itkNormalDistributionImageSourceTest(int argc, char * argv[]) -{ - if (argc < 2) - { - std::cerr << "Usage: " << argv[0]; - std::cerr << " outputImage"; - std::cerr << std::endl; - return EXIT_FAILURE; - } - const char * outputImageFileName = argv[1]; - - const unsigned int Dimension = 2; - typedef float PixelType; - typedef itk::Image ImageType; - - typedef itk::NormalDistributionImageSource DistributionSourceType; - DistributionSourceType::Pointer distributionSource = DistributionSourceType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(distributionSource, NormalDistributionImageSource, GenerateImageSource); - - - ImageType::SizeType size; - size.Fill(128); - distributionSource->SetSize(size); - - std::cout << distributionSource << std::endl; - - typedef itk::ImageFileWriter WriterType; - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName(outputImageFileName); - writer->SetInput(distributionSource->GetOutput()); - try - { - writer->Update(); - } - catch (itk::ExceptionObject & error) - { - std::cerr << "Error: " << error << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap deleted file mode 100644 index e13dd73db38..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkMinimalStandardRandomVariateGenerator.wrap +++ /dev/null @@ -1 +0,0 @@ -itk_wrap_simple_class("itk::Statistics::MinimalStandardRandomVariateGenerator" POINTER) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap deleted file mode 100644 index 70e93ecf270..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkNormalDistributionImageSource.wrap +++ /dev/null @@ -1,7 +0,0 @@ -itk_wrap_class("itk::NormalDistributionImageSource" POINTER) -foreach(d ${ITK_WRAP_IMAGE_DIMS}) - itk_wrap_template("${ITKM_I${ITKM_F}${d}}" - "${ITKT_I${ITKM_F}${d}}" - ) -endforeach() -itk_end_wrap_class() From 39dc50b3a357088506b5666c549ae5e4cbfefaa3 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 10 Dec 2017 21:49:07 -0700 Subject: [PATCH 041/150] ENH: wrapped MaximumAbsoluteValueImageFilter, fixed no == or != operators in functor --- .../itkMaximumAbsoluteValueImageFilter.h | 35 +++++++++++++------ .../itkMaximumAbsoluteValueImageFilter.wrap | 3 ++ 2 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkMaximumAbsoluteValueImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 500745d39f1..4748705a1c1 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -34,13 +34,17 @@ class MaximumAbsoluteValue ~MaximumAbsoluteValue() {} -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(Input1ConvertableToOutputCheck, (Concept::Convertible)); - itkConceptMacro(Input2ConvertableToOutputCheck, (Concept::Convertible)); - itkConceptMacro(Input1GreaterThanInput2Check, (Concept::GreaterThanComparable)); - // End concept checking -#endif + bool + operator!=(const MaximumAbsoluteValue &) const + { + return false; + } + + bool + operator==(const MaximumAbsoluteValue & other) const + { + return !(*this != other); + } inline TOutputPixel operator()(const TInputPixel1 A, const TInputPixel2 B) @@ -81,16 +85,25 @@ class MaximumAbsoluteValueImageFilter Functor::MaximumAbsoluteValue> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + typedef typename TInputImage1::PixelType Input1PixelType; + typedef typename TInputImage2::PixelType Input2PixelType; + typedef typename TOutputImage::PixelType OutputPixelType; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); - +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(Input1ConvertableToOutputCheck, (Concept::Convertible)); + itkConceptMacro(Input2ConvertableToOutputCheck, (Concept::Convertible)); + itkConceptMacro(Input1GreaterThanInput2Check, (Concept::GreaterThanComparable)); + // End concept checking +#endif protected: MaximumAbsoluteValueImageFilter() {}; diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkMaximumAbsoluteValueImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkMaximumAbsoluteValueImageFilter.wrap new file mode 100644 index 00000000000..170a98e516b --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkMaximumAbsoluteValueImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::MaximumAbsoluteValueImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}") +itk_end_wrap_class() From 969ed52df0a5fa70430df8e4ce39c7337bedf9c7 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 10:05:04 -0700 Subject: [PATCH 042/150] ENH: Added MultiScaleHessianEnhancementImageFilter wrapping --- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 3 +-- .../BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap | 3 +++ .../wrapping/itkMultiScaleHessianEnhancementImageFilter.wrap | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkMultiScaleHessianEnhancementImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 59f6485a709..c88f95b23bd 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -21,7 +21,6 @@ #include "itkImageToImageFilter.h" #include "itkHessianRecursiveGaussianImageFilter.h" #include "itkSymmetricEigenAnalysisImageFilter.h" -#include "itkSymmetricEigenAnalysis.h" #include "itkMaximumAbsoluteValueImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" @@ -87,7 +86,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Eigenvalue analysis related typedefs. */ typedef typename NumericTraits::RealType RealType; - typedef FixedArray EigenValueArrayType; + typedef Vector EigenValueArrayType; typedef Image EigenValueImageType; typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap new file mode 100644 index 00000000000..e11f604592c --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) +itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}") +itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkMultiScaleHessianEnhancementImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkMultiScaleHessianEnhancementImageFilter.wrap new file mode 100644 index 00000000000..beecc4eb510 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkMultiScaleHessianEnhancementImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::MultiScaleHessianEnhancementImageFilter" POINTER) +itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_REAL}" "3") +itk_end_wrap_class() From 7d98f5c5b4bd0e7c5de58f58a52d51c6328d2222 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 10:05:33 -0700 Subject: [PATCH 043/150] ENH: Added DescoteauxEigenToScalarImageFilter wrapping --- .../itkDescoteauxEigenToScalarImageFilter.wrap | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap new file mode 100644 index 00000000000..c09ae563cbd --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap @@ -0,0 +1,13 @@ +itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + foreach(t2 ${WRAP_ITK_SCALAR}) + foreach(t3 ${WRAP_ITK_SCALAR}) + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") + endforeach() + endforeach() +endforeach() + +# Currently, this doesn't work +#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) +itk_end_wrap_class() From 86c05fe2fd601c75efcab367895ec557e020bda3 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 11:06:01 -0700 Subject: [PATCH 044/150] ENH: Added KrcahEigenToScalarImageFilter wrapping --- .../wrapping/itkKrcahEigenToScalarImageFilter.wrap | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap new file mode 100644 index 00000000000..674a3309f3b --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap @@ -0,0 +1,13 @@ +itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + foreach(t2 ${WRAP_ITK_SCALAR}) + foreach(t3 ${WRAP_ITK_SCALAR}) + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") + endforeach() + endforeach() +endforeach() + +# Currently, this doesn't work +#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) +itk_end_wrap_class() From dedfb85cd1b7a58c2ddb03c491487005cfc8a61d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 14:41:11 -0700 Subject: [PATCH 045/150] BUG: Removed wrapping for EigenToScalarImageFilter since it is an abstract class --- .../BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap deleted file mode 100644 index e11f604592c..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,3 +0,0 @@ -itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) -itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}") -itk_end_wrap_class() From 28999a5679377b6efadb19b80563ece1356a7ea5 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 14:44:15 -0700 Subject: [PATCH 046/150] BUG: Fixed Descoteaux and Krcah wrapping to use proper types --- .../wrapping/itkDescoteauxEigenToScalarImageFilter.wrap | 2 +- .../wrapping/itkKrcahEigenToScalarImageFilter.wrap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap index c09ae563cbd..3eba96dd278 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap @@ -1,6 +1,6 @@ itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_SCALAR}) + foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) # Only defined for vectors of dimension 3 and images of dimension 3 itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap index 674a3309f3b..2dc00be83c6 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap @@ -1,6 +1,6 @@ itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_SCALAR}) + foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) # Only defined for vectors of dimension 3 and images of dimension 3 itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") From c02b0d6bf567b57587138d88d132eeb680888075 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 14:45:49 -0700 Subject: [PATCH 047/150] BUG: Use float for eigenpixel representation to support wrapping in MultiScaleHessianEnhancementImageFilter --- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index c88f95b23bd..31d6b20eb77 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -84,9 +84,12 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image typedef typename HessianFilterType::OutputImageType HessianImageType; typedef typename HessianImageType::PixelType HessianPixelType; - /** Eigenvalue analysis related typedefs. */ + /** Eigenvalue analysis related typedefs. The ITK python wrapping usually wraps floating types + * and not double types. For this reason, the eigenvalues are of type float. + */ typedef typename NumericTraits::RealType RealType; - typedef Vector EigenValueArrayType; + typedef typename NumericTraits::FloatType FloatType; + typedef Vector EigenValueArrayType; typedef Image EigenValueImageType; typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; From fa26a228359e04ca84cdb131e603720a3cad0f25 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 11 Dec 2017 23:15:51 -0700 Subject: [PATCH 048/150] BUG: Fixed progress reporting bug in MultiScaleHessianEnhancementImageFilter --- .../itkMultiScaleHessianEnhancementImageFilter.hxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 97a61aead84..bd8c859fc88 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -107,14 +107,15 @@ MultiScaleHessianEnhancementImageFilter::GenerateData float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); - progress->RegisterInternalFilter(m_HessianFilter, 3 * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenAnalysisFilter, 3 * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenToScalarImageFilter, 3 * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_HessianFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenAnalysisFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToScalarImageFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); /* Check if we need to run the MaximumAbsoluteValueFilter at all */ if (m_SigmaArray.GetSize() > 1) { - progress->RegisterInternalFilter(m_MaximumAbsoluteValueFilter, perFilterProccessPercentage); + progress->RegisterInternalFilter(m_MaximumAbsoluteValueFilter, + (m_SigmaArray.GetSize() - 1) * perFilterProccessPercentage); } else { From 2f28c8ce02ce1a12b4dd0ac19b45ef43324c3f95 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 12 Dec 2017 00:22:32 -0700 Subject: [PATCH 049/150] BUG: Explicit wrapping for KrcahEigenToScalarParameterEstimationImageFilter --- .../wrapping/itkKrcahEigenToScalarImageFilter.wrap | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap index 2dc00be83c6..fbb281bfc40 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap @@ -1,3 +1,12 @@ +itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER_WITH_SUPERCLASS) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + foreach(t3 ${WRAP_ITK_SCALAR}) + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t3}3}") + endforeach() +endforeach() +itk_end_wrap_class() + itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) From 2910c6b1bde75868046555b18ce40e456e10546b Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 12 Dec 2017 12:32:29 -0700 Subject: [PATCH 050/150] BUG: Fixed wrapping for all *EigenToScalarImageFilter classes --- .../itkDescoteauxEigenToScalarImageFilter.wrap | 2 +- .../wrapping/itkEigenToScalarImageFilter.wrap | 13 +++++++++++++ .../wrapping/itkKrcahEigenToScalarImageFilter.wrap | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap index 3eba96dd278..d5ce1a5acc1 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap @@ -1,4 +1,4 @@ -itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap new file mode 100644 index 00000000000..f4118a4345a --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap @@ -0,0 +1,13 @@ +itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + foreach(t2 ${WRAP_ITK_REAL}) + foreach(t3 ${WRAP_ITK_SCALAR}) + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") + endforeach() + endforeach() +endforeach() + +# Currently, this doesn't work +#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) +itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap index fbb281bfc40..273175aba3b 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap @@ -1,4 +1,4 @@ -itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) # Only defined for vectors of dimension 3 and images of dimension 3 @@ -7,7 +7,7 @@ foreach(t1 ${WRAP_ITK_VECTOR_REAL}) endforeach() itk_end_wrap_class() -itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) From ebc1536fc671210be95dee59543f585fd81ac4ac Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 12 Dec 2017 13:51:17 -0700 Subject: [PATCH 051/150] BUG: Fixed double wrapping of EigenToScalarImageFilter --- .../wrapping/itkEigenToScalarImageFilter.wrap | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap index f4118a4345a..4f4a7ee5eb9 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap @@ -1,10 +1,8 @@ itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") - endforeach() + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") endforeach() endforeach() From f1959cd4af7671aa8a233493a4969f9b65fcb562 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 12 Dec 2017 23:05:35 -0700 Subject: [PATCH 052/150] BUG: Corrected GenerateInputRequestedRegion in KrcahEigenToScalarPreprocessingImageToImageFilter --- ...nToScalarPreprocessingImageToImageFilter.h | 25 +++++- ...oScalarPreprocessingImageToImageFilter.hxx | 86 +++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index f83cb25fbca..ea75044d05c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -68,9 +68,15 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter /** Runtime information support. */ itkTypeMacro(KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); + /** Extract some information from the image types. Dimensionality + * of the two images is assumed to be the same. */ + itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); + /** Image related typedefs. */ - typedef typename TInputImage::PixelType PixelType; - typedef typename NumericTraits::RealType RealType; + typedef typename TInputImage::PixelType PixelType; + typedef typename TOutputImage::PixelType OutputPixelType; + typedef typename NumericTraits::RealType RealType; + typedef typename NumericTraits::ValueType OutputPixelValueType; /** Typedefs for internal filters */ typedef DiscreteGaussianImageFilter GaussianFilterType; @@ -91,6 +97,21 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter itkSetMacro(ScalingConstant, RealType); itkGetConstMacro(ScalingConstant, RealType); + /** DiscreteGaussianImageFilter needs a larger input requested region + * than the output requested region (larger by the size of the + * Gaussian kernel). As such, DiscreteGaussianImageFilter needs to + * provide an implementation for GenerateInputRequestedRegion() in + * order to inform the pipeline execution model. + * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ + virtual void + GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, + (Concept::SameDimension)); + // End concept checking +#endif protected: KrcahEigenToScalarPreprocessingImageToImageFilter(); virtual ~KrcahEigenToScalarPreprocessingImageToImageFilter() {} diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx index d178434aa0c..51487470594 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx @@ -20,6 +20,7 @@ #define itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx #include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" +#include "itkGaussianOperator.h" #include "itkMath.h" namespace itk @@ -41,6 +42,91 @@ KrcahEigenToScalarPreprocessingImageToImageFilter +void +KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() throw( + InvalidRequestedRegionError) +{ + // This implementation is copied from itkDiscreteGaussianImageFilter + + // call the superclass' implementation of this method. this should + // copy the output requested region to the input requested region + Superclass::GenerateInputRequestedRegion(); + + // get pointers to the input and output + typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) + { + return; + } + + // Build an operator so that we can determine the kernel size + GaussianOperator oper; + + typename TInputImage::SizeType radius; + + for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) + { + // Determine the size of the operator in this dimension. Note that the + // Gaussian is built as a 1D operator in each of the specified directions. + oper.SetDirection(i); + if (m_GaussianFilter->GetUseImageSpacing() == true) + { + if (this->GetInput()->GetSpacing()[i] == 0.0) + { + itkExceptionMacro(<< "Pixel spacing cannot be zero"); + } + else + { + // convert the variance from physical units to pixels + double s = this->GetInput()->GetSpacing()[i]; + s = s * s; + oper.SetVariance(m_GaussianFilter->GetVariance()[i] / s); + } + } + else + { + oper.SetVariance(m_GaussianFilter->GetVariance()[i]); + } + oper.SetMaximumError(m_GaussianFilter->GetMaximumError()[i]); + oper.SetMaximumKernelWidth(m_GaussianFilter->GetMaximumKernelWidth()); + oper.CreateDirectional(); + + radius[i] = oper.GetRadius(i); + } + + // get a copy of the input requested region (should equal the output + // requested region) + typename TInputImage::RegionType inputRequestedRegion; + inputRequestedRegion = inputPtr->GetRequestedRegion(); + + // pad the input requested region by the operator radius + inputRequestedRegion.PadByRadius(radius); + + // crop the input requested region at the input's largest possible region + if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) + { + inputPtr->SetRequestedRegion(inputRequestedRegion); + return; + } + else + { + // Couldn't crop the region (requested region is outside the largest + // possible region). Throw an exception. + + // store what we tried to request (prior to trying to crop) + inputPtr->SetRequestedRegion(inputRequestedRegion); + + // build an exception + InvalidRequestedRegionError e(__FILE__, __LINE__); + e.SetLocation(ITK_LOCATION); + e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + e.SetDataObject(inputPtr); + throw e; + } +} + template void KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateData() From 221e94d6f245cde44514cdb0d3ccd3eb3ac8117f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 12 Dec 2017 23:06:08 -0700 Subject: [PATCH 053/150] ENH: Wrapped KrcahEigenToScalarPreprocessingImageToImageFilter --- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap new file mode 100644 index 00000000000..588cba91429 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::KrcahEigenToScalarPreprocessingImageToImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}") +itk_end_wrap_class() From 7ff834244eaffb4b551132cd271ff632b5aaa509 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 2 Feb 2018 13:16:05 -0700 Subject: [PATCH 054/150] ENH: Implemented HessianGaussianImageFilter with streaming --- .../include/itkHessianGaussianImageFilter.h | 159 +++++++++++ .../include/itkHessianGaussianImageFilter.hxx | 269 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + .../itkHessianGaussianImageFilterTest.cxx | 52 ++++ .../itkHessianGaussianImageFilter.wrap | 3 + 5 files changed, 491 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h new file mode 100644 index 00000000000..4a70fd81ea8 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h @@ -0,0 +1,159 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkHessianGaussianImageFilter_h +#define itkHessianGaussianImageFilter_h + +#include "itkDiscreteGaussianDerivativeImageFilter.h" +#include "itkNthElementImageAdaptor.h" +#include "itkImage.h" +#include "itkSymmetricSecondRankTensor.h" +#include "itkPixelTraits.h" + +namespace itk +{ +/** \class HessianGaussianImageFilter + * \brief Computes the Hessian matrix of an image by convolution + * with the Second and Cross derivatives of a Gaussian + * with streaming. + * + * This filter is implemented using the discrete gaussian + * filters to enable streaming. Although IIR filters are faster + * than FIR filters, IIR filters cannot be streamed. FIR filters + * are slower but can be streamed for small memory computers. + * + * This class is an exact copy of HessianRecursiveGaussianImageFilter + * but with streaming. + * + * \sa HessianRecursiveGaussianImageFilter. + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ + +template ::RealType, + TInputImage::ImageDimension>, + TInputImage::ImageDimension>> +class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef HessianGaussianImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Pixel Type of the input image */ + typedef TInputImage InputImageType; + typedef typename TInputImage::PixelType PixelType; + typedef typename NumericTraits::RealType RealType; + + /** Image dimension. */ + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Define the image type for internal computations + RealType is usually 'double' in NumericTraits. + Here we prefer float in order to save memory. */ + typedef float InternalRealType; + typedef Image RealImageType; + + /** Output Image Nth Element Adaptor + * This adaptor allows to use conventional scalar + * smoothing filters to compute each one of the + * components of the gradient image pixels. */ + typedef NthElementImageAdaptor OutputImageAdaptorType; + + typedef typename OutputImageAdaptorType::Pointer OutputImageAdaptorPointer; + + /** Derivative filter type */ + typedef DiscreteGaussianDerivativeImageFilter DerivativeFilterType; + + /** Pointer to a gaussian filter. */ + typedef typename DerivativeFilterType::Pointer DerivativeFilterPointer; + + /** Pointer to the Output Image */ + typedef typename TOutputImage::Pointer OutputImagePointer; + + /** Type of the output Image */ + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename PixelTraits::ValueType OutputComponentType; + + /** Run-time type information (and related methods). */ + itkTypeMacro(HessianGaussianImageFilter, ImageToImageFilter); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Set Sigma value. Sigma is measured in the units of image spacing. */ + void + SetSigma(RealType sigma); + RealType + GetSigma() const; + + /** Define which normalization factor will be used for the Gaussian + * \sa DiscreteGaussianDerivativeImageFilter::SetNormalizeAcrossScale + */ + void + SetNormalizeAcrossScale(bool normalizeInScaleSpace); + bool + GetNormalizeAcrossScale() const; + itkBooleanMacro(NormalizeAcrossScale); + + /** As opposed to HessianRecursiveGaussianImageFilter, HessianGaussianImageFilter + * doe not need all of the input to produce an output. However, it does need to + * expand the InputRequestedRegion region to account for the support of the + * Gaussian filter. + * \sa DiscreteGaussianDerivativeImageFilter::GenerateInputRequestedRegion() */ + // TODO + virtual void + GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + +#ifdef ITK_USE_CONCEPT_CHECKING + /** Begin concept checking */ + itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); + itkConceptMacro(OutputHasPixelTraitsCheck, (Concept::HasPixelTraits)); + /** End concept checking */ +#endif + +protected: + HessianGaussianImageFilter(); + virtual ~HessianGaussianImageFilter() {} + void + PrintSelf(std::ostream & os, Indent indent) const; + + /** Generate Data */ + void + GenerateData(void); + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(HessianGaussianImageFilter); + + /** Internal filters **/ + DerivativeFilterPointer m_DerivativeFilter; + OutputImageAdaptorPointer m_ImageAdaptor; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkHessianGaussianImageFilter.hxx" +#endif + +#endif // itkHessianGaussianImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx new file mode 100644 index 00000000000..36c0b3fe27f --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -0,0 +1,269 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkHessianGaussianImageFilter_hxx +#define itkHessianGaussianImageFilter_hxx + +#include "itkHessianGaussianImageFilter.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkProgressAccumulator.h" +#include "itkGaussianDerivativeOperator.h" +#include "itkMath.h" + +namespace itk +{ +/** + * Constructor + */ +template +HessianGaussianImageFilter::HessianGaussianImageFilter() +{ + // Create Derivative Filter + m_DerivativeFilter = DerivativeFilterType::New(); + m_DerivativeFilter->SetInput(this->GetInput()); + m_DerivativeFilter->ReleaseDataFlagOn(); // output is only used once + m_DerivativeFilter->UseImageSpacingOn(); + + // Create image adaptor + m_ImageAdaptor = OutputImageAdaptorType::New(); + + // Setup defaults + this->SetNormalizeAcrossScale(true); + this->SetSigma(1.0); +} + +/** + * Set value of Sigma + */ +template +void +HessianGaussianImageFilter::SetSigma(RealType sigma) +{ + m_DerivativeFilter->SetVariance(sigma * sigma); + + this->Modified(); +} + +/** + * Get value of Sigma + */ +template +typename HessianGaussianImageFilter::RealType +HessianGaussianImageFilter::GetSigma() const +{ + return sqrt(m_DerivativeFilter->GetVariance()[0]); +} + +/** + * Set Normalize Across Scale Space + */ +template +void +HessianGaussianImageFilter::SetNormalizeAcrossScale(bool normalize) +{ + m_DerivativeFilter->SetNormalizeAcrossScale(normalize); + + this->Modified(); +} + +/** + * Get Normalize Across SCale Space + */ +template +bool +HessianGaussianImageFilter::GetNormalizeAcrossScale() const +{ + return m_DerivativeFilter->GetNormalizeAcrossScale(); +} + +template +void +HessianGaussianImageFilter::GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) +{ + // call the superclass' implementation of this method. this should + // copy the output requested region to the input requested region + Superclass::GenerateInputRequestedRegion(); + + // get pointers to the input + typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) + { + return; + } + + // Build an operator so that we can determine the kernel size + GaussianDerivativeOperator oper; + typename TInputImage::SizeType radius; + + for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) + { + // Determine the size of the operator in this dimension. Note that the + // Gaussian is built as a 1D operator in each of the specified directions. + oper.SetDirection(i); + if (this->GetInput()->GetSpacing()[i] == 0.0) + { + itkExceptionMacro(<< "Pixel spacing cannot be zero"); + } + else + { + oper.SetSpacing(this->GetInput()->GetSpacing()[i]); + } + + // GaussianDerivativeOperator modifies the variance when setting image + // spacing + oper.SetVariance(this->m_DerivativeFilter->GetVariance()[i]); + oper.SetMaximumError(this->m_DerivativeFilter->GetMaximumError()[i]); + oper.SetMaximumKernelWidth(this->m_DerivativeFilter->GetMaximumKernelWidth()); + oper.CreateDirectional(); + + radius[i] = oper.GetRadius(i); + } + + // get a copy of the input requested region (should equal the output + // requested region) + typename TInputImage::RegionType inputRequestedRegion; + inputRequestedRegion = inputPtr->GetRequestedRegion(); + + // pad the input requested region by the operator radius + inputRequestedRegion.PadByRadius(radius); + + // crop the input requested region at the input's largest possible region + if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) + { + inputPtr->SetRequestedRegion(inputRequestedRegion); + return; + } + else + { + // Couldn't crop the region (requested region is outside the largest + // possible region). Throw an exception. + + // store what we tried to request (prior to trying to crop) + inputPtr->SetRequestedRegion(inputRequestedRegion); + + // build an exception + InvalidRequestedRegionError e(__FILE__, __LINE__); + e.SetLocation(ITK_LOCATION); + e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + e.SetDataObject(inputPtr); + throw e; + } +} + +/** + * Compute filter for Gaussian kernel + */ +template +void +HessianGaussianImageFilter::GenerateData(void) +{ + itkDebugMacro(<< "HessianGaussianImageFilter generating data "); + + // Create a process accumulator for tracking the progress of this + // minipipeline + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + + // Compute the contribution of each filter to the total progress. + // For a DxD matrix, we do the following number of computations: + // \sum_{i=1}^D \sum_{j=i}^D 1 = D(D+1)/2 + const double weight = 1.0 / (ImageDimension * (ImageDimension + 1) / 2.0); + + progress->RegisterInternalFilter(m_DerivativeFilter, weight); + + const typename TInputImage::ConstPointer inputImage(this->GetInput()); + + // Setup Image Adaptor + m_ImageAdaptor->SetImage(this->GetOutput()); + + m_ImageAdaptor->SetLargestPossibleRegion(inputImage->GetLargestPossibleRegion()); + + m_ImageAdaptor->SetBufferedRegion(inputImage->GetBufferedRegion()); + + m_ImageAdaptor->SetRequestedRegion(inputImage->GetRequestedRegion()); + + m_ImageAdaptor->Allocate(); + + m_DerivativeFilter->SetInput(inputImage); + + unsigned int element = 0; + int order[ImageDimension]; + + for (unsigned int dima = 0; dima < ImageDimension; dima++) + { + for (unsigned int dimb = dima; dimb < ImageDimension; dimb++) + { + // All directions have zero order derivative initially + for (int k = 0; k < ImageDimension; ++k) + { + order[k] = 0; + } + + // Now set derivative directions. Note that this takes care + // of the case when dima == dimb + order[dima] = order[dima] + 1; + order[dimb] = order[dimb] + 1; + + // Set order and update + m_DerivativeFilter->SetOrder(order); + m_DerivativeFilter->Update(); + typename RealImageType::Pointer derivativeImage; + derivativeImage = m_DerivativeFilter->GetOutput(); + + progress->ResetFilterProgressAndKeepAccumulatedProgress(); + + // Copy the results to the corresponding component + // on the output image of vectors + m_ImageAdaptor->SelectNthElement(element++); + + ImageRegionIteratorWithIndex it(derivativeImage, derivativeImage->GetRequestedRegion()); + + ImageRegionIteratorWithIndex ot(m_ImageAdaptor, m_ImageAdaptor->GetRequestedRegion()); + + const RealType spacingA = inputImage->GetSpacing()[dima]; + const RealType spacingB = inputImage->GetSpacing()[dimb]; + + const RealType factor = spacingA * spacingB; + + it.GoToBegin(); + ot.GoToBegin(); + while (!it.IsAtEnd()) + { + ot.Set(it.Get() / factor); + ++it; + ++ot; + } + + derivativeImage->ReleaseData(); + } + } +} + +template +void +HessianGaussianImageFilter::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << "DerivativeFilter: " << m_DerivativeFilter << std::endl; +} + +} // end namespace itk + +#endif // itkHessianGaussianImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 2aaa6475ca0..275cc927636 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -13,6 +13,7 @@ set( itkDescoteauxEigenToScalarFunctorTest.cxx itkDescoteauxEigenToScalarFunctorImageTest.cxx itkDescoteauxEigenToScalarImageFilterTest.cxx + itkHessianGaussianImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -93,3 +94,10 @@ itk_add_test( BoneEnhancementTestDriver itkDescoteauxEigenToScalarImageFilterTest ) + +itk_add_test( + NAME itkHessianGaussianImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkHessianGaussianImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx new file mode 100644 index 00000000000..186ab1f10cf --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx @@ -0,0 +1,52 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkHessianGaussianImageFilter.h" +#include "itkUnaryFunctorImageFilter.h" +#include "itkTestingMacros.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkMath.h" + +int +itkHessianGaussianImageFilterTest(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::HessianGaussianImageFilter HessianGaussianImageFilterType; + + HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); + + /* Basic tests. */ + EXERCISE_BASIC_OBJECT_METHODS(hess_filter, HessianGaussianImageFilter, ImageToImageFilter); + + /* Exercise basic set/get methods */ + TEST_SET_GET_VALUE(1.0, hess_filter->GetSigma()); + hess_filter->SetSigma(0.5); + TEST_SET_GET_VALUE(0.5, hess_filter->GetSigma()); + + TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + hess_filter->SetNormalizeAcrossScale(true); + TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + hess_filter->NormalizeAcrossScaleOff(); + TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + hess_filter->NormalizeAcrossScaleOn(); + TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap new file mode 100644 index 00000000000..d5ec3c65c39 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::HessianGaussianImageFilter" POINTER) +itk_wrap_image_filter("${WRAP_ITK_SCALAR}" 1) +itk_end_wrap_class() From ad44e4cce25af74ed270a00cfe8b99ba474217e9 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 4 Feb 2018 01:49:40 -0700 Subject: [PATCH 055/150] ENH: Implemented itkEigenToMeasureParameterEstimationFilter --- ...kEigenToMeasureParameterEstimationFilter.h | 179 +++++++++++ ...igenToMeasureParameterEstimationFilter.hxx | 282 ++++++++++++++++++ 2 files changed, 461 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..8a08a093ba4 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,179 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureParameterEstimationFilter_h +#define itkEigenToMeasureParameterEstimationFilter_h + +#include "itkStreamingImageFilter.h" +#include "itkSpatialObject.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace itk +{ +/** \class EigenToMeasureParameterEstimationFilter + * \brief Abstract class for estimating local-structure parameters from eigenvalues. + * + * This is an abstract class that estimates parameters for local-structure enhancement + * from eigen-images. Other classes should inherit from this class so they can be used + * in the MultiScaleHessianEnhancementImageFilter framework. + * + * To estimate the parameters for local-structure enhancement, every pixel in the input + * image must be seen. To implement this functionality in a memory efficinet way, this + * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by + * restricting the output image region. + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa StreamingImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter + : public StreamingImageFilter +{ +public: + /** Standard Self typedef */ + typedef EigenToMeasureParameterEstimationFilter Self; + typedef StreamingImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EigenToMeasureParameterEstimationFilter, StreamingImageFilter); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Input Image typedefs. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Output image typedefs. */ + typedef InputImageType OutputImageType; + typedef InputImageRegionType OutputImageRegionType; + + /** Input SpatialObject typedefs. */ + typedef TInputSpatialObject SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Functor typedefs. */ + typedef TFunction FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + typedef typename ParameterType::ValueType ParameterValueType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; + itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); + + /** Get the functor object. The functor is returned by reference. + * (Functors do not have to derive from itk::LightObject, so they do + * not necessarily have a reference count. So we cannot return a + * SmartPointer.) */ + FunctorType & + GetFunctor() + { + return m_Functor; + } + const FunctorType & + GetFunctor() const + { + return m_Functor; + } + + /** Set the functor object. This replaces the current Functor with a + * copy of the specified Functor. This allows the user to specify a + * functor that has ivars set differently than the default functor. + * This method requires the following to be defined: + * Initialize() + * ProcessPixel() + * GetComputedParameters() + */ + void + SetFunctor(const FunctorType & functor) + { + if (m_Functor != functor) + { + m_Functor = functor; + this->Modified(); + } + } + + /** Decorators for parameters so they can be passed as a process object */ + ParameterDecoratedType * + GetParametersOutput(); + const ParameterDecoratedType * + GetParametersOutput() const; + + /** Standard getters for the parameters */ + ParameterType + GetParameters() const + { + return this->GetParametersOutput()->Get(); + } + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + + /** Override UpdateOutputData() from StreamingImageFilter to divide + * upstream updates into pieces. This filter does not have a GenerateData() + * or ThreadedGenerateData() method. Instead, all the work is done + * in UpdateOutputData() since it must update a little, execute a little, + * update some more, execute some more, etc. */ + void + UpdateOutputData(DataObject * output) ITK_OVERRIDE; + + /** Static function used as a "callback" by the MultiThreader. The threading + * library will call this routine for each thread, which will delegate the + * control to ThreadedGenerateData(). */ + static ITK_THREAD_RETURN_TYPE + ThreaderCallback(void * arg) ITK_OVERRIDE; + + /** Repeatedly call the functor for each pixel we index. */ + void + ThreadedGenerateData(const InputImageRegionType & region, unsigned int streamNumber); + + struct ThreadStruct + { + Pointer Filter; + }; + +protected: + EigenToMeasureParameterEstimationFilter(); + virtual ~EigenToMeasureParameterEstimationFilter() ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); + + /* Private data members. */ + FunctorType m_Functor; + unsigned int m_CurrentSplit; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkEigenToMeasureParameterEstimationFilter.hxx" +#endif + +#endif // itkEigenToMeasureParameterEstimationFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..c1b4177f207 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,282 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureParameterEstimationFilter_hxx +#define itkEigenToMeasureParameterEstimationFilter_hxx + +#include "itkEigenToMeasureParameterEstimationFilter.h" +#include "itkCommand.h" +#include "itkImageAlgorithm.h" +#include "itkImageRegionSplitterSlowDimension.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkImageRegionSplitterBase.h" + +namespace itk +{ +template +EigenToMeasureParameterEstimationFilter:: + EigenToMeasureParameterEstimationFilter() + : m_CurrentSplit(0) +{ + /* We require an input image */ + this->SetNumberOfRequiredInputs(1); + + /* We require an output image and parameters */ + this->SetNumberOfRequiredOutputs(2); + + /* Allocate parameterset decorator */ + typename ParameterDecoratedType::Pointer output = ParameterDecoratedType::New(); + ParameterType initialParameters; + for (unsigned int i = 0; i < initialParameters.Length; ++i) + { + initialParameters[i] = 0; + } + output->Set(initialParameters); + this->ProcessObject::SetNthOutput(1, output.GetPointer()); +} + +template +EigenToMeasureParameterEstimationFilter:: + ~EigenToMeasureParameterEstimationFilter() +{} + +template +void +EigenToMeasureParameterEstimationFilter::ThreadedGenerateData( + const InputImageRegionType & region, + unsigned int streamNumber) +{ + /* If size is zero, return */ + if (region.GetSize(0) == 0) + { + return; + } + + /* Get input pointers */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); + + /* Iterate and count */ + inputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + m_Functor.ProcessPixel(inputIt.Get(), streamNumber); + } + ++inputIt; + } +} + +template +void +EigenToMeasureParameterEstimationFilter::UpdateOutputData( + DataObject * itkNotUsed(output)) +{ + /** Prevent chasing our tail */ + if (this->m_Updating) + { + return; + } + + /** Prepare all the outputs. This may deallocate previous bulk data. */ + this->PrepareOutputs(); + + /** Make sure we have the necessary inputs */ + const itk::ProcessObject::DataObjectPointerArraySizeType & ninputs = this->GetNumberOfValidRequiredInputs(); + if (ninputs < this->GetNumberOfRequiredInputs()) + { + itkExceptionMacro(<< "At least " << static_cast(this->GetNumberOfRequiredInputs()) + << " inputs are required but only " << ninputs << " are specified."); + return; + } + + /** + * Tell all Observers that the filter is starting, + * before emiting the 0.0 Progress event + */ + this->InvokeEvent(StartEvent()); + + this->SetAbortGenerateData(0); + this->UpdateProgress(0.0); + this->m_Updating = true; + + /** Allocate the output buffer. */ + OutputImageType * outputPtr = this->GetOutput(0); + const OutputImageRegionType outputRegion = outputPtr->GetRequestedRegion(); + outputPtr->SetBufferedRegion(outputRegion); + outputPtr->Allocate(); + + /** Grab the input */ + InputImageType * inputPtr = const_cast(this->GetInput(0)); + + /** + * Determine of number of pieces to divide the input. This will be the + * minimum of what the user specified via SetNumberOfStreamDivisions() + * and what the Splitter thinks is a reasonable value. + */ + unsigned int numDivisions, numDivisionsFromSplitter; + + numDivisions = this->GetNumberOfStreamDivisions(); + numDivisionsFromSplitter = + this->GetRegionSplitter()->GetNumberOfSplits(outputRegion, this->GetNumberOfStreamDivisions()); + if (numDivisionsFromSplitter < numDivisions) + { + numDivisions = numDivisionsFromSplitter; + } + + /* Tell the functor the number of times we will call it (potentially) */ + m_Functor.Initialize(this->GetNumberOfStreamDivisions() * this->GetNumberOfThreads()); + + /** + * Loop over the number of pieces, execute the upstream pipeline on each + * piece, and copy the results into the output image. + */ + for (unsigned int piece = 0; piece < numDivisions && !this->GetAbortGenerateData(); piece++) + { + /* Set the current peice */ + m_CurrentSplit = piece; + + /* Determine the split region and calculate the input */ + InputImageRegionType streamRegion = outputRegion; + this->GetRegionSplitter()->GetSplit(piece, numDivisions, streamRegion); + inputPtr->SetRequestedRegion(streamRegion); + inputPtr->PropagateRequestedRegion(); + inputPtr->UpdateOutputData(); + + /* Setup a multithreadign process */ + ThreadStruct str; + str.Filter = this; + + // Get the output pointer + const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); + const unsigned int validThreads = splitter->GetNumberOfSplits(streamRegion, this->GetNumberOfThreads()); + + this->GetMultiThreader()->SetNumberOfThreads(validThreads); + this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); + + // multithread the execution + this->GetMultiThreader()->SingleMethodExecute(); + + // copy the result to the proper place in the output. the input + // requested region determined by the RegionSplitter (as opposed + // to what the pipeline might have enlarged it to) is used to + // copy the regions from the input to output + if (inputPtr != outputPtr) + { + ImageAlgorithm::Copy(inputPtr, outputPtr, streamRegion, streamRegion); + } + + /* Update progress and stream another chunk */ + this->UpdateProgress(static_cast(piece) / static_cast(numDivisions)); + } + + /* Compute and set the parameters */ + this->GetParametersOutput()->Set(m_Functor.GetComputedParameters()); + + /** + * If we ended due to aborting, push the progress up to 1.0 + * (since it probably didn't end there) + */ + if (!this->GetAbortGenerateData()) + { + this->UpdateProgress(1.0); + } + + /** Notify end event observers */ + this->InvokeEvent(EndEvent()); + + /** Now we have to mark the data as up to data. */ + for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) + { + if (this->GetOutput(idx)) + { + this->GetOutput(idx)->DataHasBeenGenerated(); + } + } + + /** Release any inputs if marked for release */ + this->ReleaseInputs(); + + /** Mark that we are no longer updating the data in this filter */ + this->m_Updating = false; +} + +template +ITK_THREAD_RETURN_TYPE +EigenToMeasureParameterEstimationFilter::ThreaderCallback(void * arg) +{ + ThreadStruct * str; + ThreadIdType total, threadId, threadCount; + + threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; + threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads; + + str = (ThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData); + + // execute the actual method with appropriate output region + // first find out how many pieces extent can be split into. + typename OutputImageType::RegionType splitRegion; + total = str->Filter->SplitRequestedRegion(threadId, threadCount, splitRegion); + unsigned int streamNumber = str->Filter->m_CurrentSplit; + + if (threadId < total) + { + str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions() * threadId + streamNumber); + } + // else + // { + // otherwise don't use this thread. Sometimes the threads dont + // break up very well and it is just as efficient to leave a + // few threads idle. + // } + + return ITK_THREAD_RETURN_VALUE; +} + +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +const typename EigenToMeasureParameterEstimationFilter:: + ParameterDecoratedType * + EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +void +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace itk + +#endif // itkEigenToMeasureParameterEstimationFilter_hxx From 1f45ea387da6e4b58217303807973293bf3f239d Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 4 Feb 2018 01:50:18 -0700 Subject: [PATCH 056/150] ENH: Implemented DescoteauxEigenToMeasureParameterEstimationFilter --- ...xEigenToMeasureParameterEstimationFilter.h | 233 +++++++++++++++++ ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 141 ++++++++++ ...asureParameterEstimationFilterUnitTest.cxx | 242 ++++++++++++++++++ 3 files changed, 616 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..a0e76653916 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,233 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_h +#define itkDescoteauxEigenToMeasureParameterEstimationFilter_h + +#include "itkFixedArray.h" +#include "itkMath.h" +#include "itkEigenToMeasureParameterEstimationFilter.h" + +namespace itk +{ +namespace Functor +{ +/** \class DescoteauxEigenParameterFunctor + * \brief Automatic parameter estimation as defined by Descoteaux et al. + * + * The default parameters are: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 max\( Frobenius norm \) + * \f} + * + * Where the Frobenius norm for a real, symmetric matrix is given by + * the square root of the sum of squares of the eigenvalues. + * + * One can set FrobeniusNormWeight to control the weighting on the + * Frobenius norm. + * + * \sa DescoteauxEigentoScalarParameterEstimationImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenParameterFunctor +{ +public: + /* Basic type definitions */ + itkStaticConstMacro(NumberOfParameters, unsigned int, 3); + typedef typename TInputPixel::ValueType PixelValueType; + typedef typename NumericTraits::RealType RealType; + typedef FixedArray ParameterType; + + DescoteauxEigenParameterFunctor() + : m_FrobeniusNormWeight(0.5) + { + m_MaxFrobeniusNormArray.SetSize(0); + } + + void + Initialize(unsigned int numberOfCalls) + { + m_MaxFrobeniusNormArray.SetSize(numberOfCalls); + m_MaxFrobeniusNormArray.Fill(NumericTraits::ZeroValue()); + } + + void + ProcessPixel(const TInputPixel & inputPixel, unsigned int callNumber) + { + RealType norm = CalculateFrobeniusNorm(inputPixel); + if (norm > m_MaxFrobeniusNormArray[callNumber]) + { + m_MaxFrobeniusNormArray[callNumber] = norm; + } + } + + ParameterType + GetComputedParameters() + { + /* Alpha is 0.5 */ + m_Parameters[0] = 0.5; + + /* Beta is 0.5 */ + m_Parameters[1] = 0.5; + + /* C is m_FrobeniusNormWeight * max(frobenius norm) */ + m_Parameters[2] = 0; + for (unsigned int i = 0; i < m_MaxFrobeniusNormArray.GetSize(); ++i) + { + if (m_MaxFrobeniusNormArray[i] > m_Parameters[2]) + { + m_Parameters[2] = m_MaxFrobeniusNormArray[i]; + } + } + + /* Weight by the selection parmaeter */ + m_Parameters[2] = m_FrobeniusNormWeight * m_Parameters[2]; + + /* Finally, return the parameters we found */ + return m_Parameters; + } + + void + SetFrobeniusNormWeight(RealType weight) + { + m_FrobeniusNormWeight = weight; + } + + RealType + GetFrobeniusNormWeight() const + { + return m_FrobeniusNormWeight; + } + +private: + inline RealType + CalculateFrobeniusNorm(const TInputPixel & pixel) + { + /* Forbenius norm is given by the square root of the sum of squares + * of the eigenvalues for real, symmetric matricies + */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i] * pixel[i]; + } + return sqrt(norm); + } + + /* Private member variables */ + RealType m_FrobeniusNormWeight; + Array m_MaxFrobeniusNormArray; + ParameterType m_Parameters; +}; // end class +} // namespace Functor + +/** \class DescoteauxEigenToMeasureParameterEstimationFilter + * \brief Automatic parameter estimation as defined by Descoteaux et al. + * + * The default parameters are: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 max\( Frobenius norm \) + * \f} + * + * Where the Frobenius norm for a real, symmetric matrix is given by + * the square root of the sum of squares of the eigenvalues. + * + * If the input image and mask have different regions over which they + * are defined, parameters are estimated only in the intersection of + * the two image regions. However, the mask region must be a proper sub + * subset (contained) in the image region. + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter< + TInputImage, + TInputSpatialObject, + Functor::DescoteauxEigenParameterFunctor> +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter< + TInputImage, + TInputSpatialObject, + Functor::DescoteauxEigenParameterFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Functor typedef */ + typedef typename Superclass::FunctorType FunctorType; + typedef typename FunctorType::RealType RealType; + typedef typename FunctorType::ParameterType ParameterType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(DescoteauxEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); + + /** Define decorator types */ + typedef SimpleDataObjectDecorator InputParameterDecoratorType; + + /** setter/getter methods for setting type of object to enhance */ + void + SetFrobeniusNormWeight(RealType weight) + { + this->GetFunctor().SetFrobeniusNormWeight(weight); + } + RealType + GetFrobeniusNormWeight() const + { + return this->GetFunctor().GetFrobeniusNormWeight(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif + +protected: + DescoteauxEigenToMeasureParameterEstimationFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); + + void + PrintSelf(std::ostream & os, Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; + } +}; // end class +} // namespace itk + +#endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx new file mode 100644 index 00000000000..f71dd2a7eaa --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx @@ -0,0 +1,141 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Functor::DescoteauxEigenParameterFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureFunctorUnitTest() + { + m_Functor = FunctorType(); + m_EigenPixel = EigenValueArrayType(); + } + ~itkDescoteauxEigenToMeasureFunctorUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FunctorType m_Functor; + EigenValueArrayType m_EigenPixel; + ParameterType m_Parameters; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetFrobeniusNormWeight) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + this->m_Functor.SetFrobeniusNormWeight(0.1); + EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfZero) +{ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOne) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + this->m_Functor.SetFrobeniusNormWeight(0.1); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestMultiplePixels) +{ + unsigned int num = 10; + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(num); + for (unsigned int i = 0; i < num; ++i) + { + for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) + { + this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; + } + + this->m_Functor.ProcessPixel(this->m_EigenPixel, i); + } + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx new file mode 100644 index 00000000000..07913da2dda --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -0,0 +1,242 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::DescoteauxEigenToMeasureParameterEstimationFilter FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + m_LargeEigenPixel[i] = 100; + } + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + typename EigenImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(maskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + maskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex input(m_MaskingEigenImage, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, maskRegion); + + input.GoToBegin(); + maskIt.GoToBegin(); + while (!input.IsAtEnd()) + { + input.Set(m_LargeEigenPixel); + maskIt.Set(1); + ++input; + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_LargeEigenPixel; + ParameterType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Filter->GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImage) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImage) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageWithDifferentWeight) +{ + this->m_Filter->SetFrobeniusNormWeight(0.1); + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObject) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(86.6025403784, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} From d8c5fb500f9df45127f8657981debe541a880186 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:13:56 -0700 Subject: [PATCH 057/150] DOC: Fixed naming for DescoteauxEigenToMeasureParameterFunctor --- ...xEigenToMeasureParameterEstimationFilter.h | 11 +- ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 251 ++++++++++++++---- ...EigenToMeasureParameterFunctorUnitTest.cxx | 141 ++++++++++ 3 files changed, 340 insertions(+), 63 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index a0e76653916..b2f0f7d2705 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -27,7 +27,7 @@ namespace itk { namespace Functor { -/** \class DescoteauxEigenParameterFunctor +/** \class DescoteauxEigenToMeasureParameterFunctor * \brief Automatic parameter estimation as defined by Descoteaux et al. * * The default parameters are: @@ -49,7 +49,7 @@ namespace Functor * \ingroup BoneEnhancement */ template -class DescoteauxEigenParameterFunctor +class DescoteauxEigenToMeasureParameterFunctor { public: /* Basic type definitions */ @@ -58,7 +58,7 @@ class DescoteauxEigenParameterFunctor typedef typename NumericTraits::RealType RealType; typedef FixedArray ParameterType; - DescoteauxEigenParameterFunctor() + DescoteauxEigenToMeasureParameterFunctor() : m_FrobeniusNormWeight(0.5) { m_MaxFrobeniusNormArray.SetSize(0); @@ -169,7 +169,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject, - Functor::DescoteauxEigenParameterFunctor> + Functor::DescoteauxEigenToMeasureParameterFunctor> { public: /** Standard Self typedef */ @@ -177,7 +177,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter typedef EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject, - Functor::DescoteauxEigenParameterFunctor> + Functor::DescoteauxEigenToMeasureParameterFunctor> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; @@ -201,6 +201,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter SetFrobeniusNormWeight(RealType weight) { this->GetFunctor().SetFrobeniusNormWeight(weight); + this->Modified(); } RealType GetFrobeniusNormWeight() const diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx index f71dd2a7eaa..f30077f7e74 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx @@ -17,7 +17,7 @@ *=========================================================================*/ #include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" namespace { @@ -26,11 +26,13 @@ class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test { public: /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Functor::DescoteauxEigenParameterFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::Image ImageType; + typedef typename itk::Functor::DescoteauxEigenToMeasureFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; itkDescoteauxEigenToMeasureFunctorUnitTest() { @@ -54,88 +56,221 @@ class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +typedef ::testing::Types TestingLabelTypes; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) { - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetFrobeniusNormWeight) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetEnhanceType) { - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - this->m_Functor.SetFrobeniusNormWeight(0.1); - EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); + this->m_Functor.SetEnhanceDarkObjects(); + EXPECT_DOUBLE_EQ(1.0, this->m_Functor.GetEnhanceType()); + this->m_Functor.SetEnhanceBrightObjects(); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfZero) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetParameters) { + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); + + this->m_Parameters[0] = 100; + this->m_Parameters[1] = 200; + this->m_Parameters[2] = 300; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(100.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(200.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(300.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFirstParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ this->m_EigenPixel[0] = 0; this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFirstParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOne) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSecondParameterSet) { - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSecondParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightThirdParameterSet) { - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkThirdParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFourthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - this->m_Functor.SetFrobeniusNormWeight(0.1); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestMultiplePixels) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFourthParameterSet) { - unsigned int num = 10; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ this->m_EigenPixel[0] = 0; this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(num); - for (unsigned int i = 0; i < num; ++i) - { - for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) - { - this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; - } + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Functor.ProcessPixel(this->m_EigenPixel, i); - } +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFifthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFifthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSixthParameterSet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSixthParameterSet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); } diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx new file mode 100644 index 00000000000..c4583e6f8a3 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx @@ -0,0 +1,141 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureParameterFunctorUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Functor::DescoteauxEigenToMeasureParameterFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureParameterFunctorUnitTest() + { + m_Functor = FunctorType(); + m_EigenPixel = EigenValueArrayType(); + } + ~itkDescoteauxEigenToMeasureParameterFunctorUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FunctorType m_Functor; + EigenValueArrayType m_EigenPixel; + ParameterType m_Parameters; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, SetGetFrobeniusNormWeight) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + this->m_Functor.SetFrobeniusNormWeight(0.1); + EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfZero) +{ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOne) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + this->m_Functor.SetFrobeniusNormWeight(0.1); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestMultiplePixels) +{ + unsigned int num = 10; + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(num); + for (unsigned int i = 0; i < num; ++i) + { + for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) + { + this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; + } + + this->m_Functor.ProcessPixel(this->m_EigenPixel, i); + } + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +} From 45aedc7f94874a4d346e65cdb8b0a69e7be6785a Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:14:39 -0700 Subject: [PATCH 058/150] BUG: Fixed initialization bug in HessianGaussianImageFilter --- .../BoneEnhancement/include/itkHessianGaussianImageFilter.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index 36c0b3fe27f..df685bdae4e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -43,7 +43,7 @@ HessianGaussianImageFilter::HessianGaussianImageFilte m_ImageAdaptor = OutputImageAdaptorType::New(); // Setup defaults - this->SetNormalizeAcrossScale(true); + this->SetNormalizeAcrossScale(false); this->SetSigma(1.0); } From 4d59cc8cf824492dd58e452e28d085da8a9b9c4e Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:15:51 -0700 Subject: [PATCH 059/150] ENH: Added EigenToMeasureImageFilter and DescoteauxEigenToMeasureImageFilter --- .../itkDescoteauxEigenToMeasureImageFilter.h | 240 +++++++++++++ .../include/itkEigenToMeasureImageFilter.h | 167 +++++++++ .../include/itkEigenToMeasureImageFilter.hxx | 105 ++++++ .../BoneEnhancement/test/CMakeLists.txt | 80 +---- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 320 ++++++++++++++++++ 5 files changed, 841 insertions(+), 71 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h new file mode 100644 index 00000000000..edbaf6d48e6 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -0,0 +1,240 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureImageFilter_h +#define itkDescoteauxEigenToMeasureImageFilter_h + +#include "itkEigenToMeasureImageFilter.h" +#include "itkMath.h" + +namespace itk +{ +namespace Functor +{ +/** \class DescoteauxEigenToMeasureFunctor + * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. + * + * Computes the following equation for eigenvalues in a three + * dimensional fixed array: + * \f{eqnarray*}{ + * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ + * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ + * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ + * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) + * \f} + * + * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. + * + * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter + * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. + * + * \sa DescoteauxEigentoScalarParameterEstimationImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureFunctor +{ +public: + /* Basic type definitions */ + itkStaticConstMacro(NumberOfParameters, unsigned int, 3); + typedef typename TInputPixel::ValueType PixelValueType; + typedef typename NumericTraits::RealType RealType; + typedef FixedArray ParameterType; + + DescoteauxEigenToMeasureFunctor() + : m_Direction(-1.0) + , m_Alpha(0.0) + , m_Beta(0.0) + , m_C(0.0) + {} + + inline TOutputPixel + operator()(const TInputPixel & A) + { + double sheetness = 0.0; + double a1 = static_cast(A[0]); + double a2 = static_cast(A[1]); + double a3 = static_cast(A[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Deal with l3 > 0 */ + if (m_Direction * a3 < 0) + { + return static_cast(0.0); + } + + /* Avoid divisions by zero (or close to zero) */ + if (l3 < Math::eps) + { + return static_cast(0.0); + } + + /* Compute measures */ + const double Rsheet = l2 / l3; + const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; + const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); + + /* Multiply together to get sheetness */ + sheetness = 1.0; + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); + sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); + + return static_cast(sheetness); + } + + /** Macro definition for set/get of parameters */ + virtual void + SetParameters(const ParameterType parameters) + { + this->m_Alpha = parameters[0]; + this->m_Beta = parameters[1]; + this->m_C = parameters[2]; + } + + virtual ParameterType + GetParameters() const + { + ParameterType parameters; + parameters[0] = this->m_Alpha; + parameters[1] = this->m_Beta; + parameters[2] = this->m_C; + + return parameters; + } + + /** Set/get the type to enhance */ + void + SetEnhanceBrightObjects() + { + m_Direction = -1.0; + } + void + SetEnhanceDarkObjects() + { + m_Direction = 1.0; + } + RealType + GetEnhanceType() const + { + return m_Direction; + } + +private: + /* Private member variables */ + RealType m_Alpha; + RealType m_Beta; + RealType m_C; + RealType m_Direction; +}; // end class +} // namespace Functor + +/** \class DescoteauxEigenToMeasureImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. + * + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Descoteaux et al. The parameters of the filter should be set using + * DescoteauxEigentoScalarParameterEstimationImageFilter. + * + * See functor DescoteauxEigenToScalarFunctor for mathematics. + * + * \sa DescoteauxEigenToMeasureFunctor + * \sa DescoteauxEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureImageFilter + : public EigenToMeasureImageFilter< + TInputImage, + TOutputImage, + TInputSpatialObject, + Functor::DescoteauxEigenToMeasureFunctor> +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToMeasureImageFilter Self; + typedef EigenToMeasureImageFilter< + TInputImage, + TOutputImage, + TInputSpatialObject, + Functor::DescoteauxEigenToMeasureFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Functor typedef */ + typedef typename Superclass::FunctorType FunctorType; + typedef typename FunctorType::RealType RealType; + typedef typename FunctorType::ParameterType ParameterType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(DescoteauxEigenToMeasureImageFilter, EigenToMeasureImageFilter); + + /** setter/getter methods for setting type of object to enhance */ + void + SetEnhanceBrightObjects() + { + this->GetFunctor().SetEnhanceBrightObjects(); + this->Modified(); + } + void + SetEnhanceDarkObjects() + { + this->GetFunctor().SetEnhanceDarkObjects(); + this->Modified(); + } + RealType + GetEnhanceType() const + { + return this->GetFunctor().GetEnhanceType(); + } + + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif + +protected: + DescoteauxEigenToMeasureImageFilter() {} + virtual ~DescoteauxEigenToMeasureImageFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); +}; // end class +} /* end namespace itk */ + +#endif /* itkDescoteauxEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h new file mode 100644 index 00000000000..0ac86321f27 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -0,0 +1,167 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureImageFilter_h +#define itkEigenToMeasureImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkSpatialObject.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace itk +{ +/** \class EigenToMeasureImageFilter + * \brief Abstract class for computing a measure from local structure. + * + * TODO + * + * This is an abstract class that estimates parameters for local-structure enhancement + * from eigen-images. Other classes should inherit from this class so they can be used + * in the MultiScaleHessianEnhancementImageFilter framework. + * + * To estimate the parameters for local-structure enhancement, every pixel in the input + * image must be seen. To implement this functionality in a memory efficinet way, this + * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by + * restricting the output image region. + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa UnaryFunctorImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef EigenToMeasureImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EigenToMeasureImageFilter, ImageToImageFilter); + + /** Input Image typedefs. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Output image typedefs. */ + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointer; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef TInputSpatialObject SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Functor typedefs. */ + typedef TFunction FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + typedef typename ParameterType::ValueType ParameterValueType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; + itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); + + /** Get the functor object. The functor is returned by reference. + * (Functors do not have to derive from itk::LightObject, so they do + * not necessarily have a reference count. So we cannot return a + * SmartPointer.) */ + FunctorType & + GetFunctor() + { + return m_Functor; + } + const FunctorType & + GetFunctor() const + { + return m_Functor; + } + + /** Set the functor object. This replaces the current Functor with a + * copy of the specified Functor. This allows the user to specify a + * functor that has ivars set differently than the default functor. + * This method requires the following to be defined: + * Initialize() + * ProcessPixel() + * GetComputedParameters() + */ + void + SetFunctor(const FunctorType & functor) + { + if (m_Functor != functor) + { + m_Functor = functor; + this->Modified(); + } + } + + /** Process object */ + itkSetGetDecoratedInputMacro(Parameters, ParameterType); + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + + /** Template the EigenValueOrderType. Methods that inherit from this class can override this function + * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from + * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial + * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type + * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. + */ + typedef enum + { + OrderByValue = 1, + OrderByMagnitude, + DoNotOrder + } EigenValueOrderType; + virtual EigenValueOrderType + GetEigenValueOrder() const = 0; + +protected: + EigenToMeasureImageFilter(); + virtual ~EigenToMeasureImageFilter() ITK_OVERRIDE; + + /** Need to access the input parameters at execution time */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); + + /* Private data members. */ + ParameterType m_Parameters; + FunctorType m_Functor; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkEigenToMeasureImageFilter.hxx" +#endif + +#endif /* itkEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx new file mode 100644 index 00000000000..59e8d464298 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx @@ -0,0 +1,105 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureImageFilter_hxx +#define itkEigenToMeasureImageFilter_hxx + +#include "itkEigenToMeasureImageFilter.h" +#include "itkProgressReporter.h" +#include "itkNumericTraits.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkImageRegionIterator.h" + +namespace itk +{ + +template +EigenToMeasureImageFilter::EigenToMeasureImageFilter() +{ + this->SetNumberOfRequiredInputs(1); +} + +template +EigenToMeasureImageFilter::~EigenToMeasureImageFilter() +{} + +template +void +EigenToMeasureImageFilter::BeforeThreadedGenerateData() + ITK_OVERRIDE +{ + /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ + this->GetFunctor().SetParameters(this->GetParametersInput()->Get()); +} + +template +void +EigenToMeasureImageFilter::ThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + InputImageConstPointer inputPtr = this->GetInput(); + OutputImagePointer outputPtr = this->GetOutput(0); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + // Define the iterators + ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + inputIt.GoToBegin(); + outputIt.GoToBegin(); + + while (!inputIt.IsAtEnd()) + { + inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + outputIt.Set(m_Functor(inputIt.Get())); + } + else + { + outputIt.Set(NumericTraits::Zero); + } + ++inputIt; + ++outputIt; + progress.CompletedPixel(); // potential exception thrown here + } +} + +template +void +EigenToMeasureImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "m_Parameters: " << this->GetParametersInput() << std::endl; +} + +} /* end namespace itk */ + +#endif /* itkEigenToMeasureImageFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 275cc927636..80fec36e66d 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -4,15 +4,6 @@ set( BoneEnhancementTests itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx - itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx - itkKrcahEigenToScalarFunctorTest.cxx - itkKrcahEigenToScalarFunctorImageFilterTest.cxx - itkKrcahEigenToScalarImageFilterTest.cxx - itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx - itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx - itkDescoteauxEigenToScalarFunctorTest.cxx - itkDescoteauxEigenToScalarFunctorImageTest.cxx - itkDescoteauxEigenToScalarImageFilterTest.cxx itkHessianGaussianImageFilterTest.cxx ) @@ -33,71 +24,18 @@ itk_add_test( ) itk_add_test( - NAME itkKrcahEigenToScalarParameterEstimationImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarParameterEstimationImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarFunctorTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarFunctorTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarFunctorImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarFunctorImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarPreprocessingImageToImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarPreprocessingImageToImageFilterTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarParameterEstimationImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarParameterEstimationImageFilterTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarFunctorTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarFunctorTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarFunctorImageTest + NAME itkHessianGaussianImageFilterTest COMMAND BoneEnhancementTestDriver - itkDescoteauxEigenToScalarFunctorImageTest + itkHessianGaussianImageFilterTest ) -itk_add_test( - NAME itkDescoteauxEigenToScalarImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarImageFilterTest +set( + BoneEnhancementUnitTests + itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx + itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx + itkDescoteauxEigenToMeasureFunctorUnitTest.cxx + itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx ) -itk_add_test( - NAME itkHessianGaussianImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkHessianGaussianImageFilterTest -) +creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx new file mode 100644 index 00000000000..78bb12a4925 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -0,0 +1,320 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::Image OutputPixelType; + typedef float EigenPixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::DescoteauxEigenToMeasureImageFilter + FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureImageFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + } + m_NonZeroEigenPixel[0] = 0.25; + m_NonZeroEigenPixel[1] = 1; + m_NonZeroEigenPixel[2] = -1; + m_NonZeroDarkEigenPixel[0] = 0.25; + m_NonZeroDarkEigenPixel[1] = 1; + m_NonZeroDarkEigenPixel[2] = 1; + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_NonZeroEigenImage = EigenImageType::New(); + m_NonZeroEigenImage->SetRegions(m_Region); + m_NonZeroEigenImage->Allocate(); + m_NonZeroEigenImage->FillBuffer(m_NonZeroEigenPixel); + + m_NonZeroDarkEigenImage = EigenImageType::New(); + m_NonZeroDarkEigenImage->SetRegions(m_Region); + m_NonZeroDarkEigenImage->Allocate(); + m_NonZeroDarkEigenImage->FillBuffer(m_NonZeroDarkEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + m_MaskRegion.SetSize(maskSize); + m_MaskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(m_MaskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + m_MaskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, m_MaskRegion); + + maskIt.GoToBegin(); + while (!maskIt.IsAtEnd()) + { + maskIt.Set(1); + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkDescoteauxEigenToMeasureImageFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_NonZeroEigenImage; + typename EigenImageType::Pointer m_NonZeroDarkEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_NonZeroEigenPixel; + EigenValueArrayType m_NonZeroDarkEigenPixel; + ParameterType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename EigenImageType::RegionType m_MaskRegion; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, InitialParameters) +{ + /* Default enhance bright structures */ + EXPECT_DOUBLE_EQ(-1.0, this->m_Filter->GetEnhanceType()); + + EXPECT_EQ(2, this->m_Filter->GetEigenValueOrder()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestZerosImage) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 1; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_ZerosEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_EQ(0.0, input.Get()); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelBrightSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0913983433747, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelDarkSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->SetEnhanceDarkObjects(); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixelBrightSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixelDarkSheet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); + this->m_Filter->SetEnhanceDarkObjects(); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.000326373962098, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + itk::ContinuousIndex point; + + std::cout << this->m_MaskRegion << std::endl; + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + this->m_Filter->GetOutput()->TransformIndexToPhysicalPoint(input.GetIndex(), point); + if (this->m_MaskRegion.IsInside(point)) + { + ASSERT_NEAR((TypeParam)0.0913983433747, input.Get(), 1e-6); + } + else + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + } + ++input; + } +} From 7f7b88e624f6ff495b00a311e3c9a3055c4a9618 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:16:23 -0700 Subject: [PATCH 060/150] DOC: Added documentation to MaximumAbsoluteValue Functor --- .../include/itkMaximumAbsoluteValueImageFilter.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 4748705a1c1..c7333b35b48 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -26,6 +26,19 @@ namespace itk { namespace Functor { +/** \class MaximumAbsoluteValue + * \brief Compute the maximum (of the absolute value) between two images. + * + * This class takes two images as arguments and returns the maximum + * of the absolute value pixel wise. For instance, two pixels with + * values 2 and -3 would return -3, since the absolute value of -3 + * is larger than 2. + * + * \sa MultiScaleHessianEnhancementImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ template class MaximumAbsoluteValue { From a039b1ac552bff00d771695dd0db4c6b09b7dd30 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 7 Feb 2018 17:41:23 -0700 Subject: [PATCH 061/150] ENH: Added ITKReview --- Modules/Filtering/BoneEnhancement/itk-module.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/itk-module.cmake b/Modules/Filtering/BoneEnhancement/itk-module.cmake index 73719fc4f24..511c4ba5f46 100644 --- a/Modules/Filtering/BoneEnhancement/itk-module.cmake +++ b/Modules/Filtering/BoneEnhancement/itk-module.cmake @@ -15,6 +15,8 @@ itk_module( ITKStatistics ITKImageFilterBase ITKImageFeature + ITKReview + ITKSpatialObjects COMPILE_DEPENDS ITKImageSources TEST_DEPENDS From d415dac96b883c4b672932433593f6d3c655a124 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 28 Feb 2018 15:24:06 -0700 Subject: [PATCH 062/150] ENH: Descoteaux implementation --- .../itkDescoteauxEigenToMeasureImageFilter.h | 231 ++++--------- ...tkDescoteauxEigenToMeasureImageFilter.hxx} | 102 ++++-- ...xEigenToMeasureParameterEstimationFilter.h | 225 ++++--------- ...igenToMeasureParameterEstimationFilter.hxx | 182 +++++++++++ ...escoteauxEigenToScalarFunctorImageFilter.h | 260 --------------- .../itkDescoteauxEigenToScalarImageFilter.h | 199 ----------- .../itkDescoteauxEigenToScalarImageFilter.hxx | 101 ------ ...enToScalarParameterEstimationImageFilter.h | 190 ----------- ...ToScalarParameterEstimationImageFilter.hxx | 266 --------------- .../include/itkEigenToMeasureImageFilter.h | 95 ++---- ...kEigenToMeasureParameterEstimationFilter.h | 86 ++--- ...igenToMeasureParameterEstimationFilter.hxx | 202 +++++------- .../include/itkEigenToScalarImageFilter.h | 89 ----- .../include/itkHessianGaussianImageFilter.hxx | 7 +- .../itkKrcahEigenToScalarFunctorImageFilter.h | 251 -------------- .../itkKrcahEigenToScalarImageFilter.h | 212 ------------ .../itkKrcahEigenToScalarImageFilter.hxx | 99 ------ ...enToScalarParameterEstimationImageFilter.h | 239 -------------- ...ToScalarParameterEstimationImageFilter.hxx | 309 ------------------ ...nToScalarPreprocessingImageToImageFilter.h | 146 --------- ...oScalarPreprocessingImageToImageFilter.hxx | 193 ----------- .../itkMaximumAbsoluteValueImageFilter.h | 2 +- ...kMultiScaleHessianEnhancementImageFilter.h | 89 +++-- ...ultiScaleHessianEnhancementImageFilter.hxx | 153 +++++++-- .../BoneEnhancement/test/CMakeLists.txt | 2 - ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 276 ---------------- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 16 +- ...asureParameterEstimationFilterUnitTest.cxx | 14 +- ...EigenToMeasureParameterFunctorUnitTest.cxx | 141 -------- ...escoteauxEigenToScalarFunctorImageTest.cxx | 121 ------- .../itkDescoteauxEigenToScalarFunctorTest.cxx | 121 ------- ...DescoteauxEigenToScalarImageFilterTest.cxx | 94 ------ ...alarParameterEstimationImageFilterTest.cxx | 170 ---------- .../test/itkKrcahEigenToScalarFunctorTest.cxx | 155 --------- ...larPreprocessingImageToImageFilterTest.cxx | 43 --- ...itkDescoteauxEigenToScalarImageFilter.wrap | 13 - .../wrapping/itkEigenToScalarImageFilter.wrap | 11 - .../itkKrcahEigenToScalarImageFilter.wrap | 22 -- ...ScalarPreprocessingImageToImageFilter.wrap | 3 - 39 files changed, 711 insertions(+), 4419 deletions(-) rename Modules/Filtering/BoneEnhancement/include/{itkEigenToMeasureImageFilter.hxx => itkDescoteauxEigenToMeasureImageFilter.hxx} (50%) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index edbaf6d48e6..04d79a467c3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -24,13 +24,14 @@ namespace itk { -namespace Functor -{ -/** \class DescoteauxEigenToMeasureFunctor - * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. +/** \class DescoteauxEigenToMeasureImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Descoteaux et al. The parameters of the filter should be set using + * DescoteauxEigentoScalarParameterEstimationImageFilter. + * + * Computes the following equation for eigenvalues in a three dimensional fixed array: * \f{eqnarray*}{ * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ @@ -41,153 +42,45 @@ namespace Functor * * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. * - * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter - * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToMeasureFunctor -{ -public: - /* Basic type definitions */ - itkStaticConstMacro(NumberOfParameters, unsigned int, 3); - typedef typename TInputPixel::ValueType PixelValueType; - typedef typename NumericTraits::RealType RealType; - typedef FixedArray ParameterType; - - DescoteauxEigenToMeasureFunctor() - : m_Direction(-1.0) - , m_Alpha(0.0) - , m_Beta(0.0) - , m_C(0.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Deal with l3 > 0 */ - if (m_Direction * a3 < 0) - { - return static_cast(0.0); - } - - /* Avoid divisions by zero (or close to zero) */ - if (l3 < Math::eps) - { - return static_cast(0.0); - } - - /* Compute measures */ - const double Rsheet = l2 / l3; - const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); - - /* Multiply together to get sheetness */ - sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetParameters(const ParameterType parameters) - { - this->m_Alpha = parameters[0]; - this->m_Beta = parameters[1]; - this->m_C = parameters[2]; - } - - virtual ParameterType - GetParameters() const - { - ParameterType parameters; - parameters[0] = this->m_Alpha; - parameters[1] = this->m_Beta; - parameters[2] = this->m_C; - - return parameters; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_C; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class DescoteauxEigenToMeasureImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Descoteaux et al. The parameters of the filter should be set using - * DescoteauxEigentoScalarParameterEstimationImageFilter. - * - * See functor DescoteauxEigenToScalarFunctor for mathematics. - * - * \sa DescoteauxEigenToMeasureFunctor - * \sa DescoteauxEigenToScalarImageFilter + * \sa DescoteauxEigenToMeasureParameterEstimationFilter + * \sa EigenToMeasureImageFilter + * \sa MultiScaleHessianEnhancementImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ template class DescoteauxEigenToMeasureImageFilter - : public EigenToMeasureImageFilter< - TInputImage, - TOutputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureFunctor> + : public EigenToMeasureImageFilter { public: /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureImageFilter Self; - typedef EigenToMeasureImageFilter< - TInputImage, - TOutputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Functor typedef */ - typedef typename Superclass::FunctorType FunctorType; - typedef typename FunctorType::RealType RealType; - typedef typename FunctorType::ParameterType ParameterType; + typedef DescoteauxEigenToMeasureImageFilter Self; + typedef EigenToMeasureImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImagePointer OutputImagePointer; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -195,46 +88,58 @@ class DescoteauxEigenToMeasureImageFilter /** Runtime information support. */ itkTypeMacro(DescoteauxEigenToMeasureImageFilter, EigenToMeasureImageFilter); - /** setter/getter methods for setting type of object to enhance */ + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + + /** Setter/Getter methods for setting Direction */ + itkSetMacro(EnhanceType, RealType); + itkGetConstMacro(EnhanceType, RealType); void SetEnhanceBrightObjects() { - this->GetFunctor().SetEnhanceBrightObjects(); - this->Modified(); + SetEnhanceType(-1.0); } void SetEnhanceDarkObjects() { - this->GetFunctor().SetEnhanceDarkObjects(); - this->Modified(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE - { - return Superclass::OrderByMagnitude; + SetEnhanceType(1.0); } #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); // End concept checking #endif - protected: - DescoteauxEigenToMeasureImageFilter() {} + DescoteauxEigenToMeasureImageFilter(); virtual ~DescoteauxEigenToMeasureImageFilter() {} + inline OutputImagePixelType + ProcessPixel(const InputImagePixelType & pixel, RealType alpha, RealType beta, RealType c); + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); + + /* Member variables */ + RealType m_EnhanceType; }; // end class } /* end namespace itk */ +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToMeasureImageFilter.hxx" +#endif + #endif /* itkDescoteauxEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx similarity index 50% rename from Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx rename to Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index 59e8d464298..ff7239d8941 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -16,48 +16,42 @@ * *=========================================================================*/ -#ifndef itkEigenToMeasureImageFilter_hxx -#define itkEigenToMeasureImageFilter_hxx +#ifndef itkDescoteauxEigenToMeasureImageFilter_hxx +#define itkDescoteauxEigenToMeasureImageFilter_hxx -#include "itkEigenToMeasureImageFilter.h" -#include "itkProgressReporter.h" -#include "itkNumericTraits.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" +#include "itkProgressReporter.h" namespace itk { - -template -EigenToMeasureImageFilter::EigenToMeasureImageFilter() -{ - this->SetNumberOfRequiredInputs(1); -} - -template -EigenToMeasureImageFilter::~EigenToMeasureImageFilter() +template +DescoteauxEigenToMeasureImageFilter:: + DescoteauxEigenToMeasureImageFilter() + : Superclass() + , m_EnhanceType(-1.0) {} -template +template void -EigenToMeasureImageFilter::BeforeThreadedGenerateData() - ITK_OVERRIDE -{ - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetParameters(this->GetParametersInput()->Get()); -} - -template -void -EigenToMeasureImageFilter::ThreadedGenerateData( +DescoteauxEigenToMeasureImageFilter::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) { - InputImageConstPointer inputPtr = this->GetInput(); + /* Get Inputs */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); + InputImageConstPointer inputPtr = this->GetInput(0); OutputImagePointer outputPtr = this->GetOutput(0); SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); typename InputImageType::PointType point; + /* Test parameters */ + if (parameters.GetSize() != 3) + { + itkExceptionMacro(<< "Parameters must have size 3. Given array of size " << parameters.GetSize()); + } + // Define the portion of the input to walk for this thread, using // the CallCopyOutputRegionToInputRegion method allows for the input // and output images to be different dimensions @@ -79,7 +73,7 @@ EigenToMeasureImageFilterTransformIndexToPhysicalPoint(inputIt.GetIndex(), point); if ((!maskPointer) || (maskPointer->IsInside(point))) { - outputIt.Set(m_Functor(inputIt.Get())); + outputIt.Set(ProcessPixel(inputIt.Get(), parameters[0], parameters[1], parameters[2])); } else { @@ -91,15 +85,57 @@ EigenToMeasureImageFilter +template +typename DescoteauxEigenToMeasureImageFilter::OutputImagePixelType +DescoteauxEigenToMeasureImageFilter::ProcessPixel( + const InputImagePixelType & pixel, + RealType alpha, + RealType beta, + RealType c) +{ + double sheetness = 0.0; + double a1 = static_cast(pixel[0]); + double a2 = static_cast(pixel[1]); + double a3 = static_cast(pixel[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Deal with l3 > 0 */ + if (m_EnhanceType * a3 < 0) + { + return static_cast(0.0); + } + + /* Avoid divisions by zero (or close to zero) */ + if (l3 < Math::eps) + { + return static_cast(0.0); + } + + /* Compute measures */ + const double Rsheet = l2 / l3; + const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; + const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); + + /* Multiply together to get sheetness */ + sheetness = 1.0; + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * alpha * alpha)); + sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * beta * beta))); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * c * c))); + + return static_cast(sheetness); +} + +template void -EigenToMeasureImageFilter::PrintSelf(std::ostream & os, - Indent indent) const +DescoteauxEigenToMeasureImageFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "m_Parameters: " << this->GetParametersInput() << std::endl; + os << indent << "Direction: " << GetEnhanceType() << std::endl; } -} /* end namespace itk */ +} // namespace itk -#endif /* itkEigenToMeasureImageFilter_hxx */ +#endif /* itkDescoteauxEigenToMeasureImageFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index b2f0f7d2705..9db48a766c8 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -19,128 +19,11 @@ #ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_h #define itkDescoteauxEigenToMeasureParameterEstimationFilter_h -#include "itkFixedArray.h" #include "itkMath.h" #include "itkEigenToMeasureParameterEstimationFilter.h" namespace itk { -namespace Functor -{ -/** \class DescoteauxEigenToMeasureParameterFunctor - * \brief Automatic parameter estimation as defined by Descoteaux et al. - * - * The default parameters are: - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.5 max\( Frobenius norm \) - * \f} - * - * Where the Frobenius norm for a real, symmetric matrix is given by - * the square root of the sum of squares of the eigenvalues. - * - * One can set FrobeniusNormWeight to control the weighting on the - * Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToMeasureParameterFunctor -{ -public: - /* Basic type definitions */ - itkStaticConstMacro(NumberOfParameters, unsigned int, 3); - typedef typename TInputPixel::ValueType PixelValueType; - typedef typename NumericTraits::RealType RealType; - typedef FixedArray ParameterType; - - DescoteauxEigenToMeasureParameterFunctor() - : m_FrobeniusNormWeight(0.5) - { - m_MaxFrobeniusNormArray.SetSize(0); - } - - void - Initialize(unsigned int numberOfCalls) - { - m_MaxFrobeniusNormArray.SetSize(numberOfCalls); - m_MaxFrobeniusNormArray.Fill(NumericTraits::ZeroValue()); - } - - void - ProcessPixel(const TInputPixel & inputPixel, unsigned int callNumber) - { - RealType norm = CalculateFrobeniusNorm(inputPixel); - if (norm > m_MaxFrobeniusNormArray[callNumber]) - { - m_MaxFrobeniusNormArray[callNumber] = norm; - } - } - - ParameterType - GetComputedParameters() - { - /* Alpha is 0.5 */ - m_Parameters[0] = 0.5; - - /* Beta is 0.5 */ - m_Parameters[1] = 0.5; - - /* C is m_FrobeniusNormWeight * max(frobenius norm) */ - m_Parameters[2] = 0; - for (unsigned int i = 0; i < m_MaxFrobeniusNormArray.GetSize(); ++i) - { - if (m_MaxFrobeniusNormArray[i] > m_Parameters[2]) - { - m_Parameters[2] = m_MaxFrobeniusNormArray[i]; - } - } - - /* Weight by the selection parmaeter */ - m_Parameters[2] = m_FrobeniusNormWeight * m_Parameters[2]; - - /* Finally, return the parameters we found */ - return m_Parameters; - } - - void - SetFrobeniusNormWeight(RealType weight) - { - m_FrobeniusNormWeight = weight; - } - - RealType - GetFrobeniusNormWeight() const - { - return m_FrobeniusNormWeight; - } - -private: - inline RealType - CalculateFrobeniusNorm(const TInputPixel & pixel) - { - /* Forbenius norm is given by the square root of the sum of squares - * of the eigenvalues for real, symmetric matricies - */ - RealType norm = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - norm += pixel[i] * pixel[i]; - } - return sqrt(norm); - } - - /* Private member variables */ - RealType m_FrobeniusNormWeight; - Array m_MaxFrobeniusNormArray; - ParameterType m_Parameters; -}; // end class -} // namespace Functor - /** \class DescoteauxEigenToMeasureParameterEstimationFilter * \brief Automatic parameter estimation as defined by Descoteaux et al. * @@ -154,38 +37,49 @@ class DescoteauxEigenToMeasureParameterFunctor * Where the Frobenius norm for a real, symmetric matrix is given by * the square root of the sum of squares of the eigenvalues. * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. + * The parameters are estimated over the whole volume unless a mask is given. + * If a mask is given, parameters are evaluated only where IsInside returns + * true. * - * \sa KrcahEigenToScalarImageFilter + * \sa DescoteauxEigenToMeasureImageFilter + * \sa EigenToMeasureParameterEstimationFilter + * \sa MultiScaleHessianEnhancementImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ template class DescoteauxEigenToMeasureParameterEstimationFilter - : public EigenToMeasureParameterEstimationFilter< - TInputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureParameterFunctor> + : public EigenToMeasureParameterEstimationFilter { public: /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; - typedef EigenToMeasureParameterEstimationFilter< - TInputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureParameterFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Functor typedef */ - typedef typename Superclass::FunctorType FunctorType; - typedef typename FunctorType::RealType RealType; - typedef typename FunctorType::ParameterType ParameterType; + typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::PixelValueType PixelValueType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -193,21 +87,9 @@ class DescoteauxEigenToMeasureParameterEstimationFilter /** Runtime information support. */ itkTypeMacro(DescoteauxEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); - /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; - - /** setter/getter methods for setting type of object to enhance */ - void - SetFrobeniusNormWeight(RealType weight) - { - this->GetFunctor().SetFrobeniusNormWeight(weight); - this->Modified(); - } - RealType - GetFrobeniusNormWeight() const - { - return this->GetFunctor().GetFrobeniusNormWeight(); - } + /** Setter/Getter methods for setting FrobeniusNormWeight */ + itkSetMacro(FrobeniusNormWeight, RealType); + itkGetConstMacro(FrobeniusNormWeight, RealType); #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking @@ -215,20 +97,39 @@ class DescoteauxEigenToMeasureParameterEstimationFilter itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); // End concept checking #endif - protected: - DescoteauxEigenToMeasureParameterEstimationFilter() {} + DescoteauxEigenToMeasureParameterEstimationFilter(); + virtual ~DescoteauxEigenToMeasureParameterEstimationFilter() {} + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + inline RealType + CalculateFrobeniusNorm(const InputImagePixelType & pixel) const; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; - } + /* Member variables */ + RealType m_FrobeniusNormWeight; + Array m_MaxFrobeniusNorm; }; // end class } // namespace itk +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx" +#endif + #endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..5ef31795fd3 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,182 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx +#define itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx + +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace itk +{ + +template +DescoteauxEigenToMeasureParameterEstimationFilter:: + DescoteauxEigenToMeasureParameterEstimationFilter() + : Superclass() + , m_FrobeniusNormWeight(0.5) +{ + /* Set parameter size to 3 */ + ParameterArrayType parameters = this->GetParametersOutput()->Get(); + parameters.SetSize(3); + parameters[0] = 0.5; + parameters[1] = 0.5; + parameters[2] = 1; + this->GetParametersOutput()->Set(parameters); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +{ + ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); + + /* Resize threads */ + m_MaxFrobeniusNorm.SetSize(numberOfCalls); + m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +{ + ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); + + /* Determine default parameters */ + RealType alpha, beta, c; + alpha = 0.5f; + beta = 0.5f; + c = 0.0f; + + /* Accumulate over threads */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + + for (unsigned int i = 0; i < numberOfCalls; ++i) + { + if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) + { + maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; + } + } + + /* Scale c */ + if (maxFrobeniusNorm > 0) + { + c = m_FrobeniusNormWeight * maxFrobeniusNorm; + } + + /* Assign outputs parameters */ + ParameterArrayType parameters; + parameters.SetSize(3); + parameters[0] = alpha; + parameters[1] = beta; + parameters[2] = c; + this->GetParametersOutput()->Set(parameters); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::ThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + /* If size is zero, return */ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Count starts zero */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + RealType thisFrobeniusNorm; + + /* Get input and mask pointer */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + OutputImageType * outputPtr = this->GetOutput(0); + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + outputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + /* Compute max norm */ + thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); + if (thisFrobeniusNorm > maxFrobeniusNorm) + { + maxFrobeniusNorm = thisFrobeniusNorm; + } + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + /* Store this thread */ + m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; +} + +template +typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType +DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( + const InputImagePixelType & pixel) const +{ + /* Forbenius norm is given by the square root of the sum of squares + * of the eigenvalues for real, symmetric matricies + */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i] * pixel[i]; + } + return sqrt(norm); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; +} + +} // namespace itk + +#endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h deleted file mode 100644 index cbfa81ce46b..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,260 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarFunctorImageFilter_h -#define itkDescoteauxEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class DescoteauxEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ - * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ - * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) - * \f} - * - * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. - * - * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter - * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - typedef typename NumericTraits::RealType RealType; - - DescoteauxEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Deal with l3 > 0 */ - if (m_Direction * a3 < 0) - { - return static_cast(0.0); - } - - /* Avoid divisions by zero (or close to zero) */ - if (l3 < Math::eps) - { - return static_cast(0.0); - } - - /* Compute measures */ - const double Rsheet = l2 / l3; - const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); - - /* Multiply together to get sheetness */ - sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetC(const RealType c) - { - this->m_C = c; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetC() const - { - return this->m_C; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_C; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class DescoteauxEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Descoteaux et al. The parameters of the filter should be set using - * DescoteauxEigentoScalarParameterEstimationImageFilter. - * - * See functor DescoteauxEigenToScalarFunctor for mathematics. - * - * \sa DescoteauxEigenToScalarFunctor - * \sa DescoteauxEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor> -{ -public: - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarFunctorImageFilter Self; - typedef UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Useful typedefs for numerics */ - typedef - typename Functor::DescoteauxEigenToScalarFunctor - DescoteauxFunctorType; - typedef typename DescoteauxFunctorType::RealType RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(C, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetC(this->GetCInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - DescoteauxEigenToScalarFunctorImageFilter() {} - virtual ~DescoteauxEigenToScalarFunctorImageFilter() {} - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); - - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "C: " << GetC() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkDescoteauxEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h deleted file mode 100644 index 8046fd1a673..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ /dev/null @@ -1,199 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarImageFilter_h -#define itkDescoteauxEigenToScalarImageFilter_h - -#include "itkEigenToScalarImageFilter.h" -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" - -namespace itk -{ -/** \class DescoteauxEigenToScalarImageFilter - * \brief Compute the Descoteaux sheetness measure from the eigenvalues - * - * This is a convenience class implementing the EigenToScalarImageFilter - * abstract class. This class computes the Descoteaux sheetness measure for - * cortical bone. Internally, DescoteauxEigenToScalarParameterEstimationImageFilter - * and DescoteauxEigenToScalarFunctorImageFilter are used for automatic parameter - * estimation and implementation of the functor. - * - * Before passing an input to MultiScaleHessianEnhancementImageFilter, - * the DescoteauxEigenToScalarPreprocessingImageToImageFilter should be used. - * - * \sa MultiScaleHessianEnhancementImageFilter - * \sa EigenToScalarImageFilter - * \sa DescoteauxEigenToScalarParameterEstimationImageFilter - * \sa DescoteauxEigenToScalarFunctorImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template > -class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter - : public EigenToScalarImageFilter -{ -public: - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarImageFilter Self; - typedef EigenToScalarImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - - /** Useful template typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - - /** Procesing filters */ - typedef DescoteauxEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; - typedef DescoteauxEigenToScalarFunctorImageFilter UnaryFunctorFilterType; - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE - { - return Superclass::OrderByMagnitude; - } - - /** Methods to set/get the mask image */ - void - SetMaskImage(const TMaskImage * mask) - { - this->m_ParameterEstimationFilter->SetMaskImage(mask); - this->Modified(); - } - virtual const TMaskImage * - GetMaskImage() const - { - return this->m_ParameterEstimationFilter->GetMaskImage(); - } - - /** Methods to set/get the background value */ - virtual void - SetBackgroundValue(const MaskPixelType back) - { - this->m_ParameterEstimationFilter->SetBackgroundValue(back); - this->Modified(); - } - virtual MaskPixelType - GetBackgroundValue() const - { - return this->m_ParameterEstimationFilter->GetBackgroundValue(); - } - - /** Methods to set/get the FrobeniusNormWeight */ - virtual void - SetFrobeniusNormWeight(const typename ParameterEstimationFilterType::RealType weight) - { - this->m_ParameterEstimationFilter->SetFrobeniusNormWeight(weight); - this->Modified(); - } - typename ParameterEstimationFilterType::RealType - GetFrobeniusNormWeight() const - { - return this->m_ParameterEstimationFilter->GetFrobeniusNormWeight(); - } - - /** Methods to get the computed parameters */ - typename UnaryFunctorFilterType::RealType - GetAlpha() const - { - return m_UnaryFunctorFilter->GetAlpha(); - } - typename UnaryFunctorFilterType::RealType - GetBeta() const - { - return m_UnaryFunctorFilter->GetBeta(); - } - typename UnaryFunctorFilterType::RealType - GetC() const - { - return m_UnaryFunctorFilter->GetC(); - } - - /** Methods to set/get the enhancment method */ - void - SetEnhanceBrightObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); - this->Modified(); - } - void - SetEnhanceDarkObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); - this->Modified(); - } - typename UnaryFunctorFilterType::RealType - GetEnhanceType() const - { - return this->m_UnaryFunctorFilter->GetEnhanceType(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - DescoteauxEigenToScalarImageFilter(); - virtual ~DescoteauxEigenToScalarImageFilter() {} - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() ITK_OVERRIDE; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; - - /** Single threaded since we are connecting data */ - void - GenerateData() ITK_OVERRIDE; - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); - - /* Filter pipeline */ - typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; - typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkDescoteauxEigenToScalarImageFilter.hxx" -#endif - -#endif // itkDescoteauxEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx deleted file mode 100644 index b7dd3e2ae51..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx +++ /dev/null @@ -1,101 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkDescoteauxEigenToScalarImageFilter_hxx -#define itkDescoteauxEigenToScalarImageFilter_hxx - -#include "itkDescoteauxEigenToScalarImageFilter.h" -#include "itkProgressAccumulator.h" - -namespace itk -{ -template -DescoteauxEigenToScalarImageFilter::DescoteauxEigenToScalarImageFilter() -{ - /* Instantiate filters. */ - m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); - m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); - - /* We require an input image */ - this->SetNumberOfRequiredInputs(1); -} - -template -void -DescoteauxEigenToScalarImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -DescoteauxEigenToScalarImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -DescoteauxEigenToScalarImageFilter::GenerateData() -{ - /* Get inputs */ - InputImageConstPointer input = this->GetInput(); - - /* Connect filters */ - m_ParameterEstimationFilter->SetInput(input); - m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); - m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); - m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); - m_UnaryFunctorFilter->SetCInput(m_ParameterEstimationFilter->GetCOutput()); - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); - progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); - - /* Graft output and we're done! */ - m_UnaryFunctorFilter->Update(); - this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); -} - -template -void -DescoteauxEigenToScalarImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; - os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; -} - -} // namespace itk - -#endif // itkDescoteauxEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h deleted file mode 100644 index 00844b5b3da..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ /dev/null @@ -1,190 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_h -#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkNumericTraits.h" -#include "itkSimpleDataObjectDecorator.h" -#include "itkArray.h" - -namespace itk -{ -/** \class DescoteauxEigenToScalarParameterEstimationImageFilter - * \brief Automatic parameter estimation for the Krcah method - * - * The default parameters are: - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.5 max\( Frobenius norm \) - * \f} - * - * Where the Frobenius norm for a real, symmetric matrix is given by - * the square root of the sum of squares of the eigenvalues. - * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter - : public ImageToImageFilter -{ -public: - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarParameterEstimationImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /** Image related typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TInputImage::RegionType InputRegionType; - typedef typename TInputImage::SizeType InputSizeType; - typedef typename TInputImage::IndexType InputIndexType; - typedef typename TInputImage::PixelType InputPixelType; - typedef typename InputPixelType::ValueType InputPixelValueType; - - /** Output region definitions */ - typedef InputRegionType OutputRegionType; - - /** Mask related typedefs. */ - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - typedef typename TMaskImage::RegionType MaskRegionType; - - /** Parameters */ - typedef typename NumericTraits::RealType RealType; - typedef SimpleDataObjectDecorator RealTypeDecoratedType; - - /** Methods to set/get the mask image */ - itkSetInputMacro(MaskImage, TMaskImage); - itkGetInputMacro(MaskImage, TMaskImage); - - /** Setter/getter for background pixel value */ - itkSetMacro(BackgroundValue, MaskPixelType); - itkGetConstMacro(BackgroundValue, MaskPixelType); - - /** Method setter/getter for Frobenius Norm Weight */ - itkSetMacro(FrobeniusNormWeight, RealType); - itkGetConstMacro(FrobeniusNormWeight, RealType); - - /** Decorators for parameters so they can be passed as a process object */ - RealTypeDecoratedType * - GetAlphaOutput(); - const RealTypeDecoratedType * - GetAlphaOutput() const; - RealTypeDecoratedType * - GetBetaOutput(); - const RealTypeDecoratedType * - GetBetaOutput() const; - RealTypeDecoratedType * - GetCOutput(); - const RealTypeDecoratedType * - GetCOutput() const; - - /** Standard getters for the output parameters */ - RealType - GetAlpha() const - { - return this->GetAlphaOutput()->Get(); - } - RealType - GetBeta() const - { - return this->GetBetaOutput()->Get(); - } - RealType - GetC() const - { - return this->GetCOutput()->Get(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - DescoteauxEigenToScalarParameterEstimationImageFilter(); - virtual ~DescoteauxEigenToScalarParameterEstimationImageFilter() {} - - /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ - void - AllocateOutputs() ITK_OVERRIDE; - - /** Initialize some accumulators before the threads run. */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Do final mean and variance computation from data accumulated in threads. */ - void - AfterThreadedGenerateData() ITK_OVERRIDE; - - /** Multi-thread version GenerateData. */ - void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() ITK_OVERRIDE; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; - - /** Compute Frobenius norm from a fixed array of eigenvalues */ - inline RealType - CalculateFrobeniusNorm(InputPixelType pixel); - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); - - /* Parameters */ - RealType m_FrobeniusNormWeight; - MaskPixelType m_BackgroundValue; - - /* Arrays for threads */ - Array m_MaxFrobeniusNorm; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx" -#endif - -#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index d835345a393..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,266 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx -#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -DescoteauxEigenToScalarParameterEstimationImageFilter:: - DescoteauxEigenToScalarParameterEstimationImageFilter() - : m_FrobeniusNormWeight(0.5f) - , m_BackgroundValue(NumericTraits::Zero) - , m_MaxFrobeniusNorm(1) -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Resize threads */ - m_MaxFrobeniusNorm.SetSize(numberOfThreads); - m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Determine default parameters */ - RealType alpha, beta, c; - alpha = 0.5f; - beta = 0.5f; - c = m_FrobeniusNormWeight; - - /* Accumulate over threads */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) - { - maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; - } - } - - /* Scale c */ - if (maxFrobeniusNorm > 0) - { - c = c * maxFrobeniusNorm; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetCOutput()->Set(c); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Count starts zero */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - RealType thisFrobeniusNorm; - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - /* Compute max norm */ - thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); - if (thisFrobeniusNorm > maxFrobeniusNorm) - { - maxFrobeniusNorm = thisFrobeniusNorm; - } - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealType -DescoteauxEigenToScalarParameterEstimationImageFilter::CalculateFrobeniusNorm( - InputPixelType pixel) -{ - /* Forbenius norm is given by the square root of the sum of squares - * of the eigenvalues for real, symmetric matricies - */ - RealType norm = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - norm += pixel[i] * pixel[i]; - } - return sqrt(norm); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << this->GetAlpha() << std::endl; - os << indent << "Beta: " << this->GetBeta() << std::endl; - os << indent << "C: " << this->GetC() << std::endl; - os << indent << "BackgroundValue: " << GetBackgroundValue() << std::endl; - os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; -} - -} // namespace itk - -#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h index 0ac86321f27..f6508d7cd6c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -28,24 +28,17 @@ namespace itk /** \class EigenToMeasureImageFilter * \brief Abstract class for computing a measure from local structure. * - * TODO - * - * This is an abstract class that estimates parameters for local-structure enhancement - * from eigen-images. Other classes should inherit from this class so they can be used - * in the MultiScaleHessianEnhancementImageFilter framework. - * - * To estimate the parameters for local-structure enhancement, every pixel in the input - * image must be seen. To implement this functionality in a memory efficinet way, this - * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by - * restricting the output image region. + * This is an abstract class that computes a local-structure measure from an eigen-image. + * Any algorithm implementing a local-structure measure should inherit from this class + * so they can be used in the MultiScaleHessianEnhancementImageFilter framework. * * \sa MultiScaleHessianEnhancementImageFilter - * \sa UnaryFunctorImageFilter + * \sa EigenToMeasureParameterEstimationFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter { public: @@ -59,11 +52,12 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< itkTypeMacro(EigenToMeasureImageFilter, ImageToImageFilter); /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename InputImagePixelType::ValueType PixelValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ @@ -76,48 +70,14 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< typedef TInputSpatialObject SpatialObjectType; typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; - /** Functor typedefs. */ - typedef TFunction FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - typedef typename ParameterType::ValueType ParameterValueType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; - itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); - - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ - FunctorType & - GetFunctor() - { - return m_Functor; - } - const FunctorType & - GetFunctor() const - { - return m_Functor; - } - - /** Set the functor object. This replaces the current Functor with a - * copy of the specified Functor. This allows the user to specify a - * functor that has ivars set differently than the default functor. - * This method requires the following to be defined: - * Initialize() - * ProcessPixel() - * GetComputedParameters() - */ - void - SetFunctor(const FunctorType & functor) - { - if (m_Functor != functor) - { - m_Functor = functor; - this->Modified(); - } - } + /** Parameter typedefs. */ + typedef typename NumericTraits::RealType RealType; + typedef RealType ParameterType; + typedef Array ParameterArrayType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; /** Process object */ - itkSetGetDecoratedInputMacro(Parameters, ParameterType); + itkSetGetDecoratedInputMacro(Parameters, ParameterArrayType); /** Methods to set/get the mask image */ itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); @@ -139,29 +99,12 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< GetEigenValueOrder() const = 0; protected: - EigenToMeasureImageFilter(); - virtual ~EigenToMeasureImageFilter() ITK_OVERRIDE; - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE; - void - ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId); - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + EigenToMeasureImageFilter() {}; + virtual ~EigenToMeasureImageFilter() {} private: ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); - - /* Private data members. */ - ParameterType m_Parameters; - FunctorType m_Functor; }; // end class } // namespace itk -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkEigenToMeasureImageFilter.hxx" -#endif - #endif /* itkEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index 8a08a093ba4..2e8d85968d5 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -26,24 +26,28 @@ namespace itk { /** \class EigenToMeasureParameterEstimationFilter - * \brief Abstract class for estimating local-structure parameters from eigenvalues. + * \brief Abstract class for estimating local-structure parameters from an eigen-image. * * This is an abstract class that estimates parameters for local-structure enhancement - * from eigen-images. Other classes should inherit from this class so they can be used - * in the MultiScaleHessianEnhancementImageFilter framework. + * from eigen-images. Any algorithm implementing a local-structure measure should inherit from this class + * so they can be used in the MultiScaleHessianEnhancementImageFilter framework. * - * To estimate the parameters for local-structure enhancement, every pixel in the input + * To estimate parameters for local-structure enhancement, every pixel in the input * image must be seen. To implement this functionality in a memory efficinet way, this * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by * restricting the output image region. * - * \sa MultiScaleHessianEnhancementImageFilter + * The method GetParametersOutput can be used to insert this filter in a pipeline before + * EigenToMeasureImageFilter. + * * \sa StreamingImageFilter + * \sa MultiScaleHessianEnhancementImageFilter + * \sa EigenToMeasureImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter : public StreamingImageFilter { @@ -57,15 +61,13 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter /** Run-time type information (and related methods). */ itkTypeMacro(EigenToMeasureParameterEstimationFilter, StreamingImageFilter); - /** Method for creation through the object factory. */ - itkNewMacro(Self); - /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename InputImagePixelType::ValueType PixelValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ @@ -76,45 +78,11 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter typedef TInputSpatialObject SpatialObjectType; typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; - /** Functor typedefs. */ - typedef TFunction FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - typedef typename ParameterType::ValueType ParameterValueType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; - itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); - - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ - FunctorType & - GetFunctor() - { - return m_Functor; - } - const FunctorType & - GetFunctor() const - { - return m_Functor; - } - - /** Set the functor object. This replaces the current Functor with a - * copy of the specified Functor. This allows the user to specify a - * functor that has ivars set differently than the default functor. - * This method requires the following to be defined: - * Initialize() - * ProcessPixel() - * GetComputedParameters() - */ - void - SetFunctor(const FunctorType & functor) - { - if (m_Functor != functor) - { - m_Functor = functor; - this->Modified(); - } - } + /** Parameter typedefs. */ + typedef typename NumericTraits::RealType RealType; + typedef RealType ParameterType; + typedef Array ParameterArrayType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; /** Decorators for parameters so they can be passed as a process object */ ParameterDecoratedType * @@ -123,7 +91,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter GetParametersOutput() const; /** Standard getters for the parameters */ - ParameterType + ParameterArrayType GetParameters() const { return this->GetParametersOutput()->Get(); @@ -147,10 +115,6 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter static ITK_THREAD_RETURN_TYPE ThreaderCallback(void * arg) ITK_OVERRIDE; - /** Repeatedly call the functor for each pixel we index. */ - void - ThreadedGenerateData(const InputImageRegionType & region, unsigned int streamNumber); - struct ThreadStruct { Pointer Filter; @@ -158,17 +122,13 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter protected: EigenToMeasureParameterEstimationFilter(); - virtual ~EigenToMeasureParameterEstimationFilter() ITK_OVERRIDE; + virtual ~EigenToMeasureParameterEstimationFilter() {} void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; private: ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); - - /* Private data members. */ - FunctorType m_Functor; - unsigned int m_CurrentSplit; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx index c1b4177f207..317219ecbef 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -24,15 +24,18 @@ #include "itkImageAlgorithm.h" #include "itkImageRegionSplitterSlowDimension.h" #include "itkImageRegionConstIteratorWithIndex.h" -#include "itkImageRegionSplitterBase.h" +#include "itkImageRegionSplitterSlowDimension.h" namespace itk { -template -EigenToMeasureParameterEstimationFilter:: - EigenToMeasureParameterEstimationFilter() - : m_CurrentSplit(0) + +template +EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() { + /* Set stream parameters */ + this->SetNumberOfStreamDivisions(10); + this->SetRegionSplitter(ImageRegionSplitterSlowDimension::New()); + /* We require an input image */ this->SetNumberOfRequiredInputs(1); @@ -41,56 +44,14 @@ EigenToMeasureParameterEstimationFilterSet(initialParameters); - this->ProcessObject::SetNthOutput(1, output.GetPointer()); -} - -template -EigenToMeasureParameterEstimationFilter:: - ~EigenToMeasureParameterEstimationFilter() -{} - -template -void -EigenToMeasureParameterEstimationFilter::ThreadedGenerateData( - const InputImageRegionType & region, - unsigned int streamNumber) -{ - /* If size is zero, return */ - if (region.GetSize(0) == 0) - { - return; - } - - /* Get input pointers */ - InputImageConstPointer inputPointer = this->GetInput(); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); - typename InputImageType::PointType point; - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) - { - m_Functor.ProcessPixel(inputIt.Get(), streamNumber); - } - ++inputIt; - } + this->SetNthOutput(1, output.GetPointer()); } -template +template void -EigenToMeasureParameterEstimationFilter::UpdateOutputData( +EigenToMeasureParameterEstimationFilter::UpdateOutputData( DataObject * itkNotUsed(output)) { /** Prevent chasing our tail */ @@ -145,8 +106,10 @@ EigenToMeasureParameterEstimationFilterGetNumberOfStreamDivisions() * this->GetNumberOfThreads()); + // Call a method that can be overridden by a subclass to perform + // some calculations prior to splitting the main computations into + // separate threads + this->BeforeThreadedGenerateData(); /** * Loop over the number of pieces, execute the upstream pipeline on each @@ -154,45 +117,47 @@ EigenToMeasureParameterEstimationFilterGetAbortGenerateData(); piece++) { - /* Set the current peice */ - m_CurrentSplit = piece; - /* Determine the split region and calculate the input */ - InputImageRegionType streamRegion = outputRegion; + InputImageRegionType streamRegion; + this->CallCopyOutputRegionToInputRegion(streamRegion, outputRegion); + this->GetRegionSplitter()->GetSplit(piece, numDivisions, streamRegion); inputPtr->SetRequestedRegion(streamRegion); inputPtr->PropagateRequestedRegion(); inputPtr->UpdateOutputData(); - /* Setup a multithreadign process */ - ThreadStruct str; - str.Filter = this; + // /* Setup a multithreadign process */ + // ThreadStruct str; + // str.Filter = this; - // Get the output pointer - const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); - const unsigned int validThreads = splitter->GetNumberOfSplits(streamRegion, this->GetNumberOfThreads()); + // // Get the output pointer + // const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); + // const unsigned int validThreads = splitter->GetNumberOfSplits( streamRegion, this->GetNumberOfThreads() ); - this->GetMultiThreader()->SetNumberOfThreads(validThreads); - this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); + // this->GetMultiThreader()->SetNumberOfThreads( validThreads ); + // this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); - // multithread the execution - this->GetMultiThreader()->SingleMethodExecute(); + // // multithread the execution + // this->GetMultiThreader()->SingleMethodExecute(); + + this->ThreadedGenerateData(streamRegion, piece); // copy the result to the proper place in the output. the input // requested region determined by the RegionSplitter (as opposed // to what the pipeline might have enlarged it to) is used to // copy the regions from the input to output - if (inputPtr != outputPtr) - { - ImageAlgorithm::Copy(inputPtr, outputPtr, streamRegion, streamRegion); - } + // if (inputPtr != outputPtr) + // { + // ImageAlgorithm::Copy( inputPtr, outputPtr, streamRegion, streamRegion ); + // } /* Update progress and stream another chunk */ this->UpdateProgress(static_cast(piece) / static_cast(numDivisions)); } - /* Compute and set the parameters */ - this->GetParametersOutput()->Set(m_Functor.GetComputedParameters()); + // Call a method that can be overridden by a subclass to perform + // some calculations after all the threads have completed + this->AfterThreadedGenerateData(); /** * If we ended due to aborting, push the progress up to 1.0 @@ -209,9 +174,9 @@ EigenToMeasureParameterEstimationFilterGetNumberOfOutputs(); ++idx) { - if (this->GetOutput(idx)) + if (this->ProcessObject::GetOutput(idx)) { - this->GetOutput(idx)->DataHasBeenGenerated(); + this->ProcessObject::GetOutput(idx)->DataHasBeenGenerated(); } } @@ -222,57 +187,60 @@ EigenToMeasureParameterEstimationFilterm_Updating = false; } -template -ITK_THREAD_RETURN_TYPE -EigenToMeasureParameterEstimationFilter::ThreaderCallback(void * arg) -{ - ThreadStruct * str; - ThreadIdType total, threadId, threadCount; - - threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; - threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads; - - str = (ThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData); - - // execute the actual method with appropriate output region - // first find out how many pieces extent can be split into. - typename OutputImageType::RegionType splitRegion; - total = str->Filter->SplitRequestedRegion(threadId, threadCount, splitRegion); - unsigned int streamNumber = str->Filter->m_CurrentSplit; - - if (threadId < total) - { - str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions() * threadId + streamNumber); - } - // else - // { - // otherwise don't use this thread. Sometimes the threads dont - // break up very well and it is just as efficient to leave a - // few threads idle. - // } - - return ITK_THREAD_RETURN_VALUE; -} - -template -typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() +// Threaded splitter +// template< typename TInputImage, typename TInputSpatialObject > +// ITK_THREAD_RETURN_TYPE +// EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject > +// ::ThreaderCallback(void *arg) +// { +// ThreadStruct *str; +// ThreadIdType total, threadId, threadCount; + +// threadId = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->ThreadID; +// threadCount = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + +// str = (ThreadStruct *)( ( (MultiThreader::ThreadInfoStruct *)( arg ) )->UserData ); + +// // execute the actual method with appropriate output region +// // first find out how many pieces extent can be split into. +// typename OutputImageType::RegionType splitRegion; +// total = str->Filter->SplitRequestedRegion(threadId, threadCount, +// splitRegion); +// unsigned int streamNumber = str->Filter->m_CurrentSplit; + +// if ( threadId < total ) +// { +// str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions()*threadId + +// streamNumber); +// } +// // else +// // { +// // otherwise don't use this thread. Sometimes the threads dont +// // break up very well and it is just as efficient to leave a +// // few threads idle. +// // } + +// return ITK_THREAD_RETURN_VALUE; +// } + +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() { return static_cast(this->ProcessObject::GetOutput(1)); } -template -const typename EigenToMeasureParameterEstimationFilter:: - ParameterDecoratedType * - EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +template +const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() const { return static_cast(this->ProcessObject::GetOutput(1)); } -template +template void -EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, - Indent indent) const +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h deleted file mode 100644 index 6910bc2cbf4..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ /dev/null @@ -1,89 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkEigenToScalarImageFilter_h -#define itkEigenToScalarImageFilter_h - -#include "itkImageToImageFilter.h" - -namespace itk -{ -/** \class EigenToScalarImageFilter - * \brief Abstract class for converting eigenvalue image to scalar image. - * - * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. - * Other classes should inherit from this class so they can be used in the BoneEnhancement framework. This abstract - * class guarantees that the variable EigenValueOrder has a valid type and enforces some concept checking - * on the class template parameters: TInputImage and TOutputImage . - * - * \sa MultiScaleHessianEnhancementImageFilter. - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter -{ -public: - /** Standard Self typedef */ - typedef EigenToScalarImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Run-time type information (and related methods). */ - itkTypeMacro(EigenToScalarImageFilter, ImageToImageFilter); - - /** Template the EigenValueOrderType. Methods that inherit from this class can override this function - * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from - * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial - * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type - * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. - */ - typedef enum - { - OrderByValue = 1, - OrderByMagnitude, - DoNotOrder - } EigenValueOrderType; - virtual EigenValueOrderType - GetEigenValueOrder() const = 0; - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, - (Concept::SameDimension)); - // End concept checking -#endif -protected: - EigenToScalarImageFilter() {} - virtual ~EigenToScalarImageFilter() {} - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE - { - Superclass::PrintSelf(os, indent); - os << indent << "EigenValueOrder: " << this->GetEigenValueOrder() << std::endl; - } - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenToScalarImageFilter); -}; // end class -} // namespace itk - -#endif // itkEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index df685bdae4e..7decae47804 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -193,15 +193,16 @@ HessianGaussianImageFilter::GenerateData(void) // Setup Image Adaptor m_ImageAdaptor->SetImage(this->GetOutput()); - m_ImageAdaptor->SetLargestPossibleRegion(inputImage->GetLargestPossibleRegion()); + m_ImageAdaptor->SetLargestPossibleRegion(this->GetOutput()->GetLargestPossibleRegion()); - m_ImageAdaptor->SetBufferedRegion(inputImage->GetBufferedRegion()); + m_ImageAdaptor->SetBufferedRegion(this->GetOutput()->GetRequestedRegion()); - m_ImageAdaptor->SetRequestedRegion(inputImage->GetRequestedRegion()); + m_ImageAdaptor->SetRequestedRegion(this->GetOutput()->GetRequestedRegion()); m_ImageAdaptor->Allocate(); m_DerivativeFilter->SetInput(inputImage); + m_DerivativeFilter->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion()); unsigned int element = 0; int order[ImageDimension]; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h deleted file mode 100644 index bf71951c707..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,251 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarFunctorImageFilter_h -#define itkKrcahEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class KrcahEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Krcah et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{tube} &=& \frac{\lambda_1|}{|\lambda_2| \cdot \lambda_3|} \\ - * R_{noise} &=& \lambda_1| + |\lambda_2| + \lambda_3| \\ - * s &=& sign(\lambda_3) \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \exp\left(- \frac{R_{tube}^2}{\beta^2} - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) - * \f} - * - * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. - * - * \sa KrcahEigentoScalarParameterEstimationImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - typedef typename NumericTraits::RealType RealType; - - KrcahEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Avoid divisions by zero (or close to zero) */ - if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) - { - return static_cast(sheetness); - } - - /** - * Compute sheet, noise, and tube like measures. Note that the average trace of the - * Hessian matrix is implicitly included in \f$ \gamma \f$ here. - */ - const double Rsheet = l2 / l3; - const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma - const double Rtube = l1 / (l2 * l3); - - /* Multiply together to get sheetness */ - sheetness = (m_Direction * a3 / l3); - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); - sheetness *= vcl_exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetGamma(const RealType gamma) - { - this->m_Gamma = gamma; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetGamma() const - { - return this->m_Gamma; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_Gamma; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class KrcahEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. - * - * See functor for mathematics. - * - * \sa KrcahEigenToScalarFunctor - * \sa KrcahEigenToScalarImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor> -{ -public: - /** Standard Self typedef */ - typedef KrcahEigenToScalarFunctorImageFilter Self; - typedef UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Useful typedefs for numerics */ - typedef typename Functor::KrcahEigenToScalarFunctor - KrcahFunctorType; - typedef typename KrcahFunctorType::RealType RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(Gamma, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetGamma(this->GetGammaInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - KrcahEigenToScalarFunctorImageFilter() {} - virtual ~KrcahEigenToScalarFunctorImageFilter() {} - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); - - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "Gamma: " << GetGamma() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkKrcahEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h deleted file mode 100644 index f52aa4d762b..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ /dev/null @@ -1,212 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarImageFilter_h -#define itkKrcahEigenToScalarImageFilter_h - -#include "itkEigenToScalarImageFilter.h" -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkKrcahEigenToScalarFunctorImageFilter.h" - -namespace itk -{ -/** \class KrcahEigenToScalarImageFilter - * \brief Compute the Krcah sheetness measure from the eigenvalues - * - * This is a convenience class implementing the EigenToScalarImageFilter - * abstract class. This class computes the Krcah sheetness measure for - * cortical bone. Internally, KrcahEigenToScalarParameterEstimationImageFilter - * and KrcahEigenToScalarFunctorImageFilter are used for automatic parameter - * estimation and implementation of the functor. - * - * Before passing an input to MultiScaleHessianEnhancementImageFilter, - * the KrcahEigenToScalarPreprocessingImageToImageFilter should be used. - * - * \sa MultiScaleHessianEnhancementImageFilter - * \sa EigenToScalarImageFilter - * \sa KrcahEigenToScalarParameterEstimationImageFilter - * \sa KrcahEigenToScalarFunctorImageFilter - * \sa KrcahEigenToScalarPreprocessingImageToImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template > -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarImageFilter -{ -public: - /** Standard Self typedef */ - typedef KrcahEigenToScalarImageFilter Self; - typedef EigenToScalarImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); - - /** Useful template typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - - /** Procesing filters */ - typedef KrcahEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; - typedef typename ParameterEstimationFilterType::KrcahImplementationType KrcahImplementationType; - typedef KrcahEigenToScalarFunctorImageFilter UnaryFunctorFilterType; - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE - { - return Superclass::OrderByMagnitude; - } - - /** Methods to set/get the mask image */ - void - SetMaskImage(const TMaskImage * mask) - { - this->m_ParameterEstimationFilter->SetMaskImage(mask); - this->Modified(); - } - virtual const TMaskImage * - GetMaskImage() const - { - return this->m_ParameterEstimationFilter->GetMaskImage(); - } - - /** Methods to set/get the background value */ - virtual void - SetBackgroundValue(const MaskPixelType back) - { - this->m_ParameterEstimationFilter->SetBackgroundValue(back); - this->Modified(); - } - virtual MaskPixelType - GetBackgroundValue() const - { - return this->m_ParameterEstimationFilter->GetBackgroundValue(); - } - - /** Methods to set/get the parameter set type */ - virtual void - SetParameterSet(const KrcahImplementationType back) - { - this->m_ParameterEstimationFilter->SetParameterSet(back); - this->Modified(); - } - virtual KrcahImplementationType - GetParameterSet() const - { - return this->m_ParameterEstimationFilter->GetParameterSet(); - } - virtual void - SetParameterSetToImplementation() - { - this->m_ParameterEstimationFilter->SetParameterSetToImplementation(); - this->Modified(); - } - virtual void - SetParameterSetToJournalArticle() - { - this->m_ParameterEstimationFilter->SetParameterSetToJournalArticle(); - this->Modified(); - } - - /** Methods to get the computed parameters */ - typename UnaryFunctorFilterType::RealType - GetAlpha() const - { - return m_UnaryFunctorFilter->GetAlpha(); - } - typename UnaryFunctorFilterType::RealType - GetBeta() const - { - return m_UnaryFunctorFilter->GetBeta(); - } - typename UnaryFunctorFilterType::RealType - GetGamma() const - { - return m_UnaryFunctorFilter->GetGamma(); - } - - /** Methods to set/get the enhancment method */ - void - SetEnhanceBrightObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); - this->Modified(); - } - void - SetEnhanceDarkObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); - this->Modified(); - } - typename UnaryFunctorFilterType::RealType - GetEnhanceType() const - { - return this->m_UnaryFunctorFilter->GetEnhanceType(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarImageFilter(); - virtual ~KrcahEigenToScalarImageFilter() {} - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() ITK_OVERRIDE; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; - - /** Single threaded since we are connecting data */ - void - GenerateData() ITK_OVERRIDE; - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); - - /* Filter pipeline */ - typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; - typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx deleted file mode 100644 index 68ab556a9a2..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx +++ /dev/null @@ -1,99 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkKrcahEigenToScalarImageFilter_hxx -#define itkKrcahEigenToScalarImageFilter_hxx - -#include "itkKrcahEigenToScalarImageFilter.h" -#include "itkProgressAccumulator.h" - -namespace itk -{ -template -KrcahEigenToScalarImageFilter::KrcahEigenToScalarImageFilter() -{ - /* Instantiate filters. */ - m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); - m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); - - /* We require an input image */ - this->SetNumberOfRequiredInputs(1); -} - -template -void -KrcahEigenToScalarImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -KrcahEigenToScalarImageFilter::EnlargeOutputRequestedRegion(DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -KrcahEigenToScalarImageFilter::GenerateData() -{ - /* Get inputs */ - InputImageConstPointer input = this->GetInput(); - - /* Connect filters */ - m_ParameterEstimationFilter->SetInput(input); - m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); - m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); - m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); - m_UnaryFunctorFilter->SetGammaInput(m_ParameterEstimationFilter->GetGammaOutput()); - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); - progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); - - /* Graft output and we're done! */ - m_UnaryFunctorFilter->Update(); - this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); -} - -template -void -KrcahEigenToScalarImageFilter::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; - os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; -} - -} // namespace itk - -#endif // itkKrcahEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h deleted file mode 100644 index d828dd9fbae..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ /dev/null @@ -1,239 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_h -#define itkKrcahEigenToScalarParameterEstimationImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkNumericTraits.h" -#include "itkSimpleDataObjectDecorator.h" -#include "itkArray.h" - -namespace itk -{ -/** \class KrcahEigenToScalarParameterEstimationImageFilter - * \brief Automatic parameter estimation for the Krcah method - * - * This class takes an image of eigenvalues and estimates the parameters for the Krcah - * bone enhanced filter. According to the original paper, - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.25 - * \f} - * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. - * The trace of the matrix can be computed directly from the eigenvalues as the sum - * of the eigenvalues. - * - * In this implementation, the average of the trace is moved into the constant - * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary - * functor. The modification is very simple. If the average of the trace is - * denoted \f$ T \f$ the new parameter becomes: - * \f{ - * \gamma &=& 0.25 \cdot T - * \f} - * - * However, the code was implemented different than described in the original - * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum - * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. - * Furthermore, all parameters were scaled by a factor of 2 in the implementation - * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the - * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType - * can be set which enables the implementation parameters: - * \f{eqnarray*}{ - * \alpha &=& \sqrt{2} \cdot 0.5 \\ - * \beta &=& \sqrt{2} \cdot 0.5 \\ - * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T - * \f} - * Default is to use parameters from the implementation, not the paper. - * - * Finally, a mask can be provided. Metal or non-standard objects in the field - * of view may throw off the parameter estimation. In those cases, a mask can - * be provided so those voxels are not factored into the calculation of \f$ T \f$. - * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter - : public ImageToImageFilter -{ -public: - /** Standard Self typedef */ - typedef KrcahEigenToScalarParameterEstimationImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /** Image related typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TInputImage::RegionType InputRegionType; - typedef typename TInputImage::SizeType InputSizeType; - typedef typename TInputImage::IndexType InputIndexType; - typedef typename TInputImage::PixelType InputPixelType; - typedef typename InputPixelType::ValueType InputPixelValueType; - - /** Output region definitions */ - typedef InputRegionType OutputRegionType; - - /** Mask related typedefs. */ - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - typedef typename TMaskImage::RegionType MaskRegionType; - - /** Methods to set/get the mask image */ - itkSetInputMacro(MaskImage, TMaskImage); - itkGetInputMacro(MaskImage, TMaskImage); - - /** Iterator types */ - itkSetMacro(BackgroundValue, MaskPixelType); - itkGetConstMacro(BackgroundValue, MaskPixelType); - - typedef enum - { - UseImplementationParameters = 1, - UseJournalParameters - } KrcahImplementationType; - itkSetMacro(ParameterSet, KrcahImplementationType); - itkGetConstMacro(ParameterSet, KrcahImplementationType); - - /* Set parameter set */ - void - SetParameterSetToImplementation() - { - this->SetParameterSet(UseImplementationParameters); - } - - void - SetParameterSetToJournalArticle() - { - this->SetParameterSet(UseJournalParameters); - } - - /** Parameters */ - typedef typename NumericTraits::RealType RealType; - typedef SimpleDataObjectDecorator RealTypeDecoratedType; - - /** Decorators for parameters so they can be passed as a process object */ - RealTypeDecoratedType * - GetAlphaOutput(); - const RealTypeDecoratedType * - GetAlphaOutput() const; - RealTypeDecoratedType * - GetBetaOutput(); - const RealTypeDecoratedType * - GetBetaOutput() const; - RealTypeDecoratedType * - GetGammaOutput(); - const RealTypeDecoratedType * - GetGammaOutput() const; - - /** Standard getters for the output parameters */ - RealType - GetAlpha() const - { - return this->GetAlphaOutput()->Get(); - } - RealType - GetBeta() const - { - return this->GetBetaOutput()->Get(); - } - RealType - GetGamma() const - { - return this->GetGammaOutput()->Get(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarParameterEstimationImageFilter(); - virtual ~KrcahEigenToScalarParameterEstimationImageFilter() {} - - /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ - void - AllocateOutputs() ITK_OVERRIDE; - - /** Initialize some accumulators before the threads run. */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Do final mean and variance computation from data accumulated in threads. */ - void - AfterThreadedGenerateData() ITK_OVERRIDE; - - /** Multi-thread version GenerateData. */ - void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() ITK_OVERRIDE; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - - /** Calculation of \f$ T \f$ changes depending on the implementation */ - inline RealType - CalculateTraceAccordingToImplementation(InputPixelType pixel); - inline RealType - CalculateTraceAccordingToJournalArticle(InputPixelType pixel); - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); - - /* Parameters */ - KrcahImplementationType m_ParameterSet; - - /* Inputs */ - MaskPixelType m_BackgroundValue; - - /* Arrays for threads */ - Array m_AccumulatedAverageTrace; - Array m_NumVoxels; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarParameterEstimationImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index 85a90c1b2a3..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,309 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_hxx -#define itkKrcahEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarParameterEstimationImageFilter::KrcahEigenToScalarParameterEstimationImageFilter() - : m_ParameterSet(UseImplementationParameters) - , m_BackgroundValue(NumericTraits::Zero) - , m_NumVoxels(1) - , m_AccumulatedAverageTrace(1) -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Resize threads */ - m_AccumulatedAverageTrace.SetSize(numberOfThreads); - m_NumVoxels.SetSize(numberOfThreads); - - m_AccumulatedAverageTrace.Fill(NumericTraits::ZeroValue()); - m_NumVoxels.Fill(NumericTraits::ZeroValue()); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Determine default parameters */ - RealType alpha, beta, gamma; - switch (m_ParameterSet) - { - case UseImplementationParameters: - alpha = Math::sqrt2 * 0.5f; - beta = Math::sqrt2 * 0.5f; - gamma = Math::sqrt2 * 0.5f; - break; - case UseJournalParameters: - alpha = 0.5f; - beta = 0.5f; - gamma = 0.25f; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Accumulate over threads */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - numVoxels += m_NumVoxels[i]; - accumulatedAverageTrace += m_AccumulatedAverageTrace[i]; - } - - /* Do derived measure */ - if (numVoxels > 0) - { - RealType averageTrace = (RealType)accumulatedAverageTrace / (RealType)numVoxels; - gamma = gamma * averageTrace; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetGammaOutput()->Set(gamma); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Determine which function to call */ - RealType (Self::*traceFunction)(InputPixelType); - switch (m_ParameterSet) - { - case UseImplementationParameters: - traceFunction = &Self::CalculateTraceAccordingToImplementation; - break; - case UseJournalParameters: - traceFunction = &Self::CalculateTraceAccordingToJournalArticle; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Count starts zero */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - numVoxels++; - - /* Compute trace */ - accumulatedAverageTrace += (this->*traceFunction)(inputIt.Get()); - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_AccumulatedAverageTrace[threadId] = accumulatedAverageTrace; - m_NumVoxels[threadId] = numVoxels; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToImplementation( - InputPixelType pixel) -{ - /* Sum of the absolute value of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += Math::abs(pixel[i]); - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToJournalArticle( - InputPixelType pixel) -{ - /* Sum of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += pixel[i]; - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "m_Alpha: " << this->GetAlpha() << std::endl; - os << indent << "m_Beta: " << this->GetBeta() << std::endl; - os << indent << "m_Gamma: " << this->GetGamma() << std::endl; - os << indent << "m_BackgroundValue: " << m_BackgroundValue << std::endl; - os << indent << "m_ParameterSet: " << m_ParameterSet << std::endl; -} - -} // end namespace itk - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h deleted file mode 100644 index ea75044d05c..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ /dev/null @@ -1,146 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_h -#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkDiscreteGaussianImageFilter.h" -#include "itkSubtractImageFilter.h" -#include "itkMultiplyImageFilter.h" -#include "itkAddImageFilter.h" - -namespace itk -{ -/** \class KrcahEigenToScalarPreprocessingImageToImageFilter - * \brief Perform preprocessing as defined by Krcah et al - * - * This filters performs an unsharp filter as defined by Krcah - * et al. The unsharp filter is defined by: - * \f{ - * J = I+k*(I-(I*G)) - * \f} - * - * Where \f$ k \f$ is a scaling constant set to 5 and the Guassian - * filter has smoothing parameter \f$ s = 1 mm \f$. A user can modify - * these defaults using the appropriate setter methods. - * - * Additionally, this filter provides the ReleaseInternalFilterData - * flag. When this flag is set, the internal filters used to compute - * the unsharp filter will release their data after processing. This - * conserves memory at the expense of computation time if ScalingConstant - * or Sigma are changed. This flag is on by default. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter - : public ImageToImageFilter -{ -public: - /** Standard Self typedef */ - typedef KrcahEigenToScalarPreprocessingImageToImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); - - /** Extract some information from the image types. Dimensionality - * of the two images is assumed to be the same. */ - itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); - - /** Image related typedefs. */ - typedef typename TInputImage::PixelType PixelType; - typedef typename TOutputImage::PixelType OutputPixelType; - typedef typename NumericTraits::RealType RealType; - typedef typename NumericTraits::ValueType OutputPixelValueType; - - /** Typedefs for internal filters */ - typedef DiscreteGaussianImageFilter GaussianFilterType; - typedef SubtractImageFilter SubstractFilterType; - typedef MultiplyImageFilter MultiplyFilterType; - typedef AddImageFilter AddFilterType; - - /** Flag to release data or not */ - itkSetMacro(ReleaseInternalFilterData, bool); - itkGetConstMacro(ReleaseInternalFilterData, bool); - itkBooleanMacro(ReleaseInternalFilterData); - - /** Flag to release data or not */ - itkSetMacro(Sigma, RealType); - itkGetConstMacro(Sigma, RealType); - - /** Flag to release data or not */ - itkSetMacro(ScalingConstant, RealType); - itkGetConstMacro(ScalingConstant, RealType); - - /** DiscreteGaussianImageFilter needs a larger input requested region - * than the output requested region (larger by the size of the - * Gaussian kernel). As such, DiscreteGaussianImageFilter needs to - * provide an implementation for GenerateInputRequestedRegion() in - * order to inform the pipeline execution model. - * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - virtual void - GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, - (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarPreprocessingImageToImageFilter(); - virtual ~KrcahEigenToScalarPreprocessingImageToImageFilter() {} - - /** Single threaded since we are connecting data */ - void - GenerateData() ITK_OVERRIDE; - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); - - /* Internal member variables */ - RealType m_Sigma; - RealType m_ScalingConstant; - bool m_ReleaseInternalFilterData; - - /* Filter member variables */ - typename GaussianFilterType::Pointer m_GaussianFilter; - typename SubstractFilterType::Pointer m_SubtractFilter; - typename MultiplyFilterType::Pointer m_MultiplyFilter; - typename AddFilterType::Pointer m_AddFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx deleted file mode 100644 index 51487470594..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ /dev/null @@ -1,193 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx -#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx - -#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" -#include "itkGaussianOperator.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarPreprocessingImageToImageFilter::KrcahEigenToScalarPreprocessingImageToImageFilter() - : m_Sigma(1.0f) - , m_ScalingConstant(10.0f) - , m_ReleaseInternalFilterData(true) -{ - /* Only need the input image */ - this->SetNumberOfRequiredInputs(1); - - /* Instantiate all filters */ - m_GaussianFilter = GaussianFilterType::New(); - m_SubtractFilter = SubstractFilterType::New(); - m_MultiplyFilter = MultiplyFilterType::New(); - m_AddFilter = AddFilterType::New(); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() throw( - InvalidRequestedRegionError) -{ - // This implementation is copied from itkDiscreteGaussianImageFilter - - // call the superclass' implementation of this method. this should - // copy the output requested region to the input requested region - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the input and output - typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); - - if (!inputPtr) - { - return; - } - - // Build an operator so that we can determine the kernel size - GaussianOperator oper; - - typename TInputImage::SizeType radius; - - for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) - { - // Determine the size of the operator in this dimension. Note that the - // Gaussian is built as a 1D operator in each of the specified directions. - oper.SetDirection(i); - if (m_GaussianFilter->GetUseImageSpacing() == true) - { - if (this->GetInput()->GetSpacing()[i] == 0.0) - { - itkExceptionMacro(<< "Pixel spacing cannot be zero"); - } - else - { - // convert the variance from physical units to pixels - double s = this->GetInput()->GetSpacing()[i]; - s = s * s; - oper.SetVariance(m_GaussianFilter->GetVariance()[i] / s); - } - } - else - { - oper.SetVariance(m_GaussianFilter->GetVariance()[i]); - } - oper.SetMaximumError(m_GaussianFilter->GetMaximumError()[i]); - oper.SetMaximumKernelWidth(m_GaussianFilter->GetMaximumKernelWidth()); - oper.CreateDirectional(); - - radius[i] = oper.GetRadius(i); - } - - // get a copy of the input requested region (should equal the output - // requested region) - typename TInputImage::RegionType inputRequestedRegion; - inputRequestedRegion = inputPtr->GetRequestedRegion(); - - // pad the input requested region by the operator radius - inputRequestedRegion.PadByRadius(radius); - - // crop the input requested region at the input's largest possible region - if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) - { - inputPtr->SetRequestedRegion(inputRequestedRegion); - return; - } - else - { - // Couldn't crop the region (requested region is outside the largest - // possible region). Throw an exception. - - // store what we tried to request (prior to trying to crop) - inputPtr->SetRequestedRegion(inputRequestedRegion); - - // build an exception - InvalidRequestedRegionError e(__FILE__, __LINE__); - e.SetLocation(ITK_LOCATION); - e.SetDescription("Requested region is (at least partially) outside the largest possible region."); - e.SetDataObject(inputPtr); - throw e; - } -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateData() -{ - /* Get Input */ - typename TInputImage::Pointer input = TInputImage::New(); - input->Graft(const_cast(this->GetInput())); - - /* I*G */ - m_GaussianFilter->SetInput(input); - m_GaussianFilter->SetVariance(Math::squared_magnitude(this->GetSigma())); - - /* I - I*G */ - m_SubtractFilter->SetInput1(input); - m_SubtractFilter->SetInput2(m_GaussianFilter->GetOutput()); - - /* k(I-(I*G)) */ - m_MultiplyFilter->SetInput(m_SubtractFilter->GetOutput()); - m_MultiplyFilter->SetConstant(this->GetScalingConstant()); - - /* I+k*(I-(I*G)) */ - m_AddFilter->SetInput1(input); - m_AddFilter->SetInput2(m_MultiplyFilter->GetOutput()); - - /* Release data if asked */ - if (this->GetReleaseInternalFilterData()) - { - m_GaussianFilter->ReleaseDataFlagOn(); - m_SubtractFilter->ReleaseDataFlagOn(); - m_MultiplyFilter->ReleaseDataFlagOn(); - m_AddFilter->ReleaseDataFlagOn(); - } - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_GaussianFilter, 0.25); - progress->RegisterInternalFilter(m_SubtractFilter, 0.25); - progress->RegisterInternalFilter(m_MultiplyFilter, 0.25); - progress->RegisterInternalFilter(m_AddFilter, 0.25); - - /* Graft Output */ - m_AddFilter->Update(); - this->GraftOutput(m_AddFilter->GetOutput()); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "GaussianFilter: " << m_GaussianFilter.GetPointer() << std::endl; - os << indent << "SubtractFilter: " << m_SubtractFilter.GetPointer() << std::endl; - os << indent << "MultiplyFilter: " << m_MultiplyFilter.GetPointer() << std::endl; - os << indent << "AddFilter: " << m_AddFilter.GetPointer() << std::endl; - os << indent << "Sigma: " << GetSigma() << std::endl; - os << indent << "ScalingConstant: " << GetScalingConstant() << std::endl; - os << indent << "ReleaseInternalFilterData: " << GetReleaseInternalFilterData() << std::endl; -} - -} // namespace itk - -#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index c7333b35b48..1772612551a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -81,7 +81,7 @@ class MaximumAbsoluteValue * \ingroup BoneEnhancement */ template -class MaximumAbsoluteValueImageFilter +class ITK_TEMPLATE_EXPORT MaximumAbsoluteValueImageFilter : public BinaryFunctorImageFilter SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Methods to set/get the mask image */ + itkSetInputMacro(ImageMask, SpatialObjectType); + itkGetInputMacro(ImageMask, SpatialObjectType); + /** Hessian related typedefs. */ - typedef HessianRecursiveGaussianImageFilter HessianFilterType; - typedef typename HessianFilterType::OutputImageType HessianImageType; - typedef typename HessianImageType::PixelType HessianPixelType; + // typedef HessianRecursiveGaussianImageFilter< TInputImage > HessianFilterType; + typedef HessianGaussianImageFilter HessianFilterType; + typedef typename HessianFilterType::OutputImageType HessianImageType; + typedef typename HessianImageType::PixelType HessianPixelType; + typedef typename HessianFilterType::InternalRealType InternalRealType; /** Eigenvalue analysis related typedefs. The ITK python wrapping usually wraps floating types * and not double types. For this reason, the eigenvalues are of type float. */ - typedef typename NumericTraits::RealType RealType; - typedef typename NumericTraits::FloatType FloatType; + typedef typename NumericTraits::RealType RealType; + typedef typename NumericTraits::FloatType FloatType; typedef Vector EigenValueArrayType; typedef Image EigenValueImageType; typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; @@ -96,17 +119,22 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Maximum over scale related typedefs. */ typedef MaximumAbsoluteValueImageFilter MaximumAbsoluteValueFilterType; - /** Eigenvalue image to scalar image related typedefs */ - typedef EigenToScalarImageFilter EigenToScalarImageFilterType; + /** Eigenvalue image to measure image related typedefs */ + typedef EigenToMeasureImageFilter EigenToMeasureImageFilterType; + typedef EigenToMeasureParameterEstimationFilter + EigenToMeasureParameterEstimationFilterType; /** Need some types to determine how to order the eigenvalues */ - // typedef typename Functor::SymmetricEigenAnalysisFunction::EigenValueOrderType InternalEigenValueOrderType; typedef typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType InternalEigenValueOrderType; - typedef typename EigenToScalarImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; + typedef typename EigenToMeasureImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; - /** Set/Get the EigenToScalarImageFilter. */ - itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); - itkGetModifiableObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); + /** Set/Get the EigenToMeasureImageFilter. */ + itkSetObjectMacro(EigenToMeasureImageFilter, EigenToMeasureImageFilterType); + itkGetModifiableObjectMacro(EigenToMeasureImageFilter, EigenToMeasureImageFilterType); + + /** Set/Get the EigenToMeasureParameterEstimationFilter. */ + itkSetObjectMacro(EigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilterType); + itkGetModifiableObjectMacro(EigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilterType); /** Sigma values. */ typedef RealType SigmaType; @@ -124,9 +152,9 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** * Static methods for generating an array of sigma values. Note that these still need to be passed - * into the class using SetSigmaArray . Implementation taken from itkMultiScaleHessianBasedMeasureImageFilter. + * into the class using SetSigmaArray. Implementation taken from itkMultiScaleHessianBasedMeasureImageFilter. * Note that these methods cannot throw exceptions according to the standard itkExceptionMacro since they are static - * methods. Instead, they will return an empty sigma array on error. + * methods. Instead, they will return an empty sigma array on error. TODO: Not ture any more. */ static Self::SigmaArrayType GenerateSigmaArray(SigmaType SigmaMinimum, @@ -144,7 +172,6 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image (Concept::SameDimension)); // End concept checking #endif - protected: MultiScaleHessianEnhancementImageFilter(); virtual ~MultiScaleHessianEnhancementImageFilter() {} @@ -165,6 +192,9 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image void GenerateInputRequestedRegion() ITK_OVERRIDE; + OutputImageRegionType + GetOutputRegion(); + /** Override since the filter produces all of its output */ void EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; @@ -174,10 +204,11 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image private: /** Internal filters. */ - typename HessianFilterType::Pointer m_HessianFilter; - typename EigenAnalysisFilterType::Pointer m_EigenAnalysisFilter; - typename MaximumAbsoluteValueFilterType::Pointer m_MaximumAbsoluteValueFilter; - typename EigenToScalarImageFilterType::Pointer m_EigenToScalarImageFilter; + typename HessianFilterType::Pointer m_HessianFilter; + typename EigenAnalysisFilterType::Pointer m_EigenAnalysisFilter; + typename MaximumAbsoluteValueFilterType::Pointer m_MaximumAbsoluteValueFilter; + typename EigenToMeasureImageFilterType::Pointer m_EigenToMeasureImageFilter; + typename EigenToMeasureParameterEstimationFilterType::Pointer m_EigenToMeasureParameterEstimationFilter; /** Sigma member variables. */ SigmaArrayType m_SigmaArray; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index bd8c859fc88..34946be8457 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -35,7 +35,8 @@ MultiScaleHessianEnhancementImageFilter::MultiScaleHe m_HessianFilter = HessianFilterType::New(); m_EigenAnalysisFilter = EigenAnalysisFilterType::New(); m_MaximumAbsoluteValueFilter = MaximumAbsoluteValueFilterType::New(); - m_EigenToScalarImageFilter = ITK_NULLPTR; // has to be provided by the user. + m_EigenToMeasureImageFilter = ITK_NULLPTR; // has to be provided by the user. + m_EigenToMeasureParameterEstimationFilter = ITK_NULLPTR; // has to be provided by the user. /* We require an input image */ this->SetNumberOfRequiredInputs(1); @@ -46,11 +47,16 @@ void MultiScaleHessianEnhancementImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); - if (this->GetInput()) + + // get pointers to the input + typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) { - typename TInputImage::Pointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); + return; } + + inputPtr->SetRequestedRegionToLargestPossibleRegion(); } template @@ -58,7 +64,38 @@ void MultiScaleHessianEnhancementImageFilter::EnlargeOutputRequestedRegion(DataObject * data) { Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); + OutputImagePointer imgData = dynamic_cast(data); + + // if ( this->GetInput() ) + // { + // OutputImageRegionType region = this->GetOutputRegion(); + // // crop the input requested region at the input's largest possible region + // if ( region.Crop( imgData->GetLargestPossibleRegion() ) ) + // { + // imgData->SetRequestedRegion(region); + // return; + // } + // else + // { + // // Couldn't crop the region (requested region is outside the largest + // // possible region). Throw an exception. + + // // store what we tried to request (prior to trying to crop) + // imgData->SetRequestedRegion(region); + + // // build an exception + // InvalidRequestedRegionError e(__FILE__, __LINE__); + // e.SetLocation(ITK_LOCATION); + // e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + // e.SetDataObject(imgData); + // throw e; + // } + // } + // else + if (imgData) + { + imgData->SetRequestedRegionToLargestPossibleRegion(); + } } template @@ -66,9 +103,14 @@ void MultiScaleHessianEnhancementImageFilter::GenerateData() { /* Test all inputs are set */ - if (!m_EigenToScalarImageFilter) + if (!m_EigenToMeasureImageFilter) { - itkExceptionMacro(<< "EigenToScalarImageFilter is not present"); + itkExceptionMacro(<< "m_EigenToMeasureImageFilter is not present"); + } + + if (!m_EigenToMeasureParameterEstimationFilter) + { + itkExceptionMacro(<< "m_EigenToMeasureParameterEstimationFilter is not present"); } if (m_SigmaArray.GetSize() < 1) @@ -80,17 +122,29 @@ MultiScaleHessianEnhancementImageFilter::GenerateData /* Set filters parameters */ m_HessianFilter->SetNormalizeAcrossScale(true); m_EigenAnalysisFilter->SetDimension(ImageDimension); - m_EigenAnalysisFilter->OrderEigenValuesBy(this->ConvertType(m_EigenToScalarImageFilter->GetEigenValueOrder())); + m_EigenAnalysisFilter->OrderEigenValuesBy(this->ConvertType(m_EigenToMeasureImageFilter->GetEigenValueOrder())); /* Connect filters */ m_HessianFilter->SetInput(this->GetInput()); m_EigenAnalysisFilter->SetInput(m_HessianFilter->GetOutput()); - m_EigenToScalarImageFilter->SetInput(m_EigenAnalysisFilter->GetOutput()); + m_EigenToMeasureParameterEstimationFilter->SetInput(m_EigenAnalysisFilter->GetOutput()); + m_EigenToMeasureImageFilter->SetInput(m_EigenToMeasureParameterEstimationFilter->GetOutput()); + m_EigenToMeasureImageFilter->SetParametersInput(m_EigenToMeasureParameterEstimationFilter->GetParametersOutput()); + + /* Set the mask */ + SpatialObjectConstPointer mask = this->GetImageMask(); + if (mask) + { + m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); + m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); + } /* After executing we want to release data to save memory */ - m_HessianFilter->ReleaseDataFlagOn(); - m_EigenAnalysisFilter->ReleaseDataFlagOn(); - m_EigenToScalarImageFilter->ReleaseDataFlagOn(); + // m_HessianFilter->ReleaseDataFlagOn(); + // m_EigenAnalysisFilter->ReleaseDataFlagOn(); + // m_EigenToMeasureImageFilter->ReleaseDataFlagOn(); + // m_EigenToMeasureParameterEstimationFilter->ReleaseDataFlagOn(); + // m_MaximumAbsoluteValueFilter->ReleaseDataFlagOn(); /* Setup progress reporter */ ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); @@ -100,16 +154,20 @@ MultiScaleHessianEnhancementImageFilter::GenerateData * We checked that m_SigmaArray.GetSize() > 0 above and do not need to repeat the check. However, * if we are only given one sigma value we do not need to take the maximum over scales. * - * Three filters, ran m_SigmaArray.GetSize() times + * Two filters, ran m_SigmaArray.GetSize() times * One filter, ran (m_SigmaArray.GetSize() - 1) times + * + * We do not count the hessian or eigenanalysis filters since they will be streamed many times. */ - float numberOfFiltersToProcess = 3 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); + float numberOfFiltersToProcess = 2 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); - progress->RegisterInternalFilter(m_HessianFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenAnalysisFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenToScalarImageFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); + + progress->RegisterInternalFilter(m_EigenToMeasureParameterEstimationFilter, + 1.5 * m_SigmaArray.GetSize() * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToMeasureImageFilter, + 0.5 * m_SigmaArray.GetSize() * perFilterProccessPercentage); /* Check if we need to run the MaximumAbsoluteValueFilter at all */ if (m_SigmaArray.GetSize() > 1) @@ -123,28 +181,29 @@ MultiScaleHessianEnhancementImageFilter::GenerateData } /* We store a single pointer that we will graft to the output */ - typename TOutputImage::Pointer outputImageTypePointer; + typename TOutputImage::Pointer outputImagePointer; /* Process the first scale */ - outputImageTypePointer = generateResponseAtScale((SigmaStepsType)0); + outputImagePointer = generateResponseAtScale((SigmaStepsType)0); /* Process the remaining sigma values */ for (SigmaStepsType scaleLevel = 1; scaleLevel < m_SigmaArray.GetSize(); ++scaleLevel) { /* Calculate next response value */ - typename TOutputImage::Pointer tempResponseOutputImageTypePointer = generateResponseAtScale(scaleLevel); + typename TOutputImage::Pointer tempResponseImagePointer = generateResponseAtScale(scaleLevel); /* Take absolute value maximum */ - m_MaximumAbsoluteValueFilter->SetInput1(outputImageTypePointer); - m_MaximumAbsoluteValueFilter->SetInput2(tempResponseOutputImageTypePointer); + m_MaximumAbsoluteValueFilter->SetInput1(outputImagePointer); + m_MaximumAbsoluteValueFilter->SetInput2(tempResponseImagePointer); + // m_MaximumAbsoluteValueFilter->GetOutput()->SetRequestedRegion(this->GetOutputRegion()); m_MaximumAbsoluteValueFilter->Update(); /* Save max and go to next sigma value */ - outputImageTypePointer = m_MaximumAbsoluteValueFilter->GetOutput(); + outputImagePointer = m_MaximumAbsoluteValueFilter->GetOutput(); } /* Graft output and we're done! */ - this->GraftOutput(outputImageTypePointer); + this->GraftOutput(outputImagePointer); } template @@ -156,8 +215,40 @@ MultiScaleHessianEnhancementImageFilter::generateResp /* Process pipeline and return */ m_HessianFilter->SetSigma(thisSigma); - m_EigenToScalarImageFilter->Update(); - return m_EigenToScalarImageFilter->GetOutput(); + // m_EigenToMeasureImageFilter->GetOutput()->SetRequestedRegion(this->GetOutputRegion()); + m_EigenToMeasureImageFilter->Update(); + return m_EigenToMeasureImageFilter->GetOutput(); +} + +template +typename MultiScaleHessianEnhancementImageFilter::OutputImageRegionType +MultiScaleHessianEnhancementImageFilter::GetOutputRegion() +{ + /* Create region */ + OutputImageRegionType region; + + /* Get and test input */ + InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) + { + itkExceptionMacro(<< "Input image must be set to run this filter."); + } + region = inputPtr->GetLargestPossibleRegion(); + + /* Grab the mask pointer */ + SpatialObjectConstPointer mask = this->GetImageMask(); + if (!mask) + { + // No mask was set so we need to estimate parameters across the whole image + return region; + } + + /* Crop the region */ + typename SpatialObjectType::RegionType maskRegion = mask->GetAxisAlignedBoundingBoxRegion(); + region.Crop(maskRegion); + + return region; } template @@ -249,11 +340,11 @@ MultiScaleHessianEnhancementImageFilter::ConvertType( { switch (order) { - case EigenToScalarImageFilterType::OrderByValue: + case EigenToMeasureImageFilterType::OrderByValue: return EigenAnalysisFilterType::FunctorType::OrderByValue; - case EigenToScalarImageFilterType::OrderByMagnitude: + case EigenToMeasureImageFilterType::OrderByMagnitude: return EigenAnalysisFilterType::FunctorType::OrderByMagnitude; - case EigenToScalarImageFilterType::DoNotOrder: + case EigenToMeasureImageFilterType::DoNotOrder: return EigenAnalysisFilterType::FunctorType::DoNotOrder; default: itkExceptionMacro(<< "Trying to convert bad order " << order); @@ -268,7 +359,9 @@ MultiScaleHessianEnhancementImageFilter::PrintSelf(st os << indent << "HessianFilter: " << m_HessianFilter.GetPointer() << std::endl; os << indent << "EigenAnalysisFilter: " << m_EigenAnalysisFilter.GetPointer() << std::endl; os << indent << "MaximumAbsoluteValueFilter: " << m_MaximumAbsoluteValueFilter.GetPointer() << std::endl; - os << indent << "EigenToScalarImageFilter: " << m_EigenToScalarImageFilter.GetPointer() << std::endl; + os << indent << "EigenToMeasureImageFilter: " << m_EigenToMeasureImageFilter.GetPointer() << std::endl; + os << indent << "EigenToMeasureParameterEstimationFilter: " << m_EigenToMeasureParameterEstimationFilter.GetPointer() + << std::endl; os << indent << "SigmaArray: " << m_SigmaArray << std::endl; } diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 80fec36e66d..330740fa631 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -32,9 +32,7 @@ itk_add_test( set( BoneEnhancementUnitTests - itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx - itkDescoteauxEigenToMeasureFunctorUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx ) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx deleted file mode 100644 index f30077f7e74..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx +++ /dev/null @@ -1,276 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureImageFilter.h" - -namespace -{ -template -class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test -{ -public: - /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenImageType; - typedef itk::Image ImageType; - typedef typename itk::Functor::DescoteauxEigenToMeasureFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - - itkDescoteauxEigenToMeasureFunctorUnitTest() - { - m_Functor = FunctorType(); - m_EigenPixel = EigenValueArrayType(); - } - ~itkDescoteauxEigenToMeasureFunctorUnitTest() override {} - -protected: - void - SetUp() override - {} - void - TearDown() override - {} - - FunctorType m_Functor; - EigenValueArrayType m_EigenPixel; - ParameterType m_Parameters; -}; -} // namespace - -// Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; -TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) -{ - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetEnhanceType) -{ - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - this->m_Functor.SetEnhanceDarkObjects(); - EXPECT_DOUBLE_EQ(1.0, this->m_Functor.GetEnhanceType()); - this->m_Functor.SetEnhanceBrightObjects(); - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetParameters) -{ - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); - - this->m_Parameters[0] = 100; - this->m_Parameters[1] = 200; - this->m_Parameters[2] = 300; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(100.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(200.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(300.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFirstParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFirstParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSecondParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSecondParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightThirdParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkThirdParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFourthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFourthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFifthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFifthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSixthParameterSet) -{ - this->m_Parameters[0] = 0.25; - this->m_Parameters[1] = 0.25; - this->m_Parameters[2] = 0.5; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSixthParameterSet) -{ - this->m_Parameters[0] = 0.25; - this->m_Parameters[1] = 0.25; - this->m_Parameters[2] = 0.5; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx index 78bb12a4925..b64a9026f93 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -38,15 +38,18 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test typedef itk::ImageMaskSpatialObject SpatialObjectType; typedef itk::Image MaskImageType; typedef typename itk::DescoteauxEigenToMeasureImageFilter - FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterType ParameterType; + FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; itkDescoteauxEigenToMeasureImageFilterUnitTest() { /* Instantiate filter */ m_Filter = FilterType::New(); + /* Set parameter size */ + m_Parameters.SetSize(3); + /* Create EigenPixels */ for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) { @@ -154,7 +157,7 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test EigenValueArrayType m_ZeroEigenPixel; EigenValueArrayType m_NonZeroEigenPixel; EigenValueArrayType m_NonZeroDarkEigenPixel; - ParameterType m_Parameters; + ParameterArrayType m_Parameters; typename EigenImageType::RegionType m_Region; typename EigenImageType::RegionType m_MaskRegion; typename SpatialObjectType::Pointer m_SpatialObject; @@ -202,7 +205,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelBri this->m_Parameters[2] = 0.25; this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -225,7 +227,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelDar this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); this->m_Filter->SetEnhanceDarkObjects(); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -247,7 +248,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe this->m_Parameters[2] = 0.25; this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -270,7 +270,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); this->m_Filter->SetEnhanceDarkObjects(); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -293,7 +292,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx index 07913da2dda..82477c99be6 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -36,8 +36,8 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te typedef itk::ImageMaskSpatialObject SpatialObjectType; typedef itk::Image MaskImageType; typedef typename itk::DescoteauxEigenToMeasureParameterEstimationFilter FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterType ParameterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() { @@ -138,14 +138,14 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te EigenValueArrayType m_OneEigenPixel; EigenValueArrayType m_ZeroEigenPixel; EigenValueArrayType m_LargeEigenPixel; - ParameterType m_Parameters; + ParameterArrayType m_Parameters; typename EigenImageType::RegionType m_Region; typename SpatialObjectType::Pointer m_SpatialObject; }; } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +typedef ::testing::Types TestingLabelTypes; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) @@ -153,9 +153,9 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, Initial EXPECT_DOUBLE_EQ(0.5, this->m_Filter->GetFrobeniusNormWeight()); this->m_Parameters = this->m_Filter->GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(1.0, this->m_Parameters[2]); } TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImage) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx deleted file mode 100644 index c4583e6f8a3..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx +++ /dev/null @@ -1,141 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" - -namespace -{ -template -class itkDescoteauxEigenToMeasureParameterFunctorUnitTest : public ::testing::Test -{ -public: - /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Functor::DescoteauxEigenToMeasureParameterFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - - itkDescoteauxEigenToMeasureParameterFunctorUnitTest() - { - m_Functor = FunctorType(); - m_EigenPixel = EigenValueArrayType(); - } - ~itkDescoteauxEigenToMeasureParameterFunctorUnitTest() override {} - -protected: - void - SetUp() override - {} - void - TearDown() override - {} - - FunctorType m_Functor; - EigenValueArrayType m_EigenPixel; - ParameterType m_Parameters; -}; -} // namespace - -// Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; -TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestingLabelTypes); - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, InitialParameters) -{ - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, SetGetFrobeniusNormWeight) -{ - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - this->m_Functor.SetFrobeniusNormWeight(0.1); - EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfZero) -{ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOne) -{ - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOneWithDifferentWeight) -{ - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - this->m_Functor.SetFrobeniusNormWeight(0.1); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestMultiplePixels) -{ - unsigned int num = 10; - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(num); - for (unsigned int i = 0; i < num; ++i) - { - for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) - { - this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; - } - - this->m_Functor.ProcessPixel(this->m_EigenPixel, i); - } - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx deleted file mode 100644 index a19558ef20e..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx +++ /dev/null @@ -1,121 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" -#include "itkUnaryFunctorImageFilter.h" -#include "itkTestingMacros.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkMath.h" - -int -itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) -{ - /* typedefs, instantiate filter */ - const unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; - - typedef double EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; - - typedef itk::DescoteauxEigenToScalarFunctorImageFilter FilterType; - FilterType::Pointer descoFilter = FilterType::New(); - - /* Basic tests. Need to set parameters first. */ - descoFilter->SetAlpha(0.5); - descoFilter->SetBeta(0.5); - descoFilter->SetC(0.25); - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /* Exercise basic set/get methods */ - descoFilter->SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetAlpha()); - descoFilter->SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetBeta()); - descoFilter->SetC(0.25); - TEST_SET_GET_VALUE(0.25, descoFilter->GetC()); - // Default should be 1 - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); - descoFilter->SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, descoFilter->GetEnhanceType()); - descoFilter->SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, 0); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - itk::ImageRegionIteratorWithIndex input(descoFilter->GetOutput(), region); - - input.GoToBegin(); - while (!input.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); - ++input; - } - - /* Create some test data which is computable */ - simpleEigenPixel.SetElement(0, 0.25); - simpleEigenPixel.SetElement(1, 1); - simpleEigenPixel.SetElement(2, -1); - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - descoFilter->SetInput(image2); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - itk::ImageRegionIteratorWithIndex input2(descoFilter->GetOutput(), region); - - input2.GoToBegin(); - while (!input2.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.0913983433747, 6, 0.000001)); - ++input2; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx deleted file mode 100644 index 5f8655d174c..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ /dev/null @@ -1,121 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" -#include "itkTestingMacros.h" - -int -itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) -{ - /* typedefs, instantiate functor */ - const unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; - - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; - - typedef itk::Functor::DescoteauxEigenToScalarFunctor FunctorType; - FunctorType functor = FunctorType(); - - /* Exercise basic set/get methods */ - functor.SetAlpha(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetAlpha()); - functor.SetBeta(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetBeta()); - functor.SetC(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetC()); - // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); - functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - - /* Test a few calculations */ - EigenValueArrayType mEigenValueArray; - functor.SetAlpha(0.5); - functor.SetBeta(0.5); - functor.SetC(0.25); - functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* Return zero on positive l3 with bright sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* Return zero on positive l3 with dark sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = -1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 0, 0, -1; bright sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); - - /* 0, 0, 1; dark sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); - - /* 1, 1, -1; bright sheets */ - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 1, 1, 1; dark sheets */ - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 0.25, 1, -1; bright sheets */ - mEigenValueArray[0] = 0.25; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); - - /* 0.25, 1, 1; dark sheets */ - mEigenValueArray[0] = 0.25; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx deleted file mode 100644 index 2d88d8608a8..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx +++ /dev/null @@ -1,94 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) -{ - const unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; - - typedef double OutputPixelType; - typedef itk::Image OutputType; - - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; - - typedef itk::DescoteauxEigenToScalarImageFilter - DescoteauxEigenToScalarImageFilterType; - - DescoteauxEigenToScalarImageFilterType::Pointer descoFilter = DescoteauxEigenToScalarImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - - /* Test defaults */ - TEST_EXPECT_EQUAL(descoFilter->GetEigenValueOrder(), - DescoteauxEigenToScalarImageFilterType::Superclass::OrderByMagnitude); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - simpleEigenPixel.SetElement(0, 0.5); - simpleEigenPixel.SetElement(1, 1.25); - simpleEigenPixel.SetElement(2, -2); - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - /* Run with no exceptions */ - descoFilter->SetEnhanceBrightObjects(); - descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetC(), 2.41091269 * 0.5, 6, 0.000001)); - - itk::ImageRegionIteratorWithIndex it(descoFilter->GetOutput(), region); - - it.GoToBegin(); - while (!it.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.364376944099, 6, 0.000001)); - ++it; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx deleted file mode 100644 index 2d1ad1045c3..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ /dev/null @@ -1,170 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) -{ - const unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; - - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; - - typedef itk::DescoteauxEigenToScalarParameterEstimationImageFilter - DescoteauxEigenToScalarParameterEstimationImageFilterType; - - DescoteauxEigenToScalarParameterEstimationImageFilterType::Pointer descoteauxParameterEstimator = - DescoteauxEigenToScalarParameterEstimationImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS( - descoteauxParameterEstimator, DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /* Test defaults */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetCOutput()->Get(), 0.5, 6, 0.000001)); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, -1); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - EigenValueImageType::IndexType maskStart; - maskStart[0] = 2; - maskStart[1] = 2; - maskStart[2] = 2; - - EigenValueImageType::SizeType maskSize; - maskSize[0] = 8; - maskSize[1] = 8; - maskSize[2] = 8; - - MaskPixelType backgroundValue = 1; - MaskPixelType foregroundValue = 2; - MaskType::Pointer mask = MaskType::New(); - mask->SetRegions(region); - mask->Allocate(); - mask->FillBuffer(backgroundValue); - - EigenValueArrayType newEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - newEigenPixel.SetElement(i, 3); - } - - EigenValueImageType::RegionType maskRegion; - maskRegion.SetSize(maskSize); - maskRegion.SetIndex(maskStart); - - itk::ImageRegionIteratorWithIndex input2It(image2, maskRegion); - itk::ImageRegionIteratorWithIndex maskIt(mask, maskRegion); - - input2It.GoToBegin(); - maskIt.GoToBegin(); - while (!input2It.IsAtEnd()) - { - input2It.Set(newEigenPixel); - maskIt.Set(foregroundValue); - ++input2It; - ++maskIt; - } - - /* Test an empty pixel value */ - descoteauxParameterEstimator->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - /* Test an empty pixel value */ - descoteauxParameterEstimator->SetFrobeniusNormWeight(0.25); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.25, 6, 0.000001)); - - /* Test with a mask */ - descoteauxParameterEstimator->SetInput(image2); - descoteauxParameterEstimator->SetMaskImage(mask); - descoteauxParameterEstimator->SetBackgroundValue(foregroundValue); - descoteauxParameterEstimator->SetFrobeniusNormWeight(0.5); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - descoteauxParameterEstimator->SetInput(image2); - descoteauxParameterEstimator->SetMaskImage(mask); - descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); - - MaskType::Pointer mask2 = MaskType::New(); - mask2->SetRegions(maskRegion); - mask2->Allocate(); - mask2->FillBuffer(foregroundValue); - - descoteauxParameterEstimator->SetInput(image); - descoteauxParameterEstimator->SetMaskImage(mask2); - descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx deleted file mode 100644 index 4a32f05c0ca..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ /dev/null @@ -1,155 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarFunctorImageFilter.h" -#include "itkTestingMacros.h" - -int -itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) -{ - /* typedefs, instantiate functor */ - const unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; - - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; - - typedef itk::Functor::KrcahEigenToScalarFunctor FunctorType; - FunctorType functor = FunctorType(); - - /* Exercise basic set/get methods */ - functor.SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetAlpha()); - functor.SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetBeta()); - functor.SetGamma(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetGamma()); - // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); - functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - - /* Test a few calculations */ - EigenValueArrayType mEigenValueArray; - functor.SetAlpha(0.5); - functor.SetBeta(0.5); - functor.SetGamma(0.25); - functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* lambda_2 zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* lambda_1 zero */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.0183156368276, 6, 0.000001)); - - /* lambda_1 zero; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0183156368276, 6, 0.000001)); - - /* one, one, one */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); - - /* one, one, one; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); - - /* one, one, one negative */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -1; - mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); - - /* one, one, one negative; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -1; - mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); - - /* -1, -2, 3 */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -2; - mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.15123975969, 6, 0.000001)); - - /* -1, -2, 3; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -2; - mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.15123975969, 6, 0.000001)); - - /* Perfect Joint */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1000; - mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); - - /* Perfect Joint; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1000; - mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); - - /* Perfect Bone */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = -1000; - mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); - - /* Perfect Bone; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = -1000; - mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx deleted file mode 100644 index 70e75c2cf74..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx +++ /dev/null @@ -1,43 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" -#include "itkTestingMacros.h" - -int -itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) -{ - const unsigned int Dimension = 3; - typedef char InputPixelType; - typedef itk::Image InputImageType; - - typedef itk::KrcahEigenToScalarPreprocessingImageToImageFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - - /* Basic test */ - EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); - - /* Default parameters */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetScalingConstant(), 10.0, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetSigma(), 1.0, 6, 0.000001)); - TEST_EXPECT_TRUE(filter->GetReleaseInternalFilterData()); - - /* TODO: Regression test */ - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap deleted file mode 100644 index d5ce1a5acc1..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,13 +0,0 @@ -itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap deleted file mode 100644 index 4f4a7ee5eb9..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,11 +0,0 @@ -itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap deleted file mode 100644 index 273175aba3b..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,22 +0,0 @@ -itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t3}3}") - endforeach() -endforeach() -itk_end_wrap_class() - -itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap deleted file mode 100644 index 588cba91429..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap +++ /dev/null @@ -1,3 +0,0 @@ -itk_wrap_class("itk::KrcahEigenToScalarPreprocessingImageToImageFilter" POINTER_WITH_SUPERCLASS) -itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}") -itk_end_wrap_class() From f7c50dfed347e04f7bd008b46a93386a5e0c8a25 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 16:56:38 -0700 Subject: [PATCH 063/150] ENH: Move itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 9 +- ...nhancementImageFilterStaticMethodsTest.cxx | 123 ------------- ...cementImageFilterStaticMethodsUnitTest.cxx | 163 ++++++++++++++++++ 3 files changed, 164 insertions(+), 131 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 330740fa631..2bfc4e9a0ea 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -3,7 +3,6 @@ itk_module_test() set( BoneEnhancementTests itkMaximumAbsoluteValueImageFilterTest.cxx - itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx itkHessianGaussianImageFilterTest.cxx ) @@ -16,13 +15,6 @@ itk_add_test( itkMaximumAbsoluteValueImageFilterTest ) -itk_add_test( - NAME itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest - COMMAND - BoneEnhancementTestDriver - itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest -) - itk_add_test( NAME itkHessianGaussianImageFilterTest COMMAND @@ -34,6 +26,7 @@ set( BoneEnhancementUnitTests itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx + itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx deleted file mode 100644 index 81dee7c62f9..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ /dev/null @@ -1,123 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkMultiScaleHessianEnhancementImageFilter.h" -#include "itkArray.h" -#include "itkTestingMacros.h" -#include "itkMath.h" - -int -itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) -{ - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; - - /* Test the two cases of step size zero */ - ArrayType sigmaArray; - bool exceptionCaught = false; - try - { - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0); - } - catch (itk::ExceptionObject & err) - { - exceptionCaught = true; - } - TEST_EXPECT_TRUE(exceptionCaught); - exceptionCaught = false; - try - { - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0); - } - catch (itk::ExceptionObject & err) - { - exceptionCaught = true; - } - TEST_EXPECT_TRUE(exceptionCaught); - - /* Test that we get one when min equals max */ - ArrayType expectedOneSigmaArray; - expectedOneSigmaArray.SetSize(1); - expectedOneSigmaArray.SetElement(0, 1); - - /* Test the two cases of min equals max with a large number of values */ - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); - - /* Test the Logarithmic method */ - ArrayType expectedLogarithmicArray; - expectedLogarithmicArray.SetSize(5); - expectedLogarithmicArray.SetElement(0, 1); - expectedLogarithmicArray.SetElement(1, 1.4953487812212205); - expectedLogarithmicArray.SetElement(2, 2.23606797749979); - expectedLogarithmicArray.SetElement(3, 3.3437015248821096); - expectedLogarithmicArray.SetElement(4, 5); - - ArrayType logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); - /* Here we need to do some floating point comparisons */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); - } - - logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); - /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); - } - - /* Test the Equidistance method */ - ArrayType expectedEquidistanceArray; - expectedEquidistanceArray.SetSize(5); - expectedEquidistanceArray.SetElement(0, 1.0); - expectedEquidistanceArray.SetElement(1, 2.0); - expectedEquidistanceArray.SetElement(2, 3.0); - expectedEquidistanceArray.SetElement(3, 4.0); - expectedEquidistanceArray.SetElement(4, 5.0); - - ArrayType equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); - /* Here we need to do some floating point comparisons. These are exact, but we should still do a floating point - * comparison to be sure */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( - expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); - } - - equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); - /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( - expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx new file mode 100644 index 00000000000..206d1f91761 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx @@ -0,0 +1,163 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkMultiScaleHessianEnhancementImageFilter.h" +#include "gtest/gtest.h" +#include "itkMath.h" + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithSizeZero) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + ArrayType sigmaArray; + EXPECT_ANY_THROW(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); + EXPECT_ANY_THROW(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithMinEqualMax) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Test that we get one when min equals max */ + ArrayType expectedOneSigmaArray; + expectedOneSigmaArray.SetSize(1); + expectedOneSigmaArray.SetElement(0, 1); + + /* Test the two cases of min equals max with a large number of values */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); + EXPECT_EQ(expectedOneSigmaArray, sigmaArray); + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); + EXPECT_EQ(expectedOneSigmaArray, sigmaArray); +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArray) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 2); + expectedArray.SetElement(2, 3); + expectedArray.SetElement(3, 4); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArrayWithFlip) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 2); + expectedArray.SetElement(2, 3); + expectedArray.SetElement(3, 4); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArray) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 1.4953487812212205); + expectedArray.SetElement(2, 2.23606797749979); + expectedArray.SetElement(3, 3.3437015248821096); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArrayWithFlip) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 1.4953487812212205); + expectedArray.SetElement(2, 2.23606797749979); + expectedArray.SetElement(3, 3.3437015248821096); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} From 457fd44233666d9132b5db2040d4c648d7b05a39 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 17:07:28 -0700 Subject: [PATCH 064/150] ENH: Move itkMaximumAbsoluteValueImageFilterTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 16 +++------------ ...ximumAbsoluteValueImageFilterUnitTest.cxx} | 20 +++++++------------ 2 files changed, 10 insertions(+), 26 deletions(-) rename Modules/Filtering/BoneEnhancement/test/{itkMaximumAbsoluteValueImageFilterTest.cxx => itkMaximumAbsoluteValueImageFilterUnitTest.cxx} (87%) diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 2bfc4e9a0ea..31ea20400b2 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -1,20 +1,9 @@ itk_module_test() -set( - BoneEnhancementTests - itkMaximumAbsoluteValueImageFilterTest.cxx - itkHessianGaussianImageFilterTest.cxx -) +set(BoneEnhancementTests itkHessianGaussianImageFilterTest.cxx) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") -itk_add_test( - NAME itkMaximumAbsoluteValueImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkMaximumAbsoluteValueImageFilterTest -) - itk_add_test( NAME itkHessianGaussianImageFilterTest COMMAND @@ -24,9 +13,10 @@ itk_add_test( set( BoneEnhancementUnitTests + itkMaximumAbsoluteValueImageFilterUnitTest.cxx + itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx - itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx similarity index 87% rename from Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx rename to Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx index 209c5c71506..19989844a68 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx @@ -17,11 +17,10 @@ *=========================================================================*/ #include "itkMaximumAbsoluteValueImageFilter.h" -#include "itkTestingMacros.h" +#include "gtest/gtest.h" #include "itkImageRegionIterator.h" -int -itkMaximumAbsoluteValueImageFilterTest(int, char *[]) +TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) { const unsigned int Dimension = 2; typedef int PixelType; @@ -29,12 +28,9 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); - /** Create an image and run a basic test */ ImageType::RegionType region; ImageType::IndexType start; - start[0] = 0; start[1] = 0; @@ -53,6 +49,7 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) image2->SetRegions(region); image2->Allocate(); + /* Iterate over images and set */ typedef itk::ImageRegionIterator IteratorType; IteratorType it1(image1, region); IteratorType it2(image2, region); @@ -75,9 +72,10 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) ++it2; } + /* Apply filter */ maxAbsFilter->SetInput1(image1); maxAbsFilter->SetInput2(image2); - maxAbsFilter->Update(); + EXPECT_NO_THROW(maxAbsFilter->Update()); ImageType::Pointer outputImage = maxAbsFilter->GetOutput(); IteratorType ot(outputImage, region); @@ -87,16 +85,12 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) { if ((i % 2) == 0) { - TEST_EXPECT_EQUAL(ot.Get(), -2); + EXPECT_EQ(ot.Get(), -2); } else { - TEST_EXPECT_EQUAL(ot.Get(), 2); + EXPECT_EQ(ot.Get(), 2); } ++ot; } - - /** TODO: Write an integration test */ - - return EXIT_SUCCESS; } From 460087699352bc78c7a6c94a626eaf645302203e Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 17:12:04 -0700 Subject: [PATCH 065/150] ENH: Move itkHessianGaussianImageFilterTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 16 +++++------ ...itkHessianGaussianImageFilterUnitTest.cxx} | 28 ++++++------------- 2 files changed, 17 insertions(+), 27 deletions(-) rename Modules/Filtering/BoneEnhancement/test/{itkHessianGaussianImageFilterTest.cxx => itkHessianGaussianImageFilterUnitTest.cxx} (61%) diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 31ea20400b2..6d723fe1718 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -1,19 +1,19 @@ itk_module_test() -set(BoneEnhancementTests itkHessianGaussianImageFilterTest.cxx) +# set(BoneEnhancementTests +# itkHessianGaussianImageFilterTest.cxx +# ) -createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") +# CreateTestDriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") -itk_add_test( - NAME itkHessianGaussianImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkHessianGaussianImageFilterTest -) +# itk_add_test(NAME itkHessianGaussianImageFilterTest +# COMMAND BoneEnhancementTestDriver itkHessianGaussianImageFilterTest +# ) set( BoneEnhancementUnitTests itkMaximumAbsoluteValueImageFilterUnitTest.cxx + itkHessianGaussianImageFilterUnitTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx similarity index 61% rename from Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx rename to Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx index 186ab1f10cf..4563e8203d4 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx @@ -17,36 +17,26 @@ *=========================================================================*/ #include "itkHessianGaussianImageFilter.h" -#include "itkUnaryFunctorImageFilter.h" -#include "itkTestingMacros.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkMath.h" +#include "gtest/gtest.h" -int -itkHessianGaussianImageFilterTest(int argc, char * argv[]) +TEST(itkHessianGaussianImageFilterTest, ExerciseBasicMethods) { const unsigned int Dimension = 2; typedef int PixelType; typedef itk::Image ImageType; typedef itk::HessianGaussianImageFilter HessianGaussianImageFilterType; - - HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); - - /* Basic tests. */ - EXERCISE_BASIC_OBJECT_METHODS(hess_filter, HessianGaussianImageFilter, ImageToImageFilter); + HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); /* Exercise basic set/get methods */ - TEST_SET_GET_VALUE(1.0, hess_filter->GetSigma()); + EXPECT_EQ(1.0, hess_filter->GetSigma()) << "Initial value of Sigma should be 1"; hess_filter->SetSigma(0.5); - TEST_SET_GET_VALUE(0.5, hess_filter->GetSigma()); + EXPECT_EQ(0.5, hess_filter->GetSigma()); - TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(false, hess_filter->GetNormalizeAcrossScale()) << "Initial value of NormalizeAcrossScale should be false"; hess_filter->SetNormalizeAcrossScale(true); - TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(true, hess_filter->GetNormalizeAcrossScale()); hess_filter->NormalizeAcrossScaleOff(); - TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(false, hess_filter->GetNormalizeAcrossScale()); hess_filter->NormalizeAcrossScaleOn(); - TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); - - return EXIT_SUCCESS; + EXPECT_EQ(true, hess_filter->GetNormalizeAcrossScale()); } From eb3f81a1ebd1e6d14f90b65990593edbc3f1aa50 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 5 Mar 2018 12:18:12 -0700 Subject: [PATCH 066/150] ENH: Remove ITKReview module --- Modules/Filtering/BoneEnhancement/itk-module.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/itk-module.cmake b/Modules/Filtering/BoneEnhancement/itk-module.cmake index 511c4ba5f46..f019f3e57c3 100644 --- a/Modules/Filtering/BoneEnhancement/itk-module.cmake +++ b/Modules/Filtering/BoneEnhancement/itk-module.cmake @@ -15,7 +15,6 @@ itk_module( ITKStatistics ITKImageFilterBase ITKImageFeature - ITKReview ITKSpatialObjects COMPILE_DEPENDS ITKImageSources From e2e1d9017e62b1a434b6825d984c5895c197e54c Mon Sep 17 00:00:00 2001 From: Pablo Hernandez-Cerdan Date: Mon, 24 Sep 2018 14:51:32 -0400 Subject: [PATCH 067/150] COMP: Remove deprecated throw specification ``` warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] throw( InvalidRequestedRegionError ) ``` --- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.h | 2 +- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index ea75044d05c..11e420471f8 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -104,7 +104,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter * order to inform the pipeline execution model. * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ virtual void - GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + GenerateInputRequestedRegion(); #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx index 51487470594..eddf59a3679 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx @@ -44,8 +44,7 @@ KrcahEigenToScalarPreprocessingImageToImageFilter void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() throw( - InvalidRequestedRegionError) +KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() { // This implementation is copied from itkDiscreteGaussianImageFilter From 5b83b02511ddf7f0753d9c8daf0d510f8641e07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 23:07:40 -0400 Subject: [PATCH 068/150] ENH: TYLE: Prefer constexpr for const numeric literals Use constexpr for constant numeric literals. --- .../test/itkDescoteauxEigenToScalarFunctorImageTest.cxx | 2 +- .../test/itkDescoteauxEigenToScalarFunctorTest.cxx | 2 +- .../test/itkDescoteauxEigenToScalarImageFilterTest.cxx | 2 +- ...escoteauxEigenToScalarParameterEstimationImageFilterTest.cxx | 2 +- .../test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx | 2 +- .../BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx | 2 +- .../test/itkKrcahEigenToScalarImageFilterTest.cxx | 2 +- .../itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx | 2 +- ...itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx | 2 +- .../test/itkMaximumAbsoluteValueImageFilterTest.cxx | 2 +- ...MultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx index a19558ef20e..23632c5a74b 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx @@ -26,7 +26,7 @@ int itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) { /* typedefs, instantiate filter */ - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef double ImagePixelType; typedef itk::Image ImageType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx index 5f8655d174c..bcc4a94f66d 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx @@ -23,7 +23,7 @@ int itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) { /* typedefs, instantiate functor */ - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef double ImagePixelType; typedef itk::Image ImageType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx index 2d88d8608a8..e51b028695c 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx @@ -24,7 +24,7 @@ int itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) { - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef unsigned int MaskPixelType; typedef itk::Image MaskType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx index 2d1ad1045c3..48aeb23095f 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx @@ -24,7 +24,7 @@ int itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) { - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef unsigned int MaskPixelType; typedef itk::Image MaskType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx index 05e9f5839d2..23e752cf626 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx @@ -26,7 +26,7 @@ int itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) { /* typedefs, instantiate filter */ - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef double ImagePixelType; typedef itk::Image ImageType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx index 4a32f05c0ca..04c2c7722ef 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx @@ -23,7 +23,7 @@ int itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) { /* typedefs, instantiate functor */ - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef double ImagePixelType; typedef itk::Image ImageType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx index 0e9f9cf6c97..da1180426d1 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx @@ -24,7 +24,7 @@ int itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) { - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef unsigned int MaskPixelType; typedef itk::Image MaskType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index e0e710273d4..9cb9083fbed 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -24,7 +24,7 @@ int itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) { - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef unsigned int MaskPixelType; typedef itk::Image MaskType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx index 70e75c2cf74..5de39ab4b22 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx @@ -22,7 +22,7 @@ int itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) { - const unsigned int Dimension = 3; + constexpr unsigned int Dimension = 3; typedef char InputPixelType; typedef itk::Image InputImageType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx index 209c5c71506..cc71a15ea01 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx @@ -23,7 +23,7 @@ int itkMaximumAbsoluteValueImageFilterTest(int, char *[]) { - const unsigned int Dimension = 2; + constexpr unsigned int Dimension = 2; typedef int PixelType; typedef itk::Image ImageType; typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index 81dee7c62f9..487f406152f 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -24,7 +24,7 @@ int itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) { - const unsigned int Dimension = 2; + constexpr unsigned int Dimension = 2; typedef int PixelType; typedef itk::Image ImageType; typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; From c015a2683176d5c17b13931dbe7b948d76512936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 23:08:40 -0400 Subject: [PATCH 069/150] STYLE: Replace itkStaticConstMacro with static constexpr Use static constexpr directly now that C++11 conformance is required by all compilers. --- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.h | 2 +- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index ea75044d05c..03719b5521f 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -70,7 +70,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ - itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); + static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension; /** Image related typedefs. */ typedef typename TInputImage::PixelType PixelType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 31d6b20eb77..7d71d35cb61 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -77,7 +77,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Image related typedefs. */ typedef typename TInputImage::PixelType PixelType; - itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; /** Hessian related typedefs. */ typedef HessianRecursiveGaussianImageFilter HessianFilterType; From bc7a6b7a599188a04c42b1aa7ee3fb19ebc36142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 23:10:13 -0400 Subject: [PATCH 070/150] COMP: Use C++11 nullptr directly git grep -l "ITK_NULLPTR" | fgrep -v itk_compiler_detection.h | fgrep -v CMakeLists.txt |fgrep -v .cmake | xargs sed -i '' -e "s/ITK_NULLPTR/nullptr/g" --- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index bd8c859fc88..1268a198f31 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -35,7 +35,7 @@ MultiScaleHessianEnhancementImageFilter::MultiScaleHe m_HessianFilter = HessianFilterType::New(); m_EigenAnalysisFilter = EigenAnalysisFilterType::New(); m_MaximumAbsoluteValueFilter = MaximumAbsoluteValueFilterType::New(); - m_EigenToScalarImageFilter = ITK_NULLPTR; // has to be provided by the user. + m_EigenToScalarImageFilter = nullptr; // has to be provided by the user. /* We require an input image */ this->SetNumberOfRequiredInputs(1); From 88d1be01f530165f912369899f4e9021a1a889b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 23:10:26 -0400 Subject: [PATCH 071/150] COMP: Use C++11 override directly git grep -l "ITK_OVERRIDE" | fgrep -v itk_compiler_detection.h | fgrep -v CMakeLists.txt |fgrep -v .cmake | xargs sed -i '' -e "s/ITK_OVERRIDE/override/g" --- .../itkDescoteauxEigenToScalarFunctorImageFilter.h | 2 +- .../itkDescoteauxEigenToScalarImageFilter.h | 10 +++++----- ...uxEigenToScalarParameterEstimationImageFilter.h | 14 +++++++------- .../include/itkEigenToScalarImageFilter.h | 2 +- .../itkKrcahEigenToScalarFunctorImageFilter.h | 2 +- .../include/itkKrcahEigenToScalarImageFilter.h | 10 +++++----- ...ahEigenToScalarParameterEstimationImageFilter.h | 14 +++++++------- ...hEigenToScalarPreprocessingImageToImageFilter.h | 4 ++-- .../itkMultiScaleHessianEnhancementImageFilter.h | 8 ++++---- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index cbfa81ce46b..dd16618eae0 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -213,7 +213,7 @@ class DescoteauxEigenToScalarFunctorImageFilter /** Need to access the input parameters at execution time */ void - BeforeThreadedGenerateData() ITK_OVERRIDE + BeforeThreadedGenerateData() override { /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h index 8046fd1a673..0b89eb8d375 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h @@ -77,7 +77,7 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE + GetEigenValueOrder() const override { return Superclass::OrderByMagnitude; } @@ -170,18 +170,18 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; /** Single threaded since we are connecting data */ void - GenerateData() ITK_OVERRIDE; + GenerateData() override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h index 00844b5b3da..b89dec74e89 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h @@ -142,34 +142,34 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ void - AllocateOutputs() ITK_OVERRIDE; + AllocateOutputs() override; /** Initialize some accumulators before the threads run. */ void - BeforeThreadedGenerateData() ITK_OVERRIDE; + BeforeThreadedGenerateData() override; /** Do final mean and variance computation from data accumulated in threads. */ void - AfterThreadedGenerateData() ITK_OVERRIDE; + AfterThreadedGenerateData() override; /** Multi-thread version GenerateData. */ void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) override; /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; /** Compute Frobenius norm from a fixed array of eigenvalues */ inline RealType CalculateFrobeniusNorm(InputPixelType pixel); void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 6910bc2cbf4..ed9f4461534 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -75,7 +75,7 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilterGetEigenValueOrder() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index bf71951c707..828f51cca1e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -204,7 +204,7 @@ class KrcahEigenToScalarFunctorImageFilter /** Need to access the input parameters at execution time */ void - BeforeThreadedGenerateData() ITK_OVERRIDE + BeforeThreadedGenerateData() override { /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index f52aa4d762b..627c51081a0 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -78,7 +78,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE + GetEigenValueOrder() const override { return Superclass::OrderByMagnitude; } @@ -183,18 +183,18 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; /** Single threaded since we are connecting data */ void - GenerateData() ITK_OVERRIDE; + GenerateData() override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index d828dd9fbae..ea35f360157 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -186,30 +186,30 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ void - AllocateOutputs() ITK_OVERRIDE; + AllocateOutputs() override; /** Initialize some accumulators before the threads run. */ void - BeforeThreadedGenerateData() ITK_OVERRIDE; + BeforeThreadedGenerateData() override; /** Do final mean and variance computation from data accumulated in threads. */ void - AfterThreadedGenerateData() ITK_OVERRIDE; + AfterThreadedGenerateData() override; /** Multi-thread version GenerateData. */ void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) override; /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; /** Calculation of \f$ T \f$ changes depending on the implementation */ inline RealType diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index 03719b5521f..bdb6400977d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -118,10 +118,10 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter /** Single threaded since we are connecting data */ void - GenerateData() ITK_OVERRIDE; + GenerateData() override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 7d71d35cb61..6e05384ed41 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -151,7 +151,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Single threaded since we are connecting data */ void - GenerateData() ITK_OVERRIDE; + GenerateData() override; /** Internal function to generate the response at a scale */ inline typename TOutputImage::Pointer @@ -163,14 +163,14 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: /** Internal filters. */ From 050fcd3b7844427092ec12c6df5567a857fa532e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 23:26:12 -0400 Subject: [PATCH 072/150] COMP: Move ITK_DISALLOW_COPY_AND_ASSIGN calls to the public section. Move `ITK_DISALLOW_COPY_AND_ASSIGN` macro calls to the public section. For a rationale of the change, visit the discourse discussion: https://discourse.itk.org/t/noncopyable/648/24 --- .../include/itkDescoteauxEigenToScalarFunctorImageFilter.h | 4 ++-- .../include/itkDescoteauxEigenToScalarImageFilter.h | 4 ++-- ...tkDescoteauxEigenToScalarParameterEstimationImageFilter.h | 4 ++-- .../BoneEnhancement/include/itkEigenToScalarImageFilter.h | 5 ++--- .../include/itkKrcahEigenToScalarFunctorImageFilter.h | 4 ++-- .../include/itkKrcahEigenToScalarImageFilter.h | 4 ++-- .../itkKrcahEigenToScalarParameterEstimationImageFilter.h | 4 ++-- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.h | 4 ++-- .../include/itkMaximumAbsoluteValueImageFilter.h | 5 ++--- .../include/itkMultiScaleHessianEnhancementImageFilter.h | 3 ++- 10 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index dd16618eae0..b3d7be1189a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -181,6 +181,8 @@ class DescoteauxEigenToScalarFunctorImageFilter Functor::DescoteauxEigenToScalarFunctor> { public: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); + /** Standard Self typedef */ typedef DescoteauxEigenToScalarFunctorImageFilter Self; typedef UnaryFunctorImageFilter< @@ -243,8 +245,6 @@ class DescoteauxEigenToScalarFunctorImageFilter virtual ~DescoteauxEigenToScalarFunctorImageFilter() {} private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); - void PrintSelf(std::ostream & os, Indent indent) const { diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h index 0b89eb8d375..67020fcfc96 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h @@ -52,6 +52,8 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter : public EigenToScalarImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); + /** Standard Self typedef */ typedef DescoteauxEigenToScalarImageFilter Self; typedef EigenToScalarImageFilter Superclass; @@ -184,8 +186,6 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); - /* Filter pipeline */ typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h index b89dec74e89..4396a05f78a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h @@ -54,6 +54,8 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter : public ImageToImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); + /** Standard Self typedef */ typedef DescoteauxEigenToScalarParameterEstimationImageFilter Self; typedef ImageToImageFilter Superclass; @@ -172,8 +174,6 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); - /* Parameters */ RealType m_FrobeniusNormWeight; MaskPixelType m_BackgroundValue; diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index ed9f4461534..2b8c27706d4 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -40,6 +40,8 @@ template class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToScalarImageFilter); + /** Standard Self typedef */ typedef EigenToScalarImageFilter Self; typedef ImageToImageFilter Superclass; @@ -80,9 +82,6 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilterGetEigenValueOrder() << std::endl; } - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenToScalarImageFilter); }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 828f51cca1e..20ee533be74 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -173,6 +173,8 @@ class KrcahEigenToScalarFunctorImageFilter Functor::KrcahEigenToScalarFunctor> { public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); + /** Standard Self typedef */ typedef KrcahEigenToScalarFunctorImageFilter Self; typedef UnaryFunctorImageFilter< @@ -234,8 +236,6 @@ class KrcahEigenToScalarFunctorImageFilter virtual ~KrcahEigenToScalarFunctorImageFilter() {} private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); - void PrintSelf(std::ostream & os, Indent indent) const { diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index 627c51081a0..ca3c0961287 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -52,6 +52,8 @@ template { public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); + /** Standard Self typedef */ typedef KrcahEigenToScalarImageFilter Self; typedef EigenToScalarImageFilter Superclass; @@ -197,8 +199,6 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); - /* Filter pipeline */ typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index ea35f360157..97ee4473d98 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -81,6 +81,8 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter : public ImageToImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); + /** Standard Self typedef */ typedef KrcahEigenToScalarParameterEstimationImageFilter Self; typedef ImageToImageFilter Superclass; @@ -218,8 +220,6 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter CalculateTraceAccordingToJournalArticle(InputPixelType pixel); private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); - /* Parameters */ KrcahImplementationType m_ParameterSet; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index bdb6400977d..d7d794bd64c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -56,6 +56,8 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter : public ImageToImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); + /** Standard Self typedef */ typedef KrcahEigenToScalarPreprocessingImageToImageFilter Self; typedef ImageToImageFilter Superclass; @@ -124,8 +126,6 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); - /* Internal member variables */ RealType m_Sigma; RealType m_ScalingConstant; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 4748705a1c1..828b7034026 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -77,6 +77,8 @@ class MaximumAbsoluteValueImageFilter typename TOutputImage::PixelType>> { public: + ITK_DISALLOW_COPY_AND_ASSIGN(MaximumAbsoluteValueImageFilter); + /** Standard Self typedef */ typedef MaximumAbsoluteValueImageFilter Self; typedef BinaryFunctorImageFilter class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public ImageToImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(MultiScaleHessianEnhancementImageFilter); + /** Standard Self typedef */ typedef MultiScaleHessianEnhancementImageFilter Self; typedef ImageToImageFilter Superclass; @@ -182,7 +184,6 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Sigma member variables. */ SigmaArrayType m_SigmaArray; - ITK_DISALLOW_COPY_AND_ASSIGN(MultiScaleHessianEnhancementImageFilter); }; // end of class } // end namespace itk From d37475b83b0c51e49817594ad8a0fd0f858b7461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Wed, 26 Sep 2018 22:45:55 -0400 Subject: [PATCH 073/150] BUG: BuG: Fix build errors and warnings. Address the following build errors: ``` ITKBoneEnhancement\include\itkMultiScaleHessianEnhancementImageFilter.h(131): error C2061: syntax error: identifier 'SigmaArrayType' ITKBoneEnhancement\include\itkMultiScaleHessianEnhancementImageFilter.h(131): error C2238: unexpected token(s) preceding ';' ``` and the following warnings: ``` ITKBoneEnhancement\include\itkMultiScaleHessianEnhancementImageFilter.h(131): note: prefix with 'typename' to indicate a type ITKBoneEnhancement\include\itkMultiScaleHessianEnhancementImageFilter.h(174): note: see reference to class template instantiation 'itk::MultiScaleHessianEnhancementImageFilter' being compiled ITKBoneEnhancement\test\itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx(39): warning C4101: 'err': unreferenced local variable ITKBoneEnhancement\test\itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx(48): warning C4101: 'err': unreferenced local variable ``` --- ...kMultiScaleHessianEnhancementImageFilter.h | 16 ++++++------- ...nhancementImageFilterStaticMethodsTest.cxx | 24 ++++--------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 31d6b20eb77..e320d2adf2b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -77,7 +77,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Image related typedefs. */ typedef typename TInputImage::PixelType PixelType; - itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; /** Hessian related typedefs. */ typedef HessianRecursiveGaussianImageFilter HessianFilterType; @@ -128,14 +128,14 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image * Note that these methods cannot throw exceptions according to the standard itkExceptionMacro since they are static * methods. Instead, they will return an empty sigma array on error. */ - static Self::SigmaArrayType + static SigmaArrayType GenerateSigmaArray(SigmaType SigmaMinimum, SigmaType SigmaMaximum, SigmaStepsType NumberOfSigmaSteps, SigmaStepMethodEnum SigmaStepMethod); - static Self::SigmaArrayType + static SigmaArrayType GenerateEquispacedSigmaArray(SigmaType SigmaMinimum, SigmaType SigmaMaximum, SigmaStepsType NumberOfSigmaSteps); - static Self::SigmaArrayType + static SigmaArrayType GenerateLogarithmicSigmaArray(SigmaType SigmaMinimum, SigmaType SigmaMaximum, SigmaStepsType NumberOfSigmaSteps); #ifdef ITK_USE_CONCEPT_CHECKING @@ -151,7 +151,7 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Single threaded since we are connecting data */ void - GenerateData() ITK_OVERRIDE; + GenerateData() override; /** Internal function to generate the response at a scale */ inline typename TOutputImage::Pointer @@ -163,14 +163,14 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Override since the filter needs all the data for the algorithm */ void - GenerateInputRequestedRegion() ITK_OVERRIDE; + GenerateInputRequestedRegion() override; /** Override since the filter produces all of its output */ void - EnlargeOutputRequestedRegion(DataObject * data) ITK_OVERRIDE; + EnlargeOutputRequestedRegion(DataObject * data) override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: /** Internal filters. */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index 81dee7c62f9..4d6452ed0ff 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -33,25 +33,11 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) /* Test the two cases of step size zero */ ArrayType sigmaArray; bool exceptionCaught = false; - try - { - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0); - } - catch (itk::ExceptionObject & err) - { - exceptionCaught = true; - } - TEST_EXPECT_TRUE(exceptionCaught); - exceptionCaught = false; - try - { - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0); - } - catch (itk::ExceptionObject & err) - { - exceptionCaught = true; - } - TEST_EXPECT_TRUE(exceptionCaught); + + TRY_EXPECT_EXCEPTION(sigmaArray = + MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); + + TRY_EXPECT_EXCEPTION(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); /* Test that we get one when min equals max */ ArrayType expectedOneSigmaArray; From f6fb4b910707efc321bf37a828c2f8e22efebe80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Tue, 16 Oct 2018 14:43:01 -0400 Subject: [PATCH 074/150] STYLE: Use "typename" for template parameters For naming template parameters, typename and class are equivalent. ref:14.1.2: There is no semantic difference between class and typename in a template-parameter. The primary purpose of this patch set is to make ITK consistent so that an enforcable style can be implemented. The ITK Style guide as been updated to reflect this change [1]. For tempalate parameters the use of "typename" is preferred over "class". Very early c++ compilers did not have a "typename" keyword, and "class" was repurposed for declaring template parameters. It was later discovered that this lead to ambiguity in some valid code constructs, and the "typename" key word was added. It is sometimes stated [2] that "typename" is marginally more expressive in it's intent and ITK should consistently use "typename" instead of "class". [1] http://www.vtk.org/Wiki/ITK/Coding_Style_Guide [2] http://blogs.msdn.com/b/slippman/archive/2004/08/11/212768.aspx --- .../include/itkDescoteauxEigenToScalarFunctorImageFilter.h | 2 +- .../include/itkKrcahEigenToScalarFunctorImageFilter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index b3d7be1189a..6ca607c254a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -51,7 +51,7 @@ namespace Functor * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class DescoteauxEigenToScalarFunctor { public: diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 20ee533be74..4156995c20b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -48,7 +48,7 @@ namespace Functor * \author: Thomas Fitze * \ingroup BoneEnhancement */ -template +template class KrcahEigenToScalarFunctor { public: From a1a6e8adbb12e401a26a52045ebc760c9654c72d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Haitz=20Legarreta=20Gorro=C3=B1o?= Date: Tue, 16 Oct 2018 20:32:35 -0400 Subject: [PATCH 075/150] STYLE: Prefer C++11 type alias over typedef. Prefer C++11 type alias over `typedef` for the reasons stated here: http://review.source.kitware.com/#/c/23103/ --- ...escoteauxEigenToScalarFunctorImageFilter.h | 19 +++---- .../itkDescoteauxEigenToScalarImageFilter.h | 26 ++++----- ...enToScalarParameterEstimationImageFilter.h | 42 +++++++------- .../include/itkEigenToScalarImageFilter.h | 10 ++-- .../itkKrcahEigenToScalarFunctorImageFilter.h | 25 ++++----- .../itkKrcahEigenToScalarImageFilter.h | 28 +++++----- ...enToScalarParameterEstimationImageFilter.h | 42 +++++++------- ...nToScalarPreprocessingImageToImageFilter.h | 28 +++++----- .../itkMaximumAbsoluteValueImageFilter.h | 27 +++++---- ...kMultiScaleHessianEnhancementImageFilter.h | 56 +++++++++---------- ...escoteauxEigenToScalarFunctorImageTest.cxx | 16 +++--- .../itkDescoteauxEigenToScalarFunctorTest.cxx | 18 +++--- ...DescoteauxEigenToScalarImageFilterTest.cxx | 20 +++---- ...alarParameterEstimationImageFilterTest.cxx | 16 +++--- ...cahEigenToScalarFunctorImageFilterTest.cxx | 18 +++--- .../test/itkKrcahEigenToScalarFunctorTest.cxx | 18 +++--- .../itkKrcahEigenToScalarImageFilterTest.cxx | 20 +++---- ...alarParameterEstimationImageFilterTest.cxx | 16 +++--- ...larPreprocessingImageToImageFilterTest.cxx | 10 ++-- ...itkMaximumAbsoluteValueImageFilterTest.cxx | 16 +++--- ...nhancementImageFilterStaticMethodsTest.cxx | 10 ++-- 21 files changed, 239 insertions(+), 242 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index b3d7be1189a..4c9c474a61f 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -56,7 +56,7 @@ class DescoteauxEigenToScalarFunctor { public: /* Basic type definitions */ - typedef typename NumericTraits::RealType RealType; + using RealType = typename NumericTraits::RealType; DescoteauxEigenToScalarFunctor() : m_Direction(-1.0) @@ -183,17 +183,16 @@ class DescoteauxEigenToScalarFunctorImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarFunctorImageFilter Self; - typedef UnaryFunctorImageFilter< + /** Standard Self type alias */ + using Self = DescoteauxEigenToScalarFunctorImageFilter; + using Superclass = UnaryFunctorImageFilter< TInputImage, TOutputImage, - Functor::DescoteauxEigenToScalarFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + Functor::DescoteauxEigenToScalarFunctor>; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; - /** Useful typedefs for numerics */ + /** Useful type alias for numerics */ typedef typename Functor::DescoteauxEigenToScalarFunctor DescoteauxFunctorType; @@ -206,7 +205,7 @@ class DescoteauxEigenToScalarFunctorImageFilter itkTypeMacro(DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; + using InputParameterDecoratorType = SimpleDataObjectDecorator; /** Process object */ itkSetGetDecoratedInputMacro(Alpha, RealType); diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h index 67020fcfc96..c8464415978 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h @@ -54,11 +54,11 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarImageFilter Self; - typedef EigenToScalarImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = DescoteauxEigenToScalarImageFilter; + using Superclass = EigenToScalarImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -66,16 +66,16 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter /** Run-time type information (and related methods). */ itkTypeMacro(DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - /** Useful template typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; + /** Useful template type alias. */ + using InputImagePointer = typename TInputImage::Pointer; + using InputImageConstPointer = typename TInputImage::ConstPointer; + using MaskImagePointer = typename TMaskImage::Pointer; + using MaskImageConstPointer = typename TMaskImage::ConstPointer; + using MaskPixelType = typename TMaskImage::PixelType; /** Procesing filters */ - typedef DescoteauxEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; - typedef DescoteauxEigenToScalarFunctorImageFilter UnaryFunctorFilterType; + using ParameterEstimationFilterType = DescoteauxEigenToScalarParameterEstimationImageFilter; + using UnaryFunctorFilterType = DescoteauxEigenToScalarFunctorImageFilter; /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ typename Superclass::EigenValueOrderType diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h index 4396a05f78a..995dc184b9d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h @@ -56,11 +56,11 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); - /** Standard Self typedef */ - typedef DescoteauxEigenToScalarParameterEstimationImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = DescoteauxEigenToScalarParameterEstimationImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -68,27 +68,27 @@ class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter /** Run-time type information (and related methods). */ itkTypeMacro(DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - /** Image related typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TInputImage::RegionType InputRegionType; - typedef typename TInputImage::SizeType InputSizeType; - typedef typename TInputImage::IndexType InputIndexType; - typedef typename TInputImage::PixelType InputPixelType; - typedef typename InputPixelType::ValueType InputPixelValueType; + /** Image related type alias. */ + using InputImagePointer = typename TInputImage::Pointer; + using InputImageConstPointer = typename TInputImage::ConstPointer; + using InputRegionType = typename TInputImage::RegionType; + using InputSizeType = typename TInputImage::SizeType; + using InputIndexType = typename TInputImage::IndexType; + using InputPixelType = typename TInputImage::PixelType; + using InputPixelValueType = typename InputPixelType::ValueType; /** Output region definitions */ - typedef InputRegionType OutputRegionType; + using OutputRegionType = InputRegionType; - /** Mask related typedefs. */ - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - typedef typename TMaskImage::RegionType MaskRegionType; + /** Mask related type alias. */ + using MaskImagePointer = typename TMaskImage::Pointer; + using MaskImageConstPointer = typename TMaskImage::ConstPointer; + using MaskPixelType = typename TMaskImage::PixelType; + using MaskRegionType = typename TMaskImage::RegionType; /** Parameters */ - typedef typename NumericTraits::RealType RealType; - typedef SimpleDataObjectDecorator RealTypeDecoratedType; + using RealType = typename NumericTraits::RealType; + using RealTypeDecoratedType = SimpleDataObjectDecorator; /** Methods to set/get the mask image */ itkSetInputMacro(MaskImage, TMaskImage); diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h index 2b8c27706d4..8b9e70bc792 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h @@ -42,11 +42,11 @@ class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = EigenToScalarImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Run-time type information (and related methods). */ itkTypeMacro(EigenToScalarImageFilter, ImageToImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 20ee533be74..3a3384f50de 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -53,7 +53,7 @@ class KrcahEigenToScalarFunctor { public: /* Basic type definitions */ - typedef typename NumericTraits::RealType RealType; + using RealType = typename NumericTraits::RealType; KrcahEigenToScalarFunctor() : m_Direction(-1.0) @@ -175,20 +175,19 @@ class KrcahEigenToScalarFunctorImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); - /** Standard Self typedef */ - typedef KrcahEigenToScalarFunctorImageFilter Self; - typedef UnaryFunctorImageFilter< + /** Standard Self type alias */ + using Self = KrcahEigenToScalarFunctorImageFilter; + using Superclass = UnaryFunctorImageFilter< TInputImage, TOutputImage, - Functor::KrcahEigenToScalarFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + Functor::KrcahEigenToScalarFunctor>; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; - /** Useful typedefs for numerics */ - typedef typename Functor::KrcahEigenToScalarFunctor - KrcahFunctorType; - typedef typename KrcahFunctorType::RealType RealType; + /** Useful type alias for numerics */ + using KrcahFunctorType = + typename Functor::KrcahEigenToScalarFunctor; + using RealType = typename KrcahFunctorType::RealType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -197,7 +196,7 @@ class KrcahEigenToScalarFunctorImageFilter itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; + using InputParameterDecoratorType = SimpleDataObjectDecorator; /** Process object */ itkSetGetDecoratedInputMacro(Alpha, RealType); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h index ca3c0961287..b49c83d6855 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h @@ -54,11 +54,11 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); - /** Standard Self typedef */ - typedef KrcahEigenToScalarImageFilter Self; - typedef EigenToScalarImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = KrcahEigenToScalarImageFilter; + using Superclass = EigenToScalarImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -66,17 +66,17 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarIm /** Run-time type information (and related methods). */ itkTypeMacro(KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); - /** Useful template typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; + /** Useful template type alias. */ + using InputImagePointer = typename TInputImage::Pointer; + using InputImageConstPointer = typename TInputImage::ConstPointer; + using MaskImagePointer = typename TMaskImage::Pointer; + using MaskImageConstPointer = typename TMaskImage::ConstPointer; + using MaskPixelType = typename TMaskImage::PixelType; /** Procesing filters */ - typedef KrcahEigenToScalarParameterEstimationImageFilter ParameterEstimationFilterType; - typedef typename ParameterEstimationFilterType::KrcahImplementationType KrcahImplementationType; - typedef KrcahEigenToScalarFunctorImageFilter UnaryFunctorFilterType; + using ParameterEstimationFilterType = KrcahEigenToScalarParameterEstimationImageFilter; + using KrcahImplementationType = typename ParameterEstimationFilterType::KrcahImplementationType; + using UnaryFunctorFilterType = KrcahEigenToScalarFunctorImageFilter; /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ typename Superclass::EigenValueOrderType diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index 97ee4473d98..79361d0e07d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -83,11 +83,11 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); - /** Standard Self typedef */ - typedef KrcahEigenToScalarParameterEstimationImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = KrcahEigenToScalarParameterEstimationImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -95,23 +95,23 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter /** Run-time type information (and related methods). */ itkTypeMacro(KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - /** Image related typedefs. */ - typedef typename TInputImage::Pointer InputImagePointer; - typedef typename TInputImage::ConstPointer InputImageConstPointer; - typedef typename TInputImage::RegionType InputRegionType; - typedef typename TInputImage::SizeType InputSizeType; - typedef typename TInputImage::IndexType InputIndexType; - typedef typename TInputImage::PixelType InputPixelType; - typedef typename InputPixelType::ValueType InputPixelValueType; + /** Image related type alias. */ + using InputImagePointer = typename TInputImage::Pointer; + using InputImageConstPointer = typename TInputImage::ConstPointer; + using InputRegionType = typename TInputImage::RegionType; + using InputSizeType = typename TInputImage::SizeType; + using InputIndexType = typename TInputImage::IndexType; + using InputPixelType = typename TInputImage::PixelType; + using InputPixelValueType = typename InputPixelType::ValueType; /** Output region definitions */ - typedef InputRegionType OutputRegionType; + using OutputRegionType = InputRegionType; - /** Mask related typedefs. */ - typedef typename TMaskImage::Pointer MaskImagePointer; - typedef typename TMaskImage::ConstPointer MaskImageConstPointer; - typedef typename TMaskImage::PixelType MaskPixelType; - typedef typename TMaskImage::RegionType MaskRegionType; + /** Mask related type alias. */ + using MaskImagePointer = typename TMaskImage::Pointer; + using MaskImageConstPointer = typename TMaskImage::ConstPointer; + using MaskPixelType = typename TMaskImage::PixelType; + using MaskRegionType = typename TMaskImage::RegionType; /** Methods to set/get the mask image */ itkSetInputMacro(MaskImage, TMaskImage); @@ -143,8 +143,8 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter } /** Parameters */ - typedef typename NumericTraits::RealType RealType; - typedef SimpleDataObjectDecorator RealTypeDecoratedType; + using RealType = typename NumericTraits::RealType; + using RealTypeDecoratedType = SimpleDataObjectDecorator; /** Decorators for parameters so they can be passed as a process object */ RealTypeDecoratedType * diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index d7d794bd64c..963a6171574 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -58,11 +58,11 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); - /** Standard Self typedef */ - typedef KrcahEigenToScalarPreprocessingImageToImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = KrcahEigenToScalarPreprocessingImageToImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -74,17 +74,17 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter * of the two images is assumed to be the same. */ static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension; - /** Image related typedefs. */ - typedef typename TInputImage::PixelType PixelType; - typedef typename TOutputImage::PixelType OutputPixelType; - typedef typename NumericTraits::RealType RealType; - typedef typename NumericTraits::ValueType OutputPixelValueType; + /** Image related type alias. */ + using PixelType = typename TInputImage::PixelType; + using OutputPixelType = typename TOutputImage::PixelType; + using RealType = typename NumericTraits::RealType; + using OutputPixelValueType = typename NumericTraits::ValueType; /** Typedefs for internal filters */ - typedef DiscreteGaussianImageFilter GaussianFilterType; - typedef SubtractImageFilter SubstractFilterType; - typedef MultiplyImageFilter MultiplyFilterType; - typedef AddImageFilter AddFilterType; + using GaussianFilterType = DiscreteGaussianImageFilter; + using SubstractFilterType = SubtractImageFilter; + using MultiplyFilterType = MultiplyImageFilter; + using AddFilterType = AddImageFilter; /** Flag to release data or not */ itkSetMacro(ReleaseInternalFilterData, bool); diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index 828b7034026..a71a9cab88d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -79,20 +79,19 @@ class MaximumAbsoluteValueImageFilter public: ITK_DISALLOW_COPY_AND_ASSIGN(MaximumAbsoluteValueImageFilter); - /** Standard Self typedef */ - typedef MaximumAbsoluteValueImageFilter Self; - typedef BinaryFunctorImageFilter> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - typedef typename TInputImage1::PixelType Input1PixelType; - typedef typename TInputImage2::PixelType Input2PixelType; - typedef typename TOutputImage::PixelType OutputPixelType; + /** Standard Self type alias */ + using Self = MaximumAbsoluteValueImageFilter; + using Superclass = BinaryFunctorImageFilter>; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + using Input1PixelType = typename TInputImage1::PixelType; + using Input2PixelType = typename TInputImage2::PixelType; + using OutputPixelType = typename TOutputImage::PixelType; /** Method for creation through the object factory. */ itkNewMacro(Self); diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index cfe8e360b3e..7532545e0d4 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -65,11 +65,11 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image public: ITK_DISALLOW_COPY_AND_ASSIGN(MultiScaleHessianEnhancementImageFilter); - /** Standard Self typedef */ - typedef MultiScaleHessianEnhancementImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + /** Standard Self type alias */ + using Self = MultiScaleHessianEnhancementImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -77,43 +77,43 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** Runtime information support. */ itkTypeMacro(MultiScaleHessianEnhancementImageFilter, ImageToImageFilter); - /** Image related typedefs. */ - typedef typename TInputImage::PixelType PixelType; - static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; + /** Image related type alias. */ + using PixelType = typename TInputImage::PixelType; + static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; - /** Hessian related typedefs. */ - typedef HessianRecursiveGaussianImageFilter HessianFilterType; - typedef typename HessianFilterType::OutputImageType HessianImageType; - typedef typename HessianImageType::PixelType HessianPixelType; + /** Hessian related type alias. */ + using HessianFilterType = HessianRecursiveGaussianImageFilter; + using HessianImageType = typename HessianFilterType::OutputImageType; + using HessianPixelType = typename HessianImageType::PixelType; - /** Eigenvalue analysis related typedefs. The ITK python wrapping usually wraps floating types + /** Eigenvalue analysis related type alias. The ITK python wrapping usually wraps floating types * and not double types. For this reason, the eigenvalues are of type float. */ - typedef typename NumericTraits::RealType RealType; - typedef typename NumericTraits::FloatType FloatType; - typedef Vector EigenValueArrayType; - typedef Image EigenValueImageType; - typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; + using RealType = typename NumericTraits::RealType; + using FloatType = typename NumericTraits::FloatType; + using EigenValueArrayType = Vector; + using EigenValueImageType = Image; + using EigenAnalysisFilterType = SymmetricEigenAnalysisImageFilter; - /** Maximum over scale related typedefs. */ - typedef MaximumAbsoluteValueImageFilter MaximumAbsoluteValueFilterType; + /** Maximum over scale related type alias. */ + using MaximumAbsoluteValueFilterType = MaximumAbsoluteValueImageFilter; - /** Eigenvalue image to scalar image related typedefs */ - typedef EigenToScalarImageFilter EigenToScalarImageFilterType; + /** Eigenvalue image to scalar image related type alias */ + using EigenToScalarImageFilterType = EigenToScalarImageFilter; /** Need some types to determine how to order the eigenvalues */ - // typedef typename Functor::SymmetricEigenAnalysisFunction::EigenValueOrderType InternalEigenValueOrderType; - typedef typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType InternalEigenValueOrderType; - typedef typename EigenToScalarImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; + // using InternalEigenValueOrderType = typename Functor::SymmetricEigenAnalysisFunction::EigenValueOrderType; + using InternalEigenValueOrderType = typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType; + using ExternalEigenValueOrderType = typename EigenToScalarImageFilterType::EigenValueOrderType; /** Set/Get the EigenToScalarImageFilter. */ itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); itkGetModifiableObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); /** Sigma values. */ - typedef RealType SigmaType; - typedef Array SigmaArrayType; - typedef unsigned int SigmaStepsType; + using SigmaType = RealType; + using SigmaArrayType = Array; + using SigmaStepsType = unsigned int; typedef enum { EquispacedSigmaSteps = 0, diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx index 23632c5a74b..344acd4a248 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx @@ -25,16 +25,16 @@ int itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) { - /* typedefs, instantiate filter */ - constexpr unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; + /* type alias, instantiate filter */ + constexpr unsigned int Dimension = 3; + using ImagePixelType = double; + using ImageType = itk::Image; - typedef double EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = double; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::DescoteauxEigenToScalarFunctorImageFilter FilterType; + using FilterType = itk::DescoteauxEigenToScalarFunctorImageFilter; FilterType::Pointer descoFilter = FilterType::New(); /* Basic tests. Need to set parameters first. */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx index bcc4a94f66d..44fc42de65e 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx @@ -22,17 +22,17 @@ int itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) { - /* typedefs, instantiate functor */ - constexpr unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; + /* type alias, instantiate functor */ + constexpr unsigned int Dimension = 3; + using ImagePixelType = double; + using ImageType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::Functor::DescoteauxEigenToScalarFunctor FunctorType; - FunctorType functor = FunctorType(); + using FunctorType = itk::Functor::DescoteauxEigenToScalarFunctor; + FunctorType functor = FunctorType(); /* Exercise basic set/get methods */ functor.SetAlpha(0.25); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx index e51b028695c..b5e4221ee2c 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx @@ -24,19 +24,19 @@ int itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) { - constexpr unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; + constexpr unsigned int Dimension = 3; + using MaskPixelType = unsigned int; + using MaskType = itk::Image; - typedef double OutputPixelType; - typedef itk::Image OutputType; + using OutputPixelType = double; + using OutputType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::DescoteauxEigenToScalarImageFilter - DescoteauxEigenToScalarImageFilterType; + using DescoteauxEigenToScalarImageFilterType = + itk::DescoteauxEigenToScalarImageFilter; DescoteauxEigenToScalarImageFilterType::Pointer descoFilter = DescoteauxEigenToScalarImageFilterType::New(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx index 48aeb23095f..97a3679c76a 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx @@ -24,16 +24,16 @@ int itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) { - constexpr unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; + constexpr unsigned int Dimension = 3; + using MaskPixelType = unsigned int; + using MaskType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::DescoteauxEigenToScalarParameterEstimationImageFilter - DescoteauxEigenToScalarParameterEstimationImageFilterType; + using DescoteauxEigenToScalarParameterEstimationImageFilterType = + itk::DescoteauxEigenToScalarParameterEstimationImageFilter; DescoteauxEigenToScalarParameterEstimationImageFilterType::Pointer descoteauxParameterEstimator = DescoteauxEigenToScalarParameterEstimationImageFilterType::New(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx index 23e752cf626..ebc364280de 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx @@ -25,17 +25,17 @@ int itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) { - /* typedefs, instantiate filter */ - constexpr unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; + /* type alias, instantiate filter */ + constexpr unsigned int Dimension = 3; + using ImagePixelType = double; + using ImageType = itk::Image; - typedef double EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = double; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::KrcahEigenToScalarFunctorImageFilter FilterType; - FilterType::Pointer krcahFilter = FilterType::New(); + using FilterType = itk::KrcahEigenToScalarFunctorImageFilter; + FilterType::Pointer krcahFilter = FilterType::New(); /* Basic tests. Need to set parameters first. */ krcahFilter->SetAlpha(0.5); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx index 04c2c7722ef..38d282791d9 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx @@ -22,17 +22,17 @@ int itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) { - /* typedefs, instantiate functor */ - constexpr unsigned int Dimension = 3; - typedef double ImagePixelType; - typedef itk::Image ImageType; + /* type alias, instantiate functor */ + constexpr unsigned int Dimension = 3; + using ImagePixelType = double; + using ImageType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::Functor::KrcahEigenToScalarFunctor FunctorType; - FunctorType functor = FunctorType(); + using FunctorType = itk::Functor::KrcahEigenToScalarFunctor; + FunctorType functor = FunctorType(); /* Exercise basic set/get methods */ functor.SetAlpha(0.5); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx index da1180426d1..b3f3da41c80 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx @@ -24,19 +24,19 @@ int itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) { - constexpr unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; + constexpr unsigned int Dimension = 3; + using MaskPixelType = unsigned int; + using MaskType = itk::Image; - typedef double OutputPixelType; - typedef itk::Image OutputType; + using OutputPixelType = double; + using OutputType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::KrcahEigenToScalarImageFilter - KrcahEigenToScalarImageFilterType; + using KrcahEigenToScalarImageFilterType = + itk::KrcahEigenToScalarImageFilter; KrcahEigenToScalarImageFilterType::Pointer krcahFilter = KrcahEigenToScalarImageFilterType::New(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index 9cb9083fbed..5786a96aca8 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -24,16 +24,16 @@ int itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) { - constexpr unsigned int Dimension = 3; - typedef unsigned int MaskPixelType; - typedef itk::Image MaskType; + constexpr unsigned int Dimension = 3; + using MaskPixelType = unsigned int; + using MaskType = itk::Image; - typedef float EigenValueType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenValueImageType; + using EigenValueType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenValueImageType = itk::Image; - typedef itk::KrcahEigenToScalarParameterEstimationImageFilter - KrcahEigenToScalarParameterEstimationImageFilterType; + using KrcahEigenToScalarParameterEstimationImageFilterType = + itk::KrcahEigenToScalarParameterEstimationImageFilter; KrcahEigenToScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = KrcahEigenToScalarParameterEstimationImageFilterType::New(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx index 5de39ab4b22..e16178cab7a 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx @@ -22,12 +22,12 @@ int itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) { - constexpr unsigned int Dimension = 3; - typedef char InputPixelType; - typedef itk::Image InputImageType; + constexpr unsigned int Dimension = 3; + using InputPixelType = char; + using InputImageType = itk::Image; - typedef itk::KrcahEigenToScalarPreprocessingImageToImageFilter FilterType; - FilterType::Pointer filter = FilterType::New(); + using FilterType = itk::KrcahEigenToScalarPreprocessingImageToImageFilter; + FilterType::Pointer filter = FilterType::New(); /* Basic test */ EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx index cc71a15ea01..c42e1ba1b98 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx @@ -23,11 +23,11 @@ int itkMaximumAbsoluteValueImageFilterTest(int, char *[]) { - constexpr unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; - MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); + constexpr unsigned int Dimension = 2; + using PixelType = int; + using ImageType = itk::Image; + using MaximumAbsoluteValueImageFilterType = itk::MaximumAbsoluteValueImageFilter; + MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); @@ -53,9 +53,9 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) image2->SetRegions(region); image2->Allocate(); - typedef itk::ImageRegionIterator IteratorType; - IteratorType it1(image1, region); - IteratorType it2(image2, region); + using IteratorType = itk::ImageRegionIterator; + IteratorType it1(image1, region); + IteratorType it2(image2, region); it1.GoToBegin(); it2.GoToBegin(); int i = 0; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index 23214ecf497..c4c0914e2e0 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -24,11 +24,11 @@ int itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) { - constexpr unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + constexpr unsigned int Dimension = 2; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Test the two cases of step size zero */ ArrayType sigmaArray; From dfe056cc4f72a64c2b6ed450040d93c3a415103f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 18 Oct 2018 13:52:32 -0600 Subject: [PATCH 076/150] ENH: Update Descoteaux filter to ITKv5 DynamicThreadedGenerateData --- .../itkDescoteauxEigenToMeasureImageFilter.h | 2 +- ...itkDescoteauxEigenToMeasureImageFilter.hxx | 8 +--- ...xEigenToMeasureParameterEstimationFilter.h | 9 ++-- ...igenToMeasureParameterEstimationFilter.hxx | 45 +++++-------------- 4 files changed, 21 insertions(+), 43 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index 04d79a467c3..95d05d92d91 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -125,7 +125,7 @@ class DescoteauxEigenToMeasureImageFilter /** Multi-thread version GenerateData. */ void - ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index ff7239d8941..686422d4480 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -35,9 +35,8 @@ DescoteauxEigenToMeasureImageFilter void -DescoteauxEigenToMeasureImageFilter::ThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread, - ThreadIdType threadId) +DescoteauxEigenToMeasureImageFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) { /* Get Inputs */ ParameterArrayType parameters = this->GetParametersInput()->Get(); @@ -63,8 +62,6 @@ DescoteauxEigenToMeasureImageFilter inputIt(inputPtr, inputRegionForThread); ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); - inputIt.GoToBegin(); outputIt.GoToBegin(); @@ -81,7 +78,6 @@ DescoteauxEigenToMeasureImageFilter m_MaxFrobeniusNorm; + RealType m_FrobeniusNormWeight; + RealType m_MaxFrobeniusNorm; + + SimpleFastMutexLock m_Mutex; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index 5ef31795fd3..aabbb818bba 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -20,6 +20,7 @@ #define itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx #include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkMutexLockHolder.h" namespace itk { @@ -43,40 +44,23 @@ template void DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { - ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); - - /* Resize threads */ - m_MaxFrobeniusNorm.SetSize(numberOfCalls); - m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); + m_MaxFrobeniusNorm = NumericTraits::NonpositiveMin(); } template void DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { - ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); - /* Determine default parameters */ RealType alpha, beta, c; alpha = 0.5f; beta = 0.5f; c = 0.0f; - /* Accumulate over threads */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfCalls; ++i) - { - if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) - { - maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; - } - } - /* Scale c */ - if (maxFrobeniusNorm > 0) + if (m_MaxFrobeniusNorm > 0) { - c = m_FrobeniusNormWeight * maxFrobeniusNorm; + c = m_FrobeniusNormWeight * m_MaxFrobeniusNorm; } /* Assign outputs parameters */ @@ -90,9 +74,8 @@ DescoteauxEigenToMeasureParameterEstimationFilter void -DescoteauxEigenToMeasureParameterEstimationFilter::ThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread, - ThreadIdType threadId) +DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ const SizeValueType size0 = outputRegionForThread.GetSize(0); @@ -101,9 +84,8 @@ DescoteauxEigenToMeasureParameterEstimationFilter::ZeroValue(); - RealType thisFrobeniusNorm; + /* Keep track of the current max */ + RealType max = NumericTraits::NonpositiveMin(); /* Get input and mask pointer */ InputImageConstPointer inputPointer = this->GetInput(); @@ -133,11 +115,7 @@ DescoteauxEigenToMeasureParameterEstimationFilterIsInside(point))) { /* Compute max norm */ - thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); - if (thisFrobeniusNorm > maxFrobeniusNorm) - { - maxFrobeniusNorm = thisFrobeniusNorm; - } + max = std::max(max, this->CalculateFrobeniusNorm(inputIt.Get())); } // Set @@ -148,8 +126,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter mutexHolder(m_Mutex); + m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); } template From e1daf3194e4fd5ba07f8435c3054dcf11f68cea2 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 19 Oct 2018 16:31:00 -0600 Subject: [PATCH 077/150] ENH: Implement Krcah parameter estimation filter and unit test --- ...hEigenToMeasureParameterEstimationFilter.h | 184 ++++++++++++ ...igenToMeasureParameterEstimationFilter.hxx | 211 +++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 1 + ...asureParameterEstimationFilterUnitTest.cxx | 278 ++++++++++++++++++ 4 files changed, 674 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..cf8c8b819c1 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,184 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToMeasureParameterEstimationFilter_h +#define itkKrcahEigenToMeasureParameterEstimationFilter_h + +#include "itkMath.h" +#include "itkEigenToMeasureParameterEstimationFilter.h" +#include "itkSimpleFastMutexLock.h" +#include "itkCompensatedSummation.h" + +namespace itk +{ +/** \class KrcahEigenToMeasureParameterEstimationFilter + * \brief Automatic parameter estimation as defined by Krcah et al. + * + * This class takes an image of eigenvalues and estimates the parameters for the Krcah + * bone enhanced filter. According to the original paper, + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.25 + * \f} + * + * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. + * The trace of the matrix can be computed directly from the eigenvalues as the sum + * of the eigenvalues. + * + * In this implementation, the average of the trace is moved into the constant + * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary + * functor. The modification is very simple. If the average of the trace is + * denoted \f$ T \f$ the new parameter becomes: + * \f{ + * \gamma &=& 0.25 \cdot T + * \f} + * + * However, the code was implemented different than described in the original + * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum + * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. + * Furthermore, all parameters were scaled by a factor of 2 in the implementation + * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the + * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType + * can be set which enables the implementation parameters: + * \f{eqnarray*}{ + * \alpha &=& \sqrt{2} \cdot 0.5 \\ + * \beta &=& \sqrt{2} \cdot 0.5 \\ + * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T + * \f} + * Default is to use parameters from the implementation, not the paper. + * + * The parameters are estimated over the whole volume unless a mask is given. + * If a mask is given, parameters are evaluated only where IsInside returns + * true. + * + * \sa KrcahEigenToMeasureImageFilter + * \sa EigenToMeasureParameterEstimationFilter + * \sa MultiScaleHessianEnhancementImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class KrcahEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter +{ +public: + /** Standard Self typedef */ + typedef KrcahEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::PixelValueType PixelValueType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(KrcahEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); + + typedef enum + { + UseImplementationParameters = 1, + UseJournalParameters + } KrcahImplementationType; + itkSetMacro(ParameterSet, KrcahImplementationType); + itkGetConstMacro(ParameterSet, KrcahImplementationType); + + /* Set parameter set */ + void + SetParameterSetToImplementation() + { + this->SetParameterSet(UseImplementationParameters); + } + + void + SetParameterSetToJournalArticle() + { + this->SetParameterSet(UseJournalParameters); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + KrcahEigenToMeasureParameterEstimationFilter(); + virtual ~KrcahEigenToMeasureParameterEstimationFilter() {} + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; + + /** Calculation of \f$ T \f$ changes depending on the implementation */ + inline RealType + CalculateTraceAccordingToImplementation(InputImagePixelType pixel); + inline RealType + CalculateTraceAccordingToJournalArticle(InputImagePixelType pixel); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); + + /* Member variables */ + KrcahImplementationType m_ParameterSet; + CompensatedSummation m_ThreadCount; + CompensatedSummation m_ThreadAccumulatedTrace; + + SimpleFastMutexLock m_Mutex; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahEigenToMeasureParameterEstimationFilter.hxx" +#endif + +#endif /* itkKrcahEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..96b1a04a844 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,211 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToMeasureParameterEstimationFilter_hxx +#define itkKrcahEigenToMeasureParameterEstimationFilter_hxx + +#include "itkKrcahEigenToMeasureParameterEstimationFilter.h" +#include "itkMutexLockHolder.h" + +namespace itk +{ + +template +KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() + : m_ParameterSet(UseImplementationParameters) +{ + /* Set parameter size to 3 */ + ParameterArrayType parameters = this->GetParametersOutput()->Get(); + parameters.SetSize(3); + parameters[0] = 0.5; + parameters[1] = 0.5; + parameters[2] = 1; + this->GetParametersOutput()->Set(parameters); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +{ + m_ThreadAccumulatedTrace = NumericTraits::ZeroValue(); + m_ThreadCount = NumericTraits::ZeroValue(); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +{ + /* Determine default parameters */ + RealType alpha, beta, gamma; + switch (m_ParameterSet) + { + case UseImplementationParameters: + alpha = Math::sqrt2 * 0.5f; + beta = Math::sqrt2 * 0.5f; + gamma = Math::sqrt2 * 0.5f; + break; + case UseJournalParameters: + alpha = 0.5f; + beta = 0.5f; + gamma = 0.25f; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Do derived measures */ + const RealType accum(m_ThreadAccumulatedTrace); + const RealType count(m_ThreadCount); + if (count > 0) + { + RealType averageTrace = accum / count; + gamma = gamma * averageTrace; + } + else + { + gamma = NumericTraits::ZeroValue(); + } + + /* Assign outputs parameters */ + ParameterArrayType parameters; + parameters.SetSize(3); + parameters[0] = alpha; + parameters[1] = beta; + parameters[2] = gamma; + this->GetParametersOutput()->Set(parameters); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) +{ + /* If size is zero, return */ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Determine which function to call */ + RealType (Self::*traceFunction)(InputImagePixelType); + switch (m_ParameterSet) + { + case UseImplementationParameters: + traceFunction = &Self::CalculateTraceAccordingToImplementation; + break; + case UseJournalParameters: + traceFunction = &Self::CalculateTraceAccordingToJournalArticle; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Keep track of the current max */ + RealType accum = NumericTraits::ZeroValue(); + RealType count = NumericTraits::ZeroValue(); + + /* Get input and mask pointer */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + OutputImageType * outputPtr = this->GetOutput(0); + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + outputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + /* Compute trace */ + count++; + accum += (this->*traceFunction)(inputIt.Get()); + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + /* Block and store */ + MutexLockHolder mutexHolder(m_Mutex); + m_ThreadCount += count; + m_ThreadAccumulatedTrace += accum; +} + +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( + InputImagePixelType pixel) +{ + /* Sum of the absolute value of the eigenvalues */ + RealType trace = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + trace += Math::abs(pixel[i]); + } + return trace; +} + +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( + InputImagePixelType pixel) +{ + /* Sum of the eigenvalues */ + RealType trace = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + trace += pixel[i]; + } + return trace; +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "ParameterSet: " << GetParameterSet() << std::endl; +} + +} // namespace itk + +#endif /* itkKrcahEigenToMeasureParameterEstimationFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 6d723fe1718..5b72f251ba2 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -17,6 +17,7 @@ set( itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx + itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx new file mode 100644 index 00000000000..4313686abf9 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -0,0 +1,278 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkKrcahEigenToMeasureParameterEstimationFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkKrcahEigenToMeasureParameterEstimationFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::KrcahEigenToMeasureParameterEstimationFilter FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; + + itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + m_LargeEigenPixel[i] = 100; + } + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + typename EigenImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(maskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + maskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex input(m_MaskingEigenImage, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, maskRegion); + + input.GoToBegin(); + maskIt.GoToBegin(); + while (!input.IsAtEnd()) + { + input.Set(m_LargeEigenPixel); + maskIt.Set(1); + ++input; + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_LargeEigenPixel; + ParameterArrayType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) +{ + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(1.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImageImplementation) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[1], 1e-6); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImageJournalArticle) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.5, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.5, this->m_Parameters[1], 1e-6); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageImplementation) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[1], 1e-6); + EXPECT_NEAR(2.12132034356, this->m_Parameters[2], 1e-6); // sqrt(2) * 0.5 * 3 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageJournalArticle) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.5, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.5, this->m_Parameters[1], 1e-6); + EXPECT_NEAR(0.75, this->m_Parameters[2], 1e-6); // 0.25 * 3 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectImplementation) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.70710678118654757, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.70710678118654757, this->m_Parameters[1]); + EXPECT_NEAR(212.132034356, this->m_Parameters[2], 1e-6); // sqrt(2) * 0.5 * 300 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectJournalArticle) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(75.0, this->m_Parameters[2], 1e-6); // 0.25 * 300 +} From 3007f3df7e5a4ff5ce242cd876800dcee323506e Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 2 Feb 2018 13:16:05 -0700 Subject: [PATCH 078/150] ENH: Implemented HessianGaussianImageFilter with streaming --- .../include/itkHessianGaussianImageFilter.h | 159 +++++++++++ .../include/itkHessianGaussianImageFilter.hxx | 269 ++++++++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 8 + .../itkHessianGaussianImageFilterTest.cxx | 52 ++++ .../itkHessianGaussianImageFilter.wrap | 3 + 5 files changed, 491 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h new file mode 100644 index 00000000000..4a70fd81ea8 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h @@ -0,0 +1,159 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkHessianGaussianImageFilter_h +#define itkHessianGaussianImageFilter_h + +#include "itkDiscreteGaussianDerivativeImageFilter.h" +#include "itkNthElementImageAdaptor.h" +#include "itkImage.h" +#include "itkSymmetricSecondRankTensor.h" +#include "itkPixelTraits.h" + +namespace itk +{ +/** \class HessianGaussianImageFilter + * \brief Computes the Hessian matrix of an image by convolution + * with the Second and Cross derivatives of a Gaussian + * with streaming. + * + * This filter is implemented using the discrete gaussian + * filters to enable streaming. Although IIR filters are faster + * than FIR filters, IIR filters cannot be streamed. FIR filters + * are slower but can be streamed for small memory computers. + * + * This class is an exact copy of HessianRecursiveGaussianImageFilter + * but with streaming. + * + * \sa HessianRecursiveGaussianImageFilter. + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ + +template ::RealType, + TInputImage::ImageDimension>, + TInputImage::ImageDimension>> +class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef HessianGaussianImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Pixel Type of the input image */ + typedef TInputImage InputImageType; + typedef typename TInputImage::PixelType PixelType; + typedef typename NumericTraits::RealType RealType; + + /** Image dimension. */ + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Define the image type for internal computations + RealType is usually 'double' in NumericTraits. + Here we prefer float in order to save memory. */ + typedef float InternalRealType; + typedef Image RealImageType; + + /** Output Image Nth Element Adaptor + * This adaptor allows to use conventional scalar + * smoothing filters to compute each one of the + * components of the gradient image pixels. */ + typedef NthElementImageAdaptor OutputImageAdaptorType; + + typedef typename OutputImageAdaptorType::Pointer OutputImageAdaptorPointer; + + /** Derivative filter type */ + typedef DiscreteGaussianDerivativeImageFilter DerivativeFilterType; + + /** Pointer to a gaussian filter. */ + typedef typename DerivativeFilterType::Pointer DerivativeFilterPointer; + + /** Pointer to the Output Image */ + typedef typename TOutputImage::Pointer OutputImagePointer; + + /** Type of the output Image */ + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename PixelTraits::ValueType OutputComponentType; + + /** Run-time type information (and related methods). */ + itkTypeMacro(HessianGaussianImageFilter, ImageToImageFilter); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Set Sigma value. Sigma is measured in the units of image spacing. */ + void + SetSigma(RealType sigma); + RealType + GetSigma() const; + + /** Define which normalization factor will be used for the Gaussian + * \sa DiscreteGaussianDerivativeImageFilter::SetNormalizeAcrossScale + */ + void + SetNormalizeAcrossScale(bool normalizeInScaleSpace); + bool + GetNormalizeAcrossScale() const; + itkBooleanMacro(NormalizeAcrossScale); + + /** As opposed to HessianRecursiveGaussianImageFilter, HessianGaussianImageFilter + * doe not need all of the input to produce an output. However, it does need to + * expand the InputRequestedRegion region to account for the support of the + * Gaussian filter. + * \sa DiscreteGaussianDerivativeImageFilter::GenerateInputRequestedRegion() */ + // TODO + virtual void + GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + +#ifdef ITK_USE_CONCEPT_CHECKING + /** Begin concept checking */ + itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); + itkConceptMacro(OutputHasPixelTraitsCheck, (Concept::HasPixelTraits)); + /** End concept checking */ +#endif + +protected: + HessianGaussianImageFilter(); + virtual ~HessianGaussianImageFilter() {} + void + PrintSelf(std::ostream & os, Indent indent) const; + + /** Generate Data */ + void + GenerateData(void); + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(HessianGaussianImageFilter); + + /** Internal filters **/ + DerivativeFilterPointer m_DerivativeFilter; + OutputImageAdaptorPointer m_ImageAdaptor; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkHessianGaussianImageFilter.hxx" +#endif + +#endif // itkHessianGaussianImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx new file mode 100644 index 00000000000..36c0b3fe27f --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -0,0 +1,269 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkHessianGaussianImageFilter_hxx +#define itkHessianGaussianImageFilter_hxx + +#include "itkHessianGaussianImageFilter.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkProgressAccumulator.h" +#include "itkGaussianDerivativeOperator.h" +#include "itkMath.h" + +namespace itk +{ +/** + * Constructor + */ +template +HessianGaussianImageFilter::HessianGaussianImageFilter() +{ + // Create Derivative Filter + m_DerivativeFilter = DerivativeFilterType::New(); + m_DerivativeFilter->SetInput(this->GetInput()); + m_DerivativeFilter->ReleaseDataFlagOn(); // output is only used once + m_DerivativeFilter->UseImageSpacingOn(); + + // Create image adaptor + m_ImageAdaptor = OutputImageAdaptorType::New(); + + // Setup defaults + this->SetNormalizeAcrossScale(true); + this->SetSigma(1.0); +} + +/** + * Set value of Sigma + */ +template +void +HessianGaussianImageFilter::SetSigma(RealType sigma) +{ + m_DerivativeFilter->SetVariance(sigma * sigma); + + this->Modified(); +} + +/** + * Get value of Sigma + */ +template +typename HessianGaussianImageFilter::RealType +HessianGaussianImageFilter::GetSigma() const +{ + return sqrt(m_DerivativeFilter->GetVariance()[0]); +} + +/** + * Set Normalize Across Scale Space + */ +template +void +HessianGaussianImageFilter::SetNormalizeAcrossScale(bool normalize) +{ + m_DerivativeFilter->SetNormalizeAcrossScale(normalize); + + this->Modified(); +} + +/** + * Get Normalize Across SCale Space + */ +template +bool +HessianGaussianImageFilter::GetNormalizeAcrossScale() const +{ + return m_DerivativeFilter->GetNormalizeAcrossScale(); +} + +template +void +HessianGaussianImageFilter::GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) +{ + // call the superclass' implementation of this method. this should + // copy the output requested region to the input requested region + Superclass::GenerateInputRequestedRegion(); + + // get pointers to the input + typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) + { + return; + } + + // Build an operator so that we can determine the kernel size + GaussianDerivativeOperator oper; + typename TInputImage::SizeType radius; + + for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) + { + // Determine the size of the operator in this dimension. Note that the + // Gaussian is built as a 1D operator in each of the specified directions. + oper.SetDirection(i); + if (this->GetInput()->GetSpacing()[i] == 0.0) + { + itkExceptionMacro(<< "Pixel spacing cannot be zero"); + } + else + { + oper.SetSpacing(this->GetInput()->GetSpacing()[i]); + } + + // GaussianDerivativeOperator modifies the variance when setting image + // spacing + oper.SetVariance(this->m_DerivativeFilter->GetVariance()[i]); + oper.SetMaximumError(this->m_DerivativeFilter->GetMaximumError()[i]); + oper.SetMaximumKernelWidth(this->m_DerivativeFilter->GetMaximumKernelWidth()); + oper.CreateDirectional(); + + radius[i] = oper.GetRadius(i); + } + + // get a copy of the input requested region (should equal the output + // requested region) + typename TInputImage::RegionType inputRequestedRegion; + inputRequestedRegion = inputPtr->GetRequestedRegion(); + + // pad the input requested region by the operator radius + inputRequestedRegion.PadByRadius(radius); + + // crop the input requested region at the input's largest possible region + if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) + { + inputPtr->SetRequestedRegion(inputRequestedRegion); + return; + } + else + { + // Couldn't crop the region (requested region is outside the largest + // possible region). Throw an exception. + + // store what we tried to request (prior to trying to crop) + inputPtr->SetRequestedRegion(inputRequestedRegion); + + // build an exception + InvalidRequestedRegionError e(__FILE__, __LINE__); + e.SetLocation(ITK_LOCATION); + e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + e.SetDataObject(inputPtr); + throw e; + } +} + +/** + * Compute filter for Gaussian kernel + */ +template +void +HessianGaussianImageFilter::GenerateData(void) +{ + itkDebugMacro(<< "HessianGaussianImageFilter generating data "); + + // Create a process accumulator for tracking the progress of this + // minipipeline + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + + // Compute the contribution of each filter to the total progress. + // For a DxD matrix, we do the following number of computations: + // \sum_{i=1}^D \sum_{j=i}^D 1 = D(D+1)/2 + const double weight = 1.0 / (ImageDimension * (ImageDimension + 1) / 2.0); + + progress->RegisterInternalFilter(m_DerivativeFilter, weight); + + const typename TInputImage::ConstPointer inputImage(this->GetInput()); + + // Setup Image Adaptor + m_ImageAdaptor->SetImage(this->GetOutput()); + + m_ImageAdaptor->SetLargestPossibleRegion(inputImage->GetLargestPossibleRegion()); + + m_ImageAdaptor->SetBufferedRegion(inputImage->GetBufferedRegion()); + + m_ImageAdaptor->SetRequestedRegion(inputImage->GetRequestedRegion()); + + m_ImageAdaptor->Allocate(); + + m_DerivativeFilter->SetInput(inputImage); + + unsigned int element = 0; + int order[ImageDimension]; + + for (unsigned int dima = 0; dima < ImageDimension; dima++) + { + for (unsigned int dimb = dima; dimb < ImageDimension; dimb++) + { + // All directions have zero order derivative initially + for (int k = 0; k < ImageDimension; ++k) + { + order[k] = 0; + } + + // Now set derivative directions. Note that this takes care + // of the case when dima == dimb + order[dima] = order[dima] + 1; + order[dimb] = order[dimb] + 1; + + // Set order and update + m_DerivativeFilter->SetOrder(order); + m_DerivativeFilter->Update(); + typename RealImageType::Pointer derivativeImage; + derivativeImage = m_DerivativeFilter->GetOutput(); + + progress->ResetFilterProgressAndKeepAccumulatedProgress(); + + // Copy the results to the corresponding component + // on the output image of vectors + m_ImageAdaptor->SelectNthElement(element++); + + ImageRegionIteratorWithIndex it(derivativeImage, derivativeImage->GetRequestedRegion()); + + ImageRegionIteratorWithIndex ot(m_ImageAdaptor, m_ImageAdaptor->GetRequestedRegion()); + + const RealType spacingA = inputImage->GetSpacing()[dima]; + const RealType spacingB = inputImage->GetSpacing()[dimb]; + + const RealType factor = spacingA * spacingB; + + it.GoToBegin(); + ot.GoToBegin(); + while (!it.IsAtEnd()) + { + ot.Set(it.Get() / factor); + ++it; + ++ot; + } + + derivativeImage->ReleaseData(); + } + } +} + +template +void +HessianGaussianImageFilter::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << "DerivativeFilter: " << m_DerivativeFilter << std::endl; +} + +} // end namespace itk + +#endif // itkHessianGaussianImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 2aaa6475ca0..275cc927636 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -13,6 +13,7 @@ set( itkDescoteauxEigenToScalarFunctorTest.cxx itkDescoteauxEigenToScalarFunctorImageTest.cxx itkDescoteauxEigenToScalarImageFilterTest.cxx + itkHessianGaussianImageFilterTest.cxx ) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") @@ -93,3 +94,10 @@ itk_add_test( BoneEnhancementTestDriver itkDescoteauxEigenToScalarImageFilterTest ) + +itk_add_test( + NAME itkHessianGaussianImageFilterTest + COMMAND + BoneEnhancementTestDriver + itkHessianGaussianImageFilterTest +) diff --git a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx new file mode 100644 index 00000000000..186ab1f10cf --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx @@ -0,0 +1,52 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkHessianGaussianImageFilter.h" +#include "itkUnaryFunctorImageFilter.h" +#include "itkTestingMacros.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkMath.h" + +int +itkHessianGaussianImageFilterTest(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::HessianGaussianImageFilter HessianGaussianImageFilterType; + + HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); + + /* Basic tests. */ + EXERCISE_BASIC_OBJECT_METHODS(hess_filter, HessianGaussianImageFilter, ImageToImageFilter); + + /* Exercise basic set/get methods */ + TEST_SET_GET_VALUE(1.0, hess_filter->GetSigma()); + hess_filter->SetSigma(0.5); + TEST_SET_GET_VALUE(0.5, hess_filter->GetSigma()); + + TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + hess_filter->SetNormalizeAcrossScale(true); + TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + hess_filter->NormalizeAcrossScaleOff(); + TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + hess_filter->NormalizeAcrossScaleOn(); + TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + + return EXIT_SUCCESS; +} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap new file mode 100644 index 00000000000..d5ec3c65c39 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkHessianGaussianImageFilter.wrap @@ -0,0 +1,3 @@ +itk_wrap_class("itk::HessianGaussianImageFilter" POINTER) +itk_wrap_image_filter("${WRAP_ITK_SCALAR}" 1) +itk_end_wrap_class() From c8512f38a95d1851cf18495f9fa2a2b3edd30483 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 4 Feb 2018 01:49:40 -0700 Subject: [PATCH 079/150] ENH: Implemented itkEigenToMeasureParameterEstimationFilter --- ...kEigenToMeasureParameterEstimationFilter.h | 179 +++++++++++ ...igenToMeasureParameterEstimationFilter.hxx | 282 ++++++++++++++++++ 2 files changed, 461 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..8a08a093ba4 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,179 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureParameterEstimationFilter_h +#define itkEigenToMeasureParameterEstimationFilter_h + +#include "itkStreamingImageFilter.h" +#include "itkSpatialObject.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace itk +{ +/** \class EigenToMeasureParameterEstimationFilter + * \brief Abstract class for estimating local-structure parameters from eigenvalues. + * + * This is an abstract class that estimates parameters for local-structure enhancement + * from eigen-images. Other classes should inherit from this class so they can be used + * in the MultiScaleHessianEnhancementImageFilter framework. + * + * To estimate the parameters for local-structure enhancement, every pixel in the input + * image must be seen. To implement this functionality in a memory efficinet way, this + * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by + * restricting the output image region. + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa StreamingImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter + : public StreamingImageFilter +{ +public: + /** Standard Self typedef */ + typedef EigenToMeasureParameterEstimationFilter Self; + typedef StreamingImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EigenToMeasureParameterEstimationFilter, StreamingImageFilter); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Input Image typedefs. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Output image typedefs. */ + typedef InputImageType OutputImageType; + typedef InputImageRegionType OutputImageRegionType; + + /** Input SpatialObject typedefs. */ + typedef TInputSpatialObject SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Functor typedefs. */ + typedef TFunction FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + typedef typename ParameterType::ValueType ParameterValueType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; + itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); + + /** Get the functor object. The functor is returned by reference. + * (Functors do not have to derive from itk::LightObject, so they do + * not necessarily have a reference count. So we cannot return a + * SmartPointer.) */ + FunctorType & + GetFunctor() + { + return m_Functor; + } + const FunctorType & + GetFunctor() const + { + return m_Functor; + } + + /** Set the functor object. This replaces the current Functor with a + * copy of the specified Functor. This allows the user to specify a + * functor that has ivars set differently than the default functor. + * This method requires the following to be defined: + * Initialize() + * ProcessPixel() + * GetComputedParameters() + */ + void + SetFunctor(const FunctorType & functor) + { + if (m_Functor != functor) + { + m_Functor = functor; + this->Modified(); + } + } + + /** Decorators for parameters so they can be passed as a process object */ + ParameterDecoratedType * + GetParametersOutput(); + const ParameterDecoratedType * + GetParametersOutput() const; + + /** Standard getters for the parameters */ + ParameterType + GetParameters() const + { + return this->GetParametersOutput()->Get(); + } + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + + /** Override UpdateOutputData() from StreamingImageFilter to divide + * upstream updates into pieces. This filter does not have a GenerateData() + * or ThreadedGenerateData() method. Instead, all the work is done + * in UpdateOutputData() since it must update a little, execute a little, + * update some more, execute some more, etc. */ + void + UpdateOutputData(DataObject * output) ITK_OVERRIDE; + + /** Static function used as a "callback" by the MultiThreader. The threading + * library will call this routine for each thread, which will delegate the + * control to ThreadedGenerateData(). */ + static ITK_THREAD_RETURN_TYPE + ThreaderCallback(void * arg) ITK_OVERRIDE; + + /** Repeatedly call the functor for each pixel we index. */ + void + ThreadedGenerateData(const InputImageRegionType & region, unsigned int streamNumber); + + struct ThreadStruct + { + Pointer Filter; + }; + +protected: + EigenToMeasureParameterEstimationFilter(); + virtual ~EigenToMeasureParameterEstimationFilter() ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); + + /* Private data members. */ + FunctorType m_Functor; + unsigned int m_CurrentSplit; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkEigenToMeasureParameterEstimationFilter.hxx" +#endif + +#endif // itkEigenToMeasureParameterEstimationFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..c1b4177f207 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,282 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureParameterEstimationFilter_hxx +#define itkEigenToMeasureParameterEstimationFilter_hxx + +#include "itkEigenToMeasureParameterEstimationFilter.h" +#include "itkCommand.h" +#include "itkImageAlgorithm.h" +#include "itkImageRegionSplitterSlowDimension.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkImageRegionSplitterBase.h" + +namespace itk +{ +template +EigenToMeasureParameterEstimationFilter:: + EigenToMeasureParameterEstimationFilter() + : m_CurrentSplit(0) +{ + /* We require an input image */ + this->SetNumberOfRequiredInputs(1); + + /* We require an output image and parameters */ + this->SetNumberOfRequiredOutputs(2); + + /* Allocate parameterset decorator */ + typename ParameterDecoratedType::Pointer output = ParameterDecoratedType::New(); + ParameterType initialParameters; + for (unsigned int i = 0; i < initialParameters.Length; ++i) + { + initialParameters[i] = 0; + } + output->Set(initialParameters); + this->ProcessObject::SetNthOutput(1, output.GetPointer()); +} + +template +EigenToMeasureParameterEstimationFilter:: + ~EigenToMeasureParameterEstimationFilter() +{} + +template +void +EigenToMeasureParameterEstimationFilter::ThreadedGenerateData( + const InputImageRegionType & region, + unsigned int streamNumber) +{ + /* If size is zero, return */ + if (region.GetSize(0) == 0) + { + return; + } + + /* Get input pointers */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); + + /* Iterate and count */ + inputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + m_Functor.ProcessPixel(inputIt.Get(), streamNumber); + } + ++inputIt; + } +} + +template +void +EigenToMeasureParameterEstimationFilter::UpdateOutputData( + DataObject * itkNotUsed(output)) +{ + /** Prevent chasing our tail */ + if (this->m_Updating) + { + return; + } + + /** Prepare all the outputs. This may deallocate previous bulk data. */ + this->PrepareOutputs(); + + /** Make sure we have the necessary inputs */ + const itk::ProcessObject::DataObjectPointerArraySizeType & ninputs = this->GetNumberOfValidRequiredInputs(); + if (ninputs < this->GetNumberOfRequiredInputs()) + { + itkExceptionMacro(<< "At least " << static_cast(this->GetNumberOfRequiredInputs()) + << " inputs are required but only " << ninputs << " are specified."); + return; + } + + /** + * Tell all Observers that the filter is starting, + * before emiting the 0.0 Progress event + */ + this->InvokeEvent(StartEvent()); + + this->SetAbortGenerateData(0); + this->UpdateProgress(0.0); + this->m_Updating = true; + + /** Allocate the output buffer. */ + OutputImageType * outputPtr = this->GetOutput(0); + const OutputImageRegionType outputRegion = outputPtr->GetRequestedRegion(); + outputPtr->SetBufferedRegion(outputRegion); + outputPtr->Allocate(); + + /** Grab the input */ + InputImageType * inputPtr = const_cast(this->GetInput(0)); + + /** + * Determine of number of pieces to divide the input. This will be the + * minimum of what the user specified via SetNumberOfStreamDivisions() + * and what the Splitter thinks is a reasonable value. + */ + unsigned int numDivisions, numDivisionsFromSplitter; + + numDivisions = this->GetNumberOfStreamDivisions(); + numDivisionsFromSplitter = + this->GetRegionSplitter()->GetNumberOfSplits(outputRegion, this->GetNumberOfStreamDivisions()); + if (numDivisionsFromSplitter < numDivisions) + { + numDivisions = numDivisionsFromSplitter; + } + + /* Tell the functor the number of times we will call it (potentially) */ + m_Functor.Initialize(this->GetNumberOfStreamDivisions() * this->GetNumberOfThreads()); + + /** + * Loop over the number of pieces, execute the upstream pipeline on each + * piece, and copy the results into the output image. + */ + for (unsigned int piece = 0; piece < numDivisions && !this->GetAbortGenerateData(); piece++) + { + /* Set the current peice */ + m_CurrentSplit = piece; + + /* Determine the split region and calculate the input */ + InputImageRegionType streamRegion = outputRegion; + this->GetRegionSplitter()->GetSplit(piece, numDivisions, streamRegion); + inputPtr->SetRequestedRegion(streamRegion); + inputPtr->PropagateRequestedRegion(); + inputPtr->UpdateOutputData(); + + /* Setup a multithreadign process */ + ThreadStruct str; + str.Filter = this; + + // Get the output pointer + const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); + const unsigned int validThreads = splitter->GetNumberOfSplits(streamRegion, this->GetNumberOfThreads()); + + this->GetMultiThreader()->SetNumberOfThreads(validThreads); + this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); + + // multithread the execution + this->GetMultiThreader()->SingleMethodExecute(); + + // copy the result to the proper place in the output. the input + // requested region determined by the RegionSplitter (as opposed + // to what the pipeline might have enlarged it to) is used to + // copy the regions from the input to output + if (inputPtr != outputPtr) + { + ImageAlgorithm::Copy(inputPtr, outputPtr, streamRegion, streamRegion); + } + + /* Update progress and stream another chunk */ + this->UpdateProgress(static_cast(piece) / static_cast(numDivisions)); + } + + /* Compute and set the parameters */ + this->GetParametersOutput()->Set(m_Functor.GetComputedParameters()); + + /** + * If we ended due to aborting, push the progress up to 1.0 + * (since it probably didn't end there) + */ + if (!this->GetAbortGenerateData()) + { + this->UpdateProgress(1.0); + } + + /** Notify end event observers */ + this->InvokeEvent(EndEvent()); + + /** Now we have to mark the data as up to data. */ + for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) + { + if (this->GetOutput(idx)) + { + this->GetOutput(idx)->DataHasBeenGenerated(); + } + } + + /** Release any inputs if marked for release */ + this->ReleaseInputs(); + + /** Mark that we are no longer updating the data in this filter */ + this->m_Updating = false; +} + +template +ITK_THREAD_RETURN_TYPE +EigenToMeasureParameterEstimationFilter::ThreaderCallback(void * arg) +{ + ThreadStruct * str; + ThreadIdType total, threadId, threadCount; + + threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; + threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads; + + str = (ThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData); + + // execute the actual method with appropriate output region + // first find out how many pieces extent can be split into. + typename OutputImageType::RegionType splitRegion; + total = str->Filter->SplitRequestedRegion(threadId, threadCount, splitRegion); + unsigned int streamNumber = str->Filter->m_CurrentSplit; + + if (threadId < total) + { + str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions() * threadId + streamNumber); + } + // else + // { + // otherwise don't use this thread. Sometimes the threads dont + // break up very well and it is just as efficient to leave a + // few threads idle. + // } + + return ITK_THREAD_RETURN_VALUE; +} + +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +const typename EigenToMeasureParameterEstimationFilter:: + ParameterDecoratedType * + EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +{ + return static_cast(this->ProcessObject::GetOutput(1)); +} + +template +void +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace itk + +#endif // itkEigenToMeasureParameterEstimationFilter_hxx From e95e9b78e0432046b8c8afb6816fa71e991032e3 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sun, 4 Feb 2018 01:50:18 -0700 Subject: [PATCH 080/150] ENH: Implemented DescoteauxEigenToMeasureParameterEstimationFilter --- ...xEigenToMeasureParameterEstimationFilter.h | 233 +++++++++++++++++ ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 141 ++++++++++ ...asureParameterEstimationFilterUnitTest.cxx | 242 ++++++++++++++++++ 3 files changed, 616 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..a0e76653916 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,233 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_h +#define itkDescoteauxEigenToMeasureParameterEstimationFilter_h + +#include "itkFixedArray.h" +#include "itkMath.h" +#include "itkEigenToMeasureParameterEstimationFilter.h" + +namespace itk +{ +namespace Functor +{ +/** \class DescoteauxEigenParameterFunctor + * \brief Automatic parameter estimation as defined by Descoteaux et al. + * + * The default parameters are: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 max\( Frobenius norm \) + * \f} + * + * Where the Frobenius norm for a real, symmetric matrix is given by + * the square root of the sum of squares of the eigenvalues. + * + * One can set FrobeniusNormWeight to control the weighting on the + * Frobenius norm. + * + * \sa DescoteauxEigentoScalarParameterEstimationImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenParameterFunctor +{ +public: + /* Basic type definitions */ + itkStaticConstMacro(NumberOfParameters, unsigned int, 3); + typedef typename TInputPixel::ValueType PixelValueType; + typedef typename NumericTraits::RealType RealType; + typedef FixedArray ParameterType; + + DescoteauxEigenParameterFunctor() + : m_FrobeniusNormWeight(0.5) + { + m_MaxFrobeniusNormArray.SetSize(0); + } + + void + Initialize(unsigned int numberOfCalls) + { + m_MaxFrobeniusNormArray.SetSize(numberOfCalls); + m_MaxFrobeniusNormArray.Fill(NumericTraits::ZeroValue()); + } + + void + ProcessPixel(const TInputPixel & inputPixel, unsigned int callNumber) + { + RealType norm = CalculateFrobeniusNorm(inputPixel); + if (norm > m_MaxFrobeniusNormArray[callNumber]) + { + m_MaxFrobeniusNormArray[callNumber] = norm; + } + } + + ParameterType + GetComputedParameters() + { + /* Alpha is 0.5 */ + m_Parameters[0] = 0.5; + + /* Beta is 0.5 */ + m_Parameters[1] = 0.5; + + /* C is m_FrobeniusNormWeight * max(frobenius norm) */ + m_Parameters[2] = 0; + for (unsigned int i = 0; i < m_MaxFrobeniusNormArray.GetSize(); ++i) + { + if (m_MaxFrobeniusNormArray[i] > m_Parameters[2]) + { + m_Parameters[2] = m_MaxFrobeniusNormArray[i]; + } + } + + /* Weight by the selection parmaeter */ + m_Parameters[2] = m_FrobeniusNormWeight * m_Parameters[2]; + + /* Finally, return the parameters we found */ + return m_Parameters; + } + + void + SetFrobeniusNormWeight(RealType weight) + { + m_FrobeniusNormWeight = weight; + } + + RealType + GetFrobeniusNormWeight() const + { + return m_FrobeniusNormWeight; + } + +private: + inline RealType + CalculateFrobeniusNorm(const TInputPixel & pixel) + { + /* Forbenius norm is given by the square root of the sum of squares + * of the eigenvalues for real, symmetric matricies + */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i] * pixel[i]; + } + return sqrt(norm); + } + + /* Private member variables */ + RealType m_FrobeniusNormWeight; + Array m_MaxFrobeniusNormArray; + ParameterType m_Parameters; +}; // end class +} // namespace Functor + +/** \class DescoteauxEigenToMeasureParameterEstimationFilter + * \brief Automatic parameter estimation as defined by Descoteaux et al. + * + * The default parameters are: + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.5 max\( Frobenius norm \) + * \f} + * + * Where the Frobenius norm for a real, symmetric matrix is given by + * the square root of the sum of squares of the eigenvalues. + * + * If the input image and mask have different regions over which they + * are defined, parameters are estimated only in the intersection of + * the two image regions. However, the mask region must be a proper sub + * subset (contained) in the image region. + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter< + TInputImage, + TInputSpatialObject, + Functor::DescoteauxEigenParameterFunctor> +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter< + TInputImage, + TInputSpatialObject, + Functor::DescoteauxEigenParameterFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Functor typedef */ + typedef typename Superclass::FunctorType FunctorType; + typedef typename FunctorType::RealType RealType; + typedef typename FunctorType::ParameterType ParameterType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(DescoteauxEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); + + /** Define decorator types */ + typedef SimpleDataObjectDecorator InputParameterDecoratorType; + + /** setter/getter methods for setting type of object to enhance */ + void + SetFrobeniusNormWeight(RealType weight) + { + this->GetFunctor().SetFrobeniusNormWeight(weight); + } + RealType + GetFrobeniusNormWeight() const + { + return this->GetFunctor().GetFrobeniusNormWeight(); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif + +protected: + DescoteauxEigenToMeasureParameterEstimationFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); + + void + PrintSelf(std::ostream & os, Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; + } +}; // end class +} // namespace itk + +#endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx new file mode 100644 index 00000000000..f71dd2a7eaa --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx @@ -0,0 +1,141 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Functor::DescoteauxEigenParameterFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureFunctorUnitTest() + { + m_Functor = FunctorType(); + m_EigenPixel = EigenValueArrayType(); + } + ~itkDescoteauxEigenToMeasureFunctorUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FunctorType m_Functor; + EigenValueArrayType m_EigenPixel; + ParameterType m_Parameters; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetFrobeniusNormWeight) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + this->m_Functor.SetFrobeniusNormWeight(0.1); + EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfZero) +{ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOne) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + this->m_Functor.SetFrobeniusNormWeight(0.1); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestMultiplePixels) +{ + unsigned int num = 10; + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(num); + for (unsigned int i = 0; i < num; ++i) + { + for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) + { + this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; + } + + this->m_Functor.ProcessPixel(this->m_EigenPixel, i); + } + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx new file mode 100644 index 00000000000..07913da2dda --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -0,0 +1,242 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::DescoteauxEigenToMeasureParameterEstimationFilter FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + m_LargeEigenPixel[i] = 100; + } + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + typename EigenImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(maskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + maskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex input(m_MaskingEigenImage, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, maskRegion); + + input.GoToBegin(); + maskIt.GoToBegin(); + while (!input.IsAtEnd()) + { + input.Set(m_LargeEigenPixel); + maskIt.Set(1); + ++input; + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_LargeEigenPixel; + ParameterType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Filter->GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImage) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImage) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageWithDifferentWeight) +{ + this->m_Filter->SetFrobeniusNormWeight(0.1); + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObject) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(86.6025403784, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} From 69082584b84a603baa73766de927d4ec18cadf8f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:13:56 -0700 Subject: [PATCH 081/150] DOC: Fixed naming for DescoteauxEigenToMeasureParameterFunctor --- ...xEigenToMeasureParameterEstimationFilter.h | 11 +- ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 251 ++++++++++++++---- ...EigenToMeasureParameterFunctorUnitTest.cxx | 141 ++++++++++ 3 files changed, 340 insertions(+), 63 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index a0e76653916..b2f0f7d2705 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -27,7 +27,7 @@ namespace itk { namespace Functor { -/** \class DescoteauxEigenParameterFunctor +/** \class DescoteauxEigenToMeasureParameterFunctor * \brief Automatic parameter estimation as defined by Descoteaux et al. * * The default parameters are: @@ -49,7 +49,7 @@ namespace Functor * \ingroup BoneEnhancement */ template -class DescoteauxEigenParameterFunctor +class DescoteauxEigenToMeasureParameterFunctor { public: /* Basic type definitions */ @@ -58,7 +58,7 @@ class DescoteauxEigenParameterFunctor typedef typename NumericTraits::RealType RealType; typedef FixedArray ParameterType; - DescoteauxEigenParameterFunctor() + DescoteauxEigenToMeasureParameterFunctor() : m_FrobeniusNormWeight(0.5) { m_MaxFrobeniusNormArray.SetSize(0); @@ -169,7 +169,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject, - Functor::DescoteauxEigenParameterFunctor> + Functor::DescoteauxEigenToMeasureParameterFunctor> { public: /** Standard Self typedef */ @@ -177,7 +177,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter typedef EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject, - Functor::DescoteauxEigenParameterFunctor> + Functor::DescoteauxEigenToMeasureParameterFunctor> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; @@ -201,6 +201,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter SetFrobeniusNormWeight(RealType weight) { this->GetFunctor().SetFrobeniusNormWeight(weight); + this->Modified(); } RealType GetFrobeniusNormWeight() const diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx index f71dd2a7eaa..f30077f7e74 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx @@ -17,7 +17,7 @@ *=========================================================================*/ #include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" namespace { @@ -26,11 +26,13 @@ class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test { public: /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Functor::DescoteauxEigenParameterFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::Image ImageType; + typedef typename itk::Functor::DescoteauxEigenToMeasureFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; itkDescoteauxEigenToMeasureFunctorUnitTest() { @@ -54,88 +56,221 @@ class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +typedef ::testing::Types TestingLabelTypes; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) { - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetFrobeniusNormWeight) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetEnhanceType) { - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - this->m_Functor.SetFrobeniusNormWeight(0.1); - EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); + this->m_Functor.SetEnhanceDarkObjects(); + EXPECT_DOUBLE_EQ(1.0, this->m_Functor.GetEnhanceType()); + this->m_Functor.SetEnhanceBrightObjects(); + EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfZero) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetParameters) { + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); + + this->m_Parameters[0] = 100; + this->m_Parameters[1] = 200; + this->m_Parameters[2] = 300; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Parameters = this->m_Functor.GetParameters(); + EXPECT_DOUBLE_EQ(100.0, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(200.0, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(300.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFirstParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ this->m_EigenPixel[0] = 0; this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFirstParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOne) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSecondParameterSet) { - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSecondParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightThirdParameterSet) { - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkThirdParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFourthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - this->m_Functor.SetFrobeniusNormWeight(0.1); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 + EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); } -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, TestMultiplePixels) +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFourthParameterSet) { - unsigned int num = 10; + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ this->m_EigenPixel[0] = 0; this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(num); - for (unsigned int i = 0; i < num; ++i) - { - for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) - { - this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; - } + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Functor.ProcessPixel(this->m_EigenPixel, i); - } +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFifthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFifthParameterSet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSixthParameterSet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceBrightObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = -1; + EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); +} - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSixthParameterSet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Functor.SetParameters(this->m_Parameters); + this->m_Functor.SetEnhanceDarkObjects(); + + /* All zeros returns zero */ + this->m_EigenPixel[0] = 0.25; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); } diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx new file mode 100644 index 00000000000..c4583e6f8a3 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx @@ -0,0 +1,141 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureParameterFunctorUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Functor::DescoteauxEigenToMeasureParameterFunctor FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureParameterFunctorUnitTest() + { + m_Functor = FunctorType(); + m_EigenPixel = EigenValueArrayType(); + } + ~itkDescoteauxEigenToMeasureParameterFunctorUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FunctorType m_Functor; + EigenValueArrayType m_EigenPixel; + ParameterType m_Parameters; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, InitialParameters) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, SetGetFrobeniusNormWeight) +{ + EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); + this->m_Functor.SetFrobeniusNormWeight(0.1); + EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfZero) +{ + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOne) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOneWithDifferentWeight) +{ + this->m_EigenPixel[0] = 1; + this->m_EigenPixel[1] = 1; + this->m_EigenPixel[2] = 1; + this->m_Functor.Initialize(1); + this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); + this->m_Functor.SetFrobeniusNormWeight(0.1); + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 +} + +TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestMultiplePixels) +{ + unsigned int num = 10; + this->m_EigenPixel[0] = 0; + this->m_EigenPixel[1] = 0; + this->m_EigenPixel[2] = 0; + this->m_Functor.Initialize(num); + for (unsigned int i = 0; i < num; ++i) + { + for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) + { + this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; + } + + this->m_Functor.ProcessPixel(this->m_EigenPixel, i); + } + + this->m_Parameters = this->m_Functor.GetComputedParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 +} From 71e528130512cfa46053c824e2f3965c9938c871 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:14:39 -0700 Subject: [PATCH 082/150] BUG: Fixed initialization bug in HessianGaussianImageFilter --- .../BoneEnhancement/include/itkHessianGaussianImageFilter.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index 36c0b3fe27f..df685bdae4e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -43,7 +43,7 @@ HessianGaussianImageFilter::HessianGaussianImageFilte m_ImageAdaptor = OutputImageAdaptorType::New(); // Setup defaults - this->SetNormalizeAcrossScale(true); + this->SetNormalizeAcrossScale(false); this->SetSigma(1.0); } From fde7787845ff3dcfa2c7a400988217ede0d6261f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:15:51 -0700 Subject: [PATCH 083/150] ENH: Added EigenToMeasureImageFilter and DescoteauxEigenToMeasureImageFilter --- .../itkDescoteauxEigenToMeasureImageFilter.h | 240 +++++++++++++ .../include/itkEigenToMeasureImageFilter.h | 167 +++++++++ .../include/itkEigenToMeasureImageFilter.hxx | 105 ++++++ .../BoneEnhancement/test/CMakeLists.txt | 80 +---- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 320 ++++++++++++++++++ 5 files changed, 841 insertions(+), 71 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h new file mode 100644 index 00000000000..edbaf6d48e6 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -0,0 +1,240 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureImageFilter_h +#define itkDescoteauxEigenToMeasureImageFilter_h + +#include "itkEigenToMeasureImageFilter.h" +#include "itkMath.h" + +namespace itk +{ +namespace Functor +{ +/** \class DescoteauxEigenToMeasureFunctor + * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. + * + * Computes the following equation for eigenvalues in a three + * dimensional fixed array: + * \f{eqnarray*}{ + * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ + * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ + * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ + * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) + * \f} + * + * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. + * + * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter + * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. + * + * \sa DescoteauxEigentoScalarParameterEstimationImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureFunctor +{ +public: + /* Basic type definitions */ + itkStaticConstMacro(NumberOfParameters, unsigned int, 3); + typedef typename TInputPixel::ValueType PixelValueType; + typedef typename NumericTraits::RealType RealType; + typedef FixedArray ParameterType; + + DescoteauxEigenToMeasureFunctor() + : m_Direction(-1.0) + , m_Alpha(0.0) + , m_Beta(0.0) + , m_C(0.0) + {} + + inline TOutputPixel + operator()(const TInputPixel & A) + { + double sheetness = 0.0; + double a1 = static_cast(A[0]); + double a2 = static_cast(A[1]); + double a3 = static_cast(A[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Deal with l3 > 0 */ + if (m_Direction * a3 < 0) + { + return static_cast(0.0); + } + + /* Avoid divisions by zero (or close to zero) */ + if (l3 < Math::eps) + { + return static_cast(0.0); + } + + /* Compute measures */ + const double Rsheet = l2 / l3; + const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; + const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); + + /* Multiply together to get sheetness */ + sheetness = 1.0; + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); + sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); + + return static_cast(sheetness); + } + + /** Macro definition for set/get of parameters */ + virtual void + SetParameters(const ParameterType parameters) + { + this->m_Alpha = parameters[0]; + this->m_Beta = parameters[1]; + this->m_C = parameters[2]; + } + + virtual ParameterType + GetParameters() const + { + ParameterType parameters; + parameters[0] = this->m_Alpha; + parameters[1] = this->m_Beta; + parameters[2] = this->m_C; + + return parameters; + } + + /** Set/get the type to enhance */ + void + SetEnhanceBrightObjects() + { + m_Direction = -1.0; + } + void + SetEnhanceDarkObjects() + { + m_Direction = 1.0; + } + RealType + GetEnhanceType() const + { + return m_Direction; + } + +private: + /* Private member variables */ + RealType m_Alpha; + RealType m_Beta; + RealType m_C; + RealType m_Direction; +}; // end class +} // namespace Functor + +/** \class DescoteauxEigenToMeasureImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. + * + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Descoteaux et al. The parameters of the filter should be set using + * DescoteauxEigentoScalarParameterEstimationImageFilter. + * + * See functor DescoteauxEigenToScalarFunctor for mathematics. + * + * \sa DescoteauxEigenToMeasureFunctor + * \sa DescoteauxEigenToScalarImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class DescoteauxEigenToMeasureImageFilter + : public EigenToMeasureImageFilter< + TInputImage, + TOutputImage, + TInputSpatialObject, + Functor::DescoteauxEigenToMeasureFunctor> +{ +public: + /** Standard Self typedef */ + typedef DescoteauxEigenToMeasureImageFilter Self; + typedef EigenToMeasureImageFilter< + TInputImage, + TOutputImage, + TInputSpatialObject, + Functor::DescoteauxEigenToMeasureFunctor> + Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Functor typedef */ + typedef typename Superclass::FunctorType FunctorType; + typedef typename FunctorType::RealType RealType; + typedef typename FunctorType::ParameterType ParameterType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(DescoteauxEigenToMeasureImageFilter, EigenToMeasureImageFilter); + + /** setter/getter methods for setting type of object to enhance */ + void + SetEnhanceBrightObjects() + { + this->GetFunctor().SetEnhanceBrightObjects(); + this->Modified(); + } + void + SetEnhanceDarkObjects() + { + this->GetFunctor().SetEnhanceDarkObjects(); + this->Modified(); + } + RealType + GetEnhanceType() const + { + return this->GetFunctor().GetEnhanceType(); + } + + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif + +protected: + DescoteauxEigenToMeasureImageFilter() {} + virtual ~DescoteauxEigenToMeasureImageFilter() {} + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); +}; // end class +} /* end namespace itk */ + +#endif /* itkDescoteauxEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h new file mode 100644 index 00000000000..0ac86321f27 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -0,0 +1,167 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureImageFilter_h +#define itkEigenToMeasureImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkSpatialObject.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace itk +{ +/** \class EigenToMeasureImageFilter + * \brief Abstract class for computing a measure from local structure. + * + * TODO + * + * This is an abstract class that estimates parameters for local-structure enhancement + * from eigen-images. Other classes should inherit from this class so they can be used + * in the MultiScaleHessianEnhancementImageFilter framework. + * + * To estimate the parameters for local-structure enhancement, every pixel in the input + * image must be seen. To implement this functionality in a memory efficinet way, this + * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by + * restricting the output image region. + * + * \sa MultiScaleHessianEnhancementImageFilter + * \sa UnaryFunctorImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter +{ +public: + /** Standard Self typedef */ + typedef EigenToMeasureImageFilter Self; + typedef ImageToImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EigenToMeasureImageFilter, ImageToImageFilter); + + /** Input Image typedefs. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Output image typedefs. */ + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointer; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef TInputSpatialObject SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Functor typedefs. */ + typedef TFunction FunctorType; + typedef typename FunctorType::ParameterType ParameterType; + typedef typename ParameterType::ValueType ParameterValueType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; + itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); + + /** Get the functor object. The functor is returned by reference. + * (Functors do not have to derive from itk::LightObject, so they do + * not necessarily have a reference count. So we cannot return a + * SmartPointer.) */ + FunctorType & + GetFunctor() + { + return m_Functor; + } + const FunctorType & + GetFunctor() const + { + return m_Functor; + } + + /** Set the functor object. This replaces the current Functor with a + * copy of the specified Functor. This allows the user to specify a + * functor that has ivars set differently than the default functor. + * This method requires the following to be defined: + * Initialize() + * ProcessPixel() + * GetComputedParameters() + */ + void + SetFunctor(const FunctorType & functor) + { + if (m_Functor != functor) + { + m_Functor = functor; + this->Modified(); + } + } + + /** Process object */ + itkSetGetDecoratedInputMacro(Parameters, ParameterType); + + /** Methods to set/get the mask image */ + itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + + /** Template the EigenValueOrderType. Methods that inherit from this class can override this function + * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from + * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial + * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type + * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. + */ + typedef enum + { + OrderByValue = 1, + OrderByMagnitude, + DoNotOrder + } EigenValueOrderType; + virtual EigenValueOrderType + GetEigenValueOrder() const = 0; + +protected: + EigenToMeasureImageFilter(); + virtual ~EigenToMeasureImageFilter() ITK_OVERRIDE; + + /** Need to access the input parameters at execution time */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); + + /* Private data members. */ + ParameterType m_Parameters; + FunctorType m_Functor; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkEigenToMeasureImageFilter.hxx" +#endif + +#endif /* itkEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx new file mode 100644 index 00000000000..59e8d464298 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx @@ -0,0 +1,105 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureImageFilter_hxx +#define itkEigenToMeasureImageFilter_hxx + +#include "itkEigenToMeasureImageFilter.h" +#include "itkProgressReporter.h" +#include "itkNumericTraits.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkImageRegionIterator.h" + +namespace itk +{ + +template +EigenToMeasureImageFilter::EigenToMeasureImageFilter() +{ + this->SetNumberOfRequiredInputs(1); +} + +template +EigenToMeasureImageFilter::~EigenToMeasureImageFilter() +{} + +template +void +EigenToMeasureImageFilter::BeforeThreadedGenerateData() + ITK_OVERRIDE +{ + /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ + this->GetFunctor().SetParameters(this->GetParametersInput()->Get()); +} + +template +void +EigenToMeasureImageFilter::ThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + InputImageConstPointer inputPtr = this->GetInput(); + OutputImagePointer outputPtr = this->GetOutput(0); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + // Define the iterators + ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); + + inputIt.GoToBegin(); + outputIt.GoToBegin(); + + while (!inputIt.IsAtEnd()) + { + inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + outputIt.Set(m_Functor(inputIt.Get())); + } + else + { + outputIt.Set(NumericTraits::Zero); + } + ++inputIt; + ++outputIt; + progress.CompletedPixel(); // potential exception thrown here + } +} + +template +void +EigenToMeasureImageFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "m_Parameters: " << this->GetParametersInput() << std::endl; +} + +} /* end namespace itk */ + +#endif /* itkEigenToMeasureImageFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 275cc927636..80fec36e66d 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -4,15 +4,6 @@ set( BoneEnhancementTests itkMaximumAbsoluteValueImageFilterTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx - itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx - itkKrcahEigenToScalarFunctorTest.cxx - itkKrcahEigenToScalarFunctorImageFilterTest.cxx - itkKrcahEigenToScalarImageFilterTest.cxx - itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx - itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx - itkDescoteauxEigenToScalarFunctorTest.cxx - itkDescoteauxEigenToScalarFunctorImageTest.cxx - itkDescoteauxEigenToScalarImageFilterTest.cxx itkHessianGaussianImageFilterTest.cxx ) @@ -33,71 +24,18 @@ itk_add_test( ) itk_add_test( - NAME itkKrcahEigenToScalarParameterEstimationImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarParameterEstimationImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarFunctorTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarFunctorTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarFunctorImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarFunctorImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarImageFilterTest -) - -itk_add_test( - NAME itkKrcahEigenToScalarPreprocessingImageToImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkKrcahEigenToScalarPreprocessingImageToImageFilterTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarParameterEstimationImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarParameterEstimationImageFilterTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarFunctorTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarFunctorTest -) - -itk_add_test( - NAME itkDescoteauxEigenToScalarFunctorImageTest + NAME itkHessianGaussianImageFilterTest COMMAND BoneEnhancementTestDriver - itkDescoteauxEigenToScalarFunctorImageTest + itkHessianGaussianImageFilterTest ) -itk_add_test( - NAME itkDescoteauxEigenToScalarImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkDescoteauxEigenToScalarImageFilterTest +set( + BoneEnhancementUnitTests + itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx + itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx + itkDescoteauxEigenToMeasureFunctorUnitTest.cxx + itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx ) -itk_add_test( - NAME itkHessianGaussianImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkHessianGaussianImageFilterTest -) +creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx new file mode 100644 index 00000000000..78bb12a4925 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -0,0 +1,320 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::Image OutputPixelType; + typedef float EigenPixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::DescoteauxEigenToMeasureImageFilter + FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterType ParameterType; + + itkDescoteauxEigenToMeasureImageFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + } + m_NonZeroEigenPixel[0] = 0.25; + m_NonZeroEigenPixel[1] = 1; + m_NonZeroEigenPixel[2] = -1; + m_NonZeroDarkEigenPixel[0] = 0.25; + m_NonZeroDarkEigenPixel[1] = 1; + m_NonZeroDarkEigenPixel[2] = 1; + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_NonZeroEigenImage = EigenImageType::New(); + m_NonZeroEigenImage->SetRegions(m_Region); + m_NonZeroEigenImage->Allocate(); + m_NonZeroEigenImage->FillBuffer(m_NonZeroEigenPixel); + + m_NonZeroDarkEigenImage = EigenImageType::New(); + m_NonZeroDarkEigenImage->SetRegions(m_Region); + m_NonZeroDarkEigenImage->Allocate(); + m_NonZeroDarkEigenImage->FillBuffer(m_NonZeroDarkEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + m_MaskRegion.SetSize(maskSize); + m_MaskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(m_MaskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + m_MaskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, m_MaskRegion); + + maskIt.GoToBegin(); + while (!maskIt.IsAtEnd()) + { + maskIt.Set(1); + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkDescoteauxEigenToMeasureImageFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_NonZeroEigenImage; + typename EigenImageType::Pointer m_NonZeroDarkEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_NonZeroEigenPixel; + EigenValueArrayType m_NonZeroDarkEigenPixel; + ParameterType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename EigenImageType::RegionType m_MaskRegion; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, InitialParameters) +{ + /* Default enhance bright structures */ + EXPECT_DOUBLE_EQ(-1.0, this->m_Filter->GetEnhanceType()); + + EXPECT_EQ(2, this->m_Filter->GetEigenValueOrder()); +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestZerosImage) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 1; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_ZerosEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_EQ(0.0, input.Get()); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelBrightSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0913983433747, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelDarkSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->SetEnhanceDarkObjects(); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixelBrightSheet) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixelDarkSheet) +{ + this->m_Parameters[0] = 0.25; + this->m_Parameters[1] = 0.25; + this->m_Parameters[2] = 0.5; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); + this->m_Filter->SetEnhanceDarkObjects(); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_NEAR((TypeParam)0.000326373962098, input.Get(), 1e-6); + ++input; + } +} + +TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject) +{ + this->m_Parameters[0] = 0.5; + this->m_Parameters[1] = 0.5; + this->m_Parameters[2] = 0.25; + this->m_Filter->SetParameters(this->m_Parameters); + this->m_Filter->SetInput(this->m_NonZeroEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->Update(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + itk::ContinuousIndex point; + + std::cout << this->m_MaskRegion << std::endl; + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + this->m_Filter->GetOutput()->TransformIndexToPhysicalPoint(input.GetIndex(), point); + if (this->m_MaskRegion.IsInside(point)) + { + ASSERT_NEAR((TypeParam)0.0913983433747, input.Get(), 1e-6); + } + else + { + ASSERT_NEAR((TypeParam)0.0, input.Get(), 1e-6); + } + ++input; + } +} From 0f2c5bcc6f24550887680d9da59ae705938deaed Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Tue, 6 Feb 2018 17:16:23 -0700 Subject: [PATCH 084/150] DOC: Added documentation to MaximumAbsoluteValue Functor --- .../include/itkMaximumAbsoluteValueImageFilter.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index a71a9cab88d..ab8636b60d2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -26,6 +26,19 @@ namespace itk { namespace Functor { +/** \class MaximumAbsoluteValue + * \brief Compute the maximum (of the absolute value) between two images. + * + * This class takes two images as arguments and returns the maximum + * of the absolute value pixel wise. For instance, two pixels with + * values 2 and -3 would return -3, since the absolute value of -3 + * is larger than 2. + * + * \sa MultiScaleHessianEnhancementImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ template class MaximumAbsoluteValue { From 0d85346b377696b04fe4d93f7c3cb1bb6d2eba3e Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 7 Feb 2018 17:41:23 -0700 Subject: [PATCH 085/150] ENH: Added ITKReview --- Modules/Filtering/BoneEnhancement/itk-module.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/itk-module.cmake b/Modules/Filtering/BoneEnhancement/itk-module.cmake index 73719fc4f24..511c4ba5f46 100644 --- a/Modules/Filtering/BoneEnhancement/itk-module.cmake +++ b/Modules/Filtering/BoneEnhancement/itk-module.cmake @@ -15,6 +15,8 @@ itk_module( ITKStatistics ITKImageFilterBase ITKImageFeature + ITKReview + ITKSpatialObjects COMPILE_DEPENDS ITKImageSources TEST_DEPENDS From 112aee13f60cc8795c933ea34d0fa94e2c6f7f96 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 28 Feb 2018 15:24:06 -0700 Subject: [PATCH 086/150] ENH: Descoteaux implementation --- .../itkDescoteauxEigenToMeasureImageFilter.h | 231 ++++--------- ...tkDescoteauxEigenToMeasureImageFilter.hxx} | 102 ++++-- ...xEigenToMeasureParameterEstimationFilter.h | 225 ++++--------- ...igenToMeasureParameterEstimationFilter.hxx | 182 +++++++++++ ...escoteauxEigenToScalarFunctorImageFilter.h | 259 --------------- .../itkDescoteauxEigenToScalarImageFilter.h | 199 ----------- .../itkDescoteauxEigenToScalarImageFilter.hxx | 101 ------ ...enToScalarParameterEstimationImageFilter.h | 190 ----------- ...ToScalarParameterEstimationImageFilter.hxx | 266 --------------- .../include/itkEigenToMeasureImageFilter.h | 95 ++---- ...kEigenToMeasureParameterEstimationFilter.h | 88 ++--- ...igenToMeasureParameterEstimationFilter.hxx | 202 +++++------- .../include/itkEigenToScalarImageFilter.h | 88 ----- .../include/itkHessianGaussianImageFilter.hxx | 7 +- .../itkKrcahEigenToScalarFunctorImageFilter.h | 250 -------------- .../itkKrcahEigenToScalarImageFilter.h | 212 ------------ .../itkKrcahEigenToScalarImageFilter.hxx | 99 ------ ...enToScalarParameterEstimationImageFilter.h | 239 -------------- ...ToScalarParameterEstimationImageFilter.hxx | 309 ------------------ ...nToScalarPreprocessingImageToImageFilter.h | 146 --------- ...oScalarPreprocessingImageToImageFilter.hxx | 192 ----------- .../itkMaximumAbsoluteValueImageFilter.h | 2 +- ...kMultiScaleHessianEnhancementImageFilter.h | 103 ++++-- ...ultiScaleHessianEnhancementImageFilter.hxx | 153 +++++++-- .../BoneEnhancement/itk-module.cmake | 1 - .../BoneEnhancement/test/CMakeLists.txt | 2 - ...escoteauxEigenToMeasureFunctorUnitTest.cxx | 276 ---------------- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 16 +- ...asureParameterEstimationFilterUnitTest.cxx | 14 +- ...EigenToMeasureParameterFunctorUnitTest.cxx | 141 -------- ...escoteauxEigenToScalarFunctorImageTest.cxx | 121 ------- .../itkDescoteauxEigenToScalarFunctorTest.cxx | 121 ------- ...DescoteauxEigenToScalarImageFilterTest.cxx | 94 ------ ...alarParameterEstimationImageFilterTest.cxx | 170 ---------- .../test/itkKrcahEigenToScalarFunctorTest.cxx | 155 --------- ...larPreprocessingImageToImageFilterTest.cxx | 43 --- ...itkDescoteauxEigenToScalarImageFilter.wrap | 13 - .../wrapping/itkEigenToScalarImageFilter.wrap | 11 - .../itkKrcahEigenToScalarImageFilter.wrap | 22 -- ...ScalarPreprocessingImageToImageFilter.wrap | 3 - 40 files changed, 719 insertions(+), 4424 deletions(-) rename Modules/Filtering/BoneEnhancement/include/{itkEigenToMeasureImageFilter.hxx => itkDescoteauxEigenToMeasureImageFilter.hxx} (50%) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap delete mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index edbaf6d48e6..04d79a467c3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -24,13 +24,14 @@ namespace itk { -namespace Functor -{ -/** \class DescoteauxEigenToMeasureFunctor - * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. +/** \class DescoteauxEigenToMeasureImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Descoteaux et al. The parameters of the filter should be set using + * DescoteauxEigentoScalarParameterEstimationImageFilter. + * + * Computes the following equation for eigenvalues in a three dimensional fixed array: * \f{eqnarray*}{ * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ @@ -41,153 +42,45 @@ namespace Functor * * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. * - * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter - * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToMeasureFunctor -{ -public: - /* Basic type definitions */ - itkStaticConstMacro(NumberOfParameters, unsigned int, 3); - typedef typename TInputPixel::ValueType PixelValueType; - typedef typename NumericTraits::RealType RealType; - typedef FixedArray ParameterType; - - DescoteauxEigenToMeasureFunctor() - : m_Direction(-1.0) - , m_Alpha(0.0) - , m_Beta(0.0) - , m_C(0.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Deal with l3 > 0 */ - if (m_Direction * a3 < 0) - { - return static_cast(0.0); - } - - /* Avoid divisions by zero (or close to zero) */ - if (l3 < Math::eps) - { - return static_cast(0.0); - } - - /* Compute measures */ - const double Rsheet = l2 / l3; - const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); - - /* Multiply together to get sheetness */ - sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetParameters(const ParameterType parameters) - { - this->m_Alpha = parameters[0]; - this->m_Beta = parameters[1]; - this->m_C = parameters[2]; - } - - virtual ParameterType - GetParameters() const - { - ParameterType parameters; - parameters[0] = this->m_Alpha; - parameters[1] = this->m_Beta; - parameters[2] = this->m_C; - - return parameters; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_C; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class DescoteauxEigenToMeasureImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Descoteaux et al. The parameters of the filter should be set using - * DescoteauxEigentoScalarParameterEstimationImageFilter. - * - * See functor DescoteauxEigenToScalarFunctor for mathematics. - * - * \sa DescoteauxEigenToMeasureFunctor - * \sa DescoteauxEigenToScalarImageFilter + * \sa DescoteauxEigenToMeasureParameterEstimationFilter + * \sa EigenToMeasureImageFilter + * \sa MultiScaleHessianEnhancementImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ template class DescoteauxEigenToMeasureImageFilter - : public EigenToMeasureImageFilter< - TInputImage, - TOutputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureFunctor> + : public EigenToMeasureImageFilter { public: /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureImageFilter Self; - typedef EigenToMeasureImageFilter< - TInputImage, - TOutputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Functor typedef */ - typedef typename Superclass::FunctorType FunctorType; - typedef typename FunctorType::RealType RealType; - typedef typename FunctorType::ParameterType ParameterType; + typedef DescoteauxEigenToMeasureImageFilter Self; + typedef EigenToMeasureImageFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImagePointer OutputImagePointer; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -195,46 +88,58 @@ class DescoteauxEigenToMeasureImageFilter /** Runtime information support. */ itkTypeMacro(DescoteauxEigenToMeasureImageFilter, EigenToMeasureImageFilter); - /** setter/getter methods for setting type of object to enhance */ + /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ + typename Superclass::EigenValueOrderType + GetEigenValueOrder() const ITK_OVERRIDE + { + return Superclass::OrderByMagnitude; + } + + /** Setter/Getter methods for setting Direction */ + itkSetMacro(EnhanceType, RealType); + itkGetConstMacro(EnhanceType, RealType); void SetEnhanceBrightObjects() { - this->GetFunctor().SetEnhanceBrightObjects(); - this->Modified(); + SetEnhanceType(-1.0); } void SetEnhanceDarkObjects() { - this->GetFunctor().SetEnhanceDarkObjects(); - this->Modified(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE - { - return Superclass::OrderByMagnitude; + SetEnhanceType(1.0); } #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); // End concept checking #endif - protected: - DescoteauxEigenToMeasureImageFilter() {} + DescoteauxEigenToMeasureImageFilter(); virtual ~DescoteauxEigenToMeasureImageFilter() {} + inline OutputImagePixelType + ProcessPixel(const InputImagePixelType & pixel, RealType alpha, RealType beta, RealType c); + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); + + /* Member variables */ + RealType m_EnhanceType; }; // end class } /* end namespace itk */ +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToMeasureImageFilter.hxx" +#endif + #endif /* itkDescoteauxEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx similarity index 50% rename from Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx rename to Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index 59e8d464298..ff7239d8941 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -16,48 +16,42 @@ * *=========================================================================*/ -#ifndef itkEigenToMeasureImageFilter_hxx -#define itkEigenToMeasureImageFilter_hxx +#ifndef itkDescoteauxEigenToMeasureImageFilter_hxx +#define itkDescoteauxEigenToMeasureImageFilter_hxx -#include "itkEigenToMeasureImageFilter.h" -#include "itkProgressReporter.h" -#include "itkNumericTraits.h" +#include "itkDescoteauxEigenToMeasureImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" +#include "itkProgressReporter.h" namespace itk { - -template -EigenToMeasureImageFilter::EigenToMeasureImageFilter() -{ - this->SetNumberOfRequiredInputs(1); -} - -template -EigenToMeasureImageFilter::~EigenToMeasureImageFilter() +template +DescoteauxEigenToMeasureImageFilter:: + DescoteauxEigenToMeasureImageFilter() + : Superclass() + , m_EnhanceType(-1.0) {} -template +template void -EigenToMeasureImageFilter::BeforeThreadedGenerateData() - ITK_OVERRIDE -{ - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetParameters(this->GetParametersInput()->Get()); -} - -template -void -EigenToMeasureImageFilter::ThreadedGenerateData( +DescoteauxEigenToMeasureImageFilter::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) { - InputImageConstPointer inputPtr = this->GetInput(); + /* Get Inputs */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); + InputImageConstPointer inputPtr = this->GetInput(0); OutputImagePointer outputPtr = this->GetOutput(0); SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); typename InputImageType::PointType point; + /* Test parameters */ + if (parameters.GetSize() != 3) + { + itkExceptionMacro(<< "Parameters must have size 3. Given array of size " << parameters.GetSize()); + } + // Define the portion of the input to walk for this thread, using // the CallCopyOutputRegionToInputRegion method allows for the input // and output images to be different dimensions @@ -79,7 +73,7 @@ EigenToMeasureImageFilterTransformIndexToPhysicalPoint(inputIt.GetIndex(), point); if ((!maskPointer) || (maskPointer->IsInside(point))) { - outputIt.Set(m_Functor(inputIt.Get())); + outputIt.Set(ProcessPixel(inputIt.Get(), parameters[0], parameters[1], parameters[2])); } else { @@ -91,15 +85,57 @@ EigenToMeasureImageFilter +template +typename DescoteauxEigenToMeasureImageFilter::OutputImagePixelType +DescoteauxEigenToMeasureImageFilter::ProcessPixel( + const InputImagePixelType & pixel, + RealType alpha, + RealType beta, + RealType c) +{ + double sheetness = 0.0; + double a1 = static_cast(pixel[0]); + double a2 = static_cast(pixel[1]); + double a3 = static_cast(pixel[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Deal with l3 > 0 */ + if (m_EnhanceType * a3 < 0) + { + return static_cast(0.0); + } + + /* Avoid divisions by zero (or close to zero) */ + if (l3 < Math::eps) + { + return static_cast(0.0); + } + + /* Compute measures */ + const double Rsheet = l2 / l3; + const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; + const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); + + /* Multiply together to get sheetness */ + sheetness = 1.0; + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * alpha * alpha)); + sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * beta * beta))); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * c * c))); + + return static_cast(sheetness); +} + +template void -EigenToMeasureImageFilter::PrintSelf(std::ostream & os, - Indent indent) const +DescoteauxEigenToMeasureImageFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "m_Parameters: " << this->GetParametersInput() << std::endl; + os << indent << "Direction: " << GetEnhanceType() << std::endl; } -} /* end namespace itk */ +} // namespace itk -#endif /* itkEigenToMeasureImageFilter_hxx */ +#endif /* itkDescoteauxEigenToMeasureImageFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index b2f0f7d2705..9db48a766c8 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -19,128 +19,11 @@ #ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_h #define itkDescoteauxEigenToMeasureParameterEstimationFilter_h -#include "itkFixedArray.h" #include "itkMath.h" #include "itkEigenToMeasureParameterEstimationFilter.h" namespace itk { -namespace Functor -{ -/** \class DescoteauxEigenToMeasureParameterFunctor - * \brief Automatic parameter estimation as defined by Descoteaux et al. - * - * The default parameters are: - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.5 max\( Frobenius norm \) - * \f} - * - * Where the Frobenius norm for a real, symmetric matrix is given by - * the square root of the sum of squares of the eigenvalues. - * - * One can set FrobeniusNormWeight to control the weighting on the - * Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToMeasureParameterFunctor -{ -public: - /* Basic type definitions */ - itkStaticConstMacro(NumberOfParameters, unsigned int, 3); - typedef typename TInputPixel::ValueType PixelValueType; - typedef typename NumericTraits::RealType RealType; - typedef FixedArray ParameterType; - - DescoteauxEigenToMeasureParameterFunctor() - : m_FrobeniusNormWeight(0.5) - { - m_MaxFrobeniusNormArray.SetSize(0); - } - - void - Initialize(unsigned int numberOfCalls) - { - m_MaxFrobeniusNormArray.SetSize(numberOfCalls); - m_MaxFrobeniusNormArray.Fill(NumericTraits::ZeroValue()); - } - - void - ProcessPixel(const TInputPixel & inputPixel, unsigned int callNumber) - { - RealType norm = CalculateFrobeniusNorm(inputPixel); - if (norm > m_MaxFrobeniusNormArray[callNumber]) - { - m_MaxFrobeniusNormArray[callNumber] = norm; - } - } - - ParameterType - GetComputedParameters() - { - /* Alpha is 0.5 */ - m_Parameters[0] = 0.5; - - /* Beta is 0.5 */ - m_Parameters[1] = 0.5; - - /* C is m_FrobeniusNormWeight * max(frobenius norm) */ - m_Parameters[2] = 0; - for (unsigned int i = 0; i < m_MaxFrobeniusNormArray.GetSize(); ++i) - { - if (m_MaxFrobeniusNormArray[i] > m_Parameters[2]) - { - m_Parameters[2] = m_MaxFrobeniusNormArray[i]; - } - } - - /* Weight by the selection parmaeter */ - m_Parameters[2] = m_FrobeniusNormWeight * m_Parameters[2]; - - /* Finally, return the parameters we found */ - return m_Parameters; - } - - void - SetFrobeniusNormWeight(RealType weight) - { - m_FrobeniusNormWeight = weight; - } - - RealType - GetFrobeniusNormWeight() const - { - return m_FrobeniusNormWeight; - } - -private: - inline RealType - CalculateFrobeniusNorm(const TInputPixel & pixel) - { - /* Forbenius norm is given by the square root of the sum of squares - * of the eigenvalues for real, symmetric matricies - */ - RealType norm = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - norm += pixel[i] * pixel[i]; - } - return sqrt(norm); - } - - /* Private member variables */ - RealType m_FrobeniusNormWeight; - Array m_MaxFrobeniusNormArray; - ParameterType m_Parameters; -}; // end class -} // namespace Functor - /** \class DescoteauxEigenToMeasureParameterEstimationFilter * \brief Automatic parameter estimation as defined by Descoteaux et al. * @@ -154,38 +37,49 @@ class DescoteauxEigenToMeasureParameterFunctor * Where the Frobenius norm for a real, symmetric matrix is given by * the square root of the sum of squares of the eigenvalues. * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. + * The parameters are estimated over the whole volume unless a mask is given. + * If a mask is given, parameters are evaluated only where IsInside returns + * true. * - * \sa KrcahEigenToScalarImageFilter + * \sa DescoteauxEigenToMeasureImageFilter + * \sa EigenToMeasureParameterEstimationFilter + * \sa MultiScaleHessianEnhancementImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ template class DescoteauxEigenToMeasureParameterEstimationFilter - : public EigenToMeasureParameterEstimationFilter< - TInputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureParameterFunctor> + : public EigenToMeasureParameterEstimationFilter { public: /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; - typedef EigenToMeasureParameterEstimationFilter< - TInputImage, - TInputSpatialObject, - Functor::DescoteauxEigenToMeasureParameterFunctor> - Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Functor typedef */ - typedef typename Superclass::FunctorType FunctorType; - typedef typename FunctorType::RealType RealType; - typedef typename FunctorType::ParameterType ParameterType; + typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::PixelValueType PixelValueType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -193,21 +87,9 @@ class DescoteauxEigenToMeasureParameterEstimationFilter /** Runtime information support. */ itkTypeMacro(DescoteauxEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); - /** Define decorator types */ - typedef SimpleDataObjectDecorator InputParameterDecoratorType; - - /** setter/getter methods for setting type of object to enhance */ - void - SetFrobeniusNormWeight(RealType weight) - { - this->GetFunctor().SetFrobeniusNormWeight(weight); - this->Modified(); - } - RealType - GetFrobeniusNormWeight() const - { - return this->GetFunctor().GetFrobeniusNormWeight(); - } + /** Setter/Getter methods for setting FrobeniusNormWeight */ + itkSetMacro(FrobeniusNormWeight, RealType); + itkGetConstMacro(FrobeniusNormWeight, RealType); #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking @@ -215,20 +97,39 @@ class DescoteauxEigenToMeasureParameterEstimationFilter itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); // End concept checking #endif - protected: - DescoteauxEigenToMeasureParameterEstimationFilter() {} + DescoteauxEigenToMeasureParameterEstimationFilter(); + virtual ~DescoteauxEigenToMeasureParameterEstimationFilter() {} + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + + inline RealType + CalculateFrobeniusNorm(const InputImagePixelType & pixel) const; + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; private: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; - } + /* Member variables */ + RealType m_FrobeniusNormWeight; + Array m_MaxFrobeniusNorm; }; // end class } // namespace itk +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx" +#endif + #endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..5ef31795fd3 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,182 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx +#define itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx + +#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" + +namespace itk +{ + +template +DescoteauxEigenToMeasureParameterEstimationFilter:: + DescoteauxEigenToMeasureParameterEstimationFilter() + : Superclass() + , m_FrobeniusNormWeight(0.5) +{ + /* Set parameter size to 3 */ + ParameterArrayType parameters = this->GetParametersOutput()->Get(); + parameters.SetSize(3); + parameters[0] = 0.5; + parameters[1] = 0.5; + parameters[2] = 1; + this->GetParametersOutput()->Set(parameters); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +{ + ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); + + /* Resize threads */ + m_MaxFrobeniusNorm.SetSize(numberOfCalls); + m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +{ + ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); + + /* Determine default parameters */ + RealType alpha, beta, c; + alpha = 0.5f; + beta = 0.5f; + c = 0.0f; + + /* Accumulate over threads */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + + for (unsigned int i = 0; i < numberOfCalls; ++i) + { + if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) + { + maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; + } + } + + /* Scale c */ + if (maxFrobeniusNorm > 0) + { + c = m_FrobeniusNormWeight * maxFrobeniusNorm; + } + + /* Assign outputs parameters */ + ParameterArrayType parameters; + parameters.SetSize(3); + parameters[0] = alpha; + parameters[1] = beta; + parameters[2] = c; + this->GetParametersOutput()->Set(parameters); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::ThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread, + ThreadIdType threadId) +{ + /* If size is zero, return */ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Count starts zero */ + RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); + RealType thisFrobeniusNorm; + + /* Get input and mask pointer */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + OutputImageType * outputPtr = this->GetOutput(0); + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + outputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + /* Compute max norm */ + thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); + if (thisFrobeniusNorm > maxFrobeniusNorm) + { + maxFrobeniusNorm = thisFrobeniusNorm; + } + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + /* Store this thread */ + m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; +} + +template +typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType +DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( + const InputImagePixelType & pixel) const +{ + /* Forbenius norm is given by the square root of the sum of squares + * of the eigenvalues for real, symmetric matricies + */ + RealType norm = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + norm += pixel[i] * pixel[i]; + } + return sqrt(norm); +} + +template +void +DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; +} + +} // namespace itk + +#endif /* itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h deleted file mode 100644 index de7f7217caf..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,259 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarFunctorImageFilter_h -#define itkDescoteauxEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class DescoteauxEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ - * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ - * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) - * \f} - * - * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. - * - * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter - * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - using RealType = typename NumericTraits::RealType; - - DescoteauxEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Deal with l3 > 0 */ - if (m_Direction * a3 < 0) - { - return static_cast(0.0); - } - - /* Avoid divisions by zero (or close to zero) */ - if (l3 < Math::eps) - { - return static_cast(0.0); - } - - /* Compute measures */ - const double Rsheet = l2 / l3; - const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); - - /* Multiply together to get sheetness */ - sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetC(const RealType c) - { - this->m_C = c; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetC() const - { - return this->m_C; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_C; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class DescoteauxEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Descoteaux et al. The parameters of the filter should be set using - * DescoteauxEigentoScalarParameterEstimationImageFilter. - * - * See functor DescoteauxEigenToScalarFunctor for mathematics. - * - * \sa DescoteauxEigenToScalarFunctor - * \sa DescoteauxEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor> -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); - - /** Standard Self type alias */ - using Self = DescoteauxEigenToScalarFunctorImageFilter; - using Superclass = UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor>; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Useful type alias for numerics */ - typedef - typename Functor::DescoteauxEigenToScalarFunctor - DescoteauxFunctorType; - typedef typename DescoteauxFunctorType::RealType RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - using InputParameterDecoratorType = SimpleDataObjectDecorator; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(C, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() override - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetC(this->GetCInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - DescoteauxEigenToScalarFunctorImageFilter() {} - virtual ~DescoteauxEigenToScalarFunctorImageFilter() {} - -private: - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "C: " << GetC() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkDescoteauxEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h deleted file mode 100644 index c8464415978..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.h +++ /dev/null @@ -1,199 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarImageFilter_h -#define itkDescoteauxEigenToScalarImageFilter_h - -#include "itkEigenToScalarImageFilter.h" -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" - -namespace itk -{ -/** \class DescoteauxEigenToScalarImageFilter - * \brief Compute the Descoteaux sheetness measure from the eigenvalues - * - * This is a convenience class implementing the EigenToScalarImageFilter - * abstract class. This class computes the Descoteaux sheetness measure for - * cortical bone. Internally, DescoteauxEigenToScalarParameterEstimationImageFilter - * and DescoteauxEigenToScalarFunctorImageFilter are used for automatic parameter - * estimation and implementation of the functor. - * - * Before passing an input to MultiScaleHessianEnhancementImageFilter, - * the DescoteauxEigenToScalarPreprocessingImageToImageFilter should be used. - * - * \sa MultiScaleHessianEnhancementImageFilter - * \sa EigenToScalarImageFilter - * \sa DescoteauxEigenToScalarParameterEstimationImageFilter - * \sa DescoteauxEigenToScalarFunctorImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template > -class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarImageFilter - : public EigenToScalarImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarImageFilter); - - /** Standard Self type alias */ - using Self = DescoteauxEigenToScalarImageFilter; - using Superclass = EigenToScalarImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - - /** Useful template type alias. */ - using InputImagePointer = typename TInputImage::Pointer; - using InputImageConstPointer = typename TInputImage::ConstPointer; - using MaskImagePointer = typename TMaskImage::Pointer; - using MaskImageConstPointer = typename TMaskImage::ConstPointer; - using MaskPixelType = typename TMaskImage::PixelType; - - /** Procesing filters */ - using ParameterEstimationFilterType = DescoteauxEigenToScalarParameterEstimationImageFilter; - using UnaryFunctorFilterType = DescoteauxEigenToScalarFunctorImageFilter; - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const override - { - return Superclass::OrderByMagnitude; - } - - /** Methods to set/get the mask image */ - void - SetMaskImage(const TMaskImage * mask) - { - this->m_ParameterEstimationFilter->SetMaskImage(mask); - this->Modified(); - } - virtual const TMaskImage * - GetMaskImage() const - { - return this->m_ParameterEstimationFilter->GetMaskImage(); - } - - /** Methods to set/get the background value */ - virtual void - SetBackgroundValue(const MaskPixelType back) - { - this->m_ParameterEstimationFilter->SetBackgroundValue(back); - this->Modified(); - } - virtual MaskPixelType - GetBackgroundValue() const - { - return this->m_ParameterEstimationFilter->GetBackgroundValue(); - } - - /** Methods to set/get the FrobeniusNormWeight */ - virtual void - SetFrobeniusNormWeight(const typename ParameterEstimationFilterType::RealType weight) - { - this->m_ParameterEstimationFilter->SetFrobeniusNormWeight(weight); - this->Modified(); - } - typename ParameterEstimationFilterType::RealType - GetFrobeniusNormWeight() const - { - return this->m_ParameterEstimationFilter->GetFrobeniusNormWeight(); - } - - /** Methods to get the computed parameters */ - typename UnaryFunctorFilterType::RealType - GetAlpha() const - { - return m_UnaryFunctorFilter->GetAlpha(); - } - typename UnaryFunctorFilterType::RealType - GetBeta() const - { - return m_UnaryFunctorFilter->GetBeta(); - } - typename UnaryFunctorFilterType::RealType - GetC() const - { - return m_UnaryFunctorFilter->GetC(); - } - - /** Methods to set/get the enhancment method */ - void - SetEnhanceBrightObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); - this->Modified(); - } - void - SetEnhanceDarkObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); - this->Modified(); - } - typename UnaryFunctorFilterType::RealType - GetEnhanceType() const - { - return this->m_UnaryFunctorFilter->GetEnhanceType(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - DescoteauxEigenToScalarImageFilter(); - virtual ~DescoteauxEigenToScalarImageFilter() {} - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() override; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) override; - - /** Single threaded since we are connecting data */ - void - GenerateData() override; - - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - /* Filter pipeline */ - typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; - typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkDescoteauxEigenToScalarImageFilter.hxx" -#endif - -#endif // itkDescoteauxEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx deleted file mode 100644 index b7dd3e2ae51..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarImageFilter.hxx +++ /dev/null @@ -1,101 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkDescoteauxEigenToScalarImageFilter_hxx -#define itkDescoteauxEigenToScalarImageFilter_hxx - -#include "itkDescoteauxEigenToScalarImageFilter.h" -#include "itkProgressAccumulator.h" - -namespace itk -{ -template -DescoteauxEigenToScalarImageFilter::DescoteauxEigenToScalarImageFilter() -{ - /* Instantiate filters. */ - m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); - m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); - - /* We require an input image */ - this->SetNumberOfRequiredInputs(1); -} - -template -void -DescoteauxEigenToScalarImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -DescoteauxEigenToScalarImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -DescoteauxEigenToScalarImageFilter::GenerateData() -{ - /* Get inputs */ - InputImageConstPointer input = this->GetInput(); - - /* Connect filters */ - m_ParameterEstimationFilter->SetInput(input); - m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); - m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); - m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); - m_UnaryFunctorFilter->SetCInput(m_ParameterEstimationFilter->GetCOutput()); - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); - progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); - - /* Graft output and we're done! */ - m_UnaryFunctorFilter->Update(); - this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); -} - -template -void -DescoteauxEigenToScalarImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; - os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; -} - -} // namespace itk - -#endif // itkDescoteauxEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h deleted file mode 100644 index 995dc184b9d..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.h +++ /dev/null @@ -1,190 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_h -#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkNumericTraits.h" -#include "itkSimpleDataObjectDecorator.h" -#include "itkArray.h" - -namespace itk -{ -/** \class DescoteauxEigenToScalarParameterEstimationImageFilter - * \brief Automatic parameter estimation for the Krcah method - * - * The default parameters are: - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.5 max\( Frobenius norm \) - * \f} - * - * Where the Frobenius norm for a real, symmetric matrix is given by - * the square root of the sum of squares of the eigenvalues. - * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT DescoteauxEigenToScalarParameterEstimationImageFilter - : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarParameterEstimationImageFilter); - - /** Standard Self type alias */ - using Self = DescoteauxEigenToScalarParameterEstimationImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /** Image related type alias. */ - using InputImagePointer = typename TInputImage::Pointer; - using InputImageConstPointer = typename TInputImage::ConstPointer; - using InputRegionType = typename TInputImage::RegionType; - using InputSizeType = typename TInputImage::SizeType; - using InputIndexType = typename TInputImage::IndexType; - using InputPixelType = typename TInputImage::PixelType; - using InputPixelValueType = typename InputPixelType::ValueType; - - /** Output region definitions */ - using OutputRegionType = InputRegionType; - - /** Mask related type alias. */ - using MaskImagePointer = typename TMaskImage::Pointer; - using MaskImageConstPointer = typename TMaskImage::ConstPointer; - using MaskPixelType = typename TMaskImage::PixelType; - using MaskRegionType = typename TMaskImage::RegionType; - - /** Parameters */ - using RealType = typename NumericTraits::RealType; - using RealTypeDecoratedType = SimpleDataObjectDecorator; - - /** Methods to set/get the mask image */ - itkSetInputMacro(MaskImage, TMaskImage); - itkGetInputMacro(MaskImage, TMaskImage); - - /** Setter/getter for background pixel value */ - itkSetMacro(BackgroundValue, MaskPixelType); - itkGetConstMacro(BackgroundValue, MaskPixelType); - - /** Method setter/getter for Frobenius Norm Weight */ - itkSetMacro(FrobeniusNormWeight, RealType); - itkGetConstMacro(FrobeniusNormWeight, RealType); - - /** Decorators for parameters so they can be passed as a process object */ - RealTypeDecoratedType * - GetAlphaOutput(); - const RealTypeDecoratedType * - GetAlphaOutput() const; - RealTypeDecoratedType * - GetBetaOutput(); - const RealTypeDecoratedType * - GetBetaOutput() const; - RealTypeDecoratedType * - GetCOutput(); - const RealTypeDecoratedType * - GetCOutput() const; - - /** Standard getters for the output parameters */ - RealType - GetAlpha() const - { - return this->GetAlphaOutput()->Get(); - } - RealType - GetBeta() const - { - return this->GetBetaOutput()->Get(); - } - RealType - GetC() const - { - return this->GetCOutput()->Get(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - DescoteauxEigenToScalarParameterEstimationImageFilter(); - virtual ~DescoteauxEigenToScalarParameterEstimationImageFilter() {} - - /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ - void - AllocateOutputs() override; - - /** Initialize some accumulators before the threads run. */ - void - BeforeThreadedGenerateData() override; - - /** Do final mean and variance computation from data accumulated in threads. */ - void - AfterThreadedGenerateData() override; - - /** Multi-thread version GenerateData. */ - void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) override; - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() override; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) override; - - /** Compute Frobenius norm from a fixed array of eigenvalues */ - inline RealType - CalculateFrobeniusNorm(InputPixelType pixel); - - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - /* Parameters */ - RealType m_FrobeniusNormWeight; - MaskPixelType m_BackgroundValue; - - /* Arrays for threads */ - Array m_MaxFrobeniusNorm; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx" -#endif - -#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index d835345a393..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,266 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx -#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -DescoteauxEigenToScalarParameterEstimationImageFilter:: - DescoteauxEigenToScalarParameterEstimationImageFilter() - : m_FrobeniusNormWeight(0.5f) - , m_BackgroundValue(NumericTraits::Zero) - , m_MaxFrobeniusNorm(1) -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Resize threads */ - m_MaxFrobeniusNorm.SetSize(numberOfThreads); - m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Determine default parameters */ - RealType alpha, beta, c; - alpha = 0.5f; - beta = 0.5f; - c = m_FrobeniusNormWeight; - - /* Accumulate over threads */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) - { - maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; - } - } - - /* Scale c */ - if (maxFrobeniusNorm > 0) - { - c = c * maxFrobeniusNorm; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetCOutput()->Set(c); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Count starts zero */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - RealType thisFrobeniusNorm; - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - /* Compute max norm */ - thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); - if (thisFrobeniusNorm > maxFrobeniusNorm) - { - maxFrobeniusNorm = thisFrobeniusNorm; - } - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealType -DescoteauxEigenToScalarParameterEstimationImageFilter::CalculateFrobeniusNorm( - InputPixelType pixel) -{ - /* Forbenius norm is given by the square root of the sum of squares - * of the eigenvalues for real, symmetric matricies - */ - RealType norm = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - norm += pixel[i] * pixel[i]; - } - return sqrt(norm); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << this->GetAlpha() << std::endl; - os << indent << "Beta: " << this->GetBeta() << std::endl; - os << indent << "C: " << this->GetC() << std::endl; - os << indent << "BackgroundValue: " << GetBackgroundValue() << std::endl; - os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; -} - -} // namespace itk - -#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h index 0ac86321f27..f6508d7cd6c 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -28,24 +28,17 @@ namespace itk /** \class EigenToMeasureImageFilter * \brief Abstract class for computing a measure from local structure. * - * TODO - * - * This is an abstract class that estimates parameters for local-structure enhancement - * from eigen-images. Other classes should inherit from this class so they can be used - * in the MultiScaleHessianEnhancementImageFilter framework. - * - * To estimate the parameters for local-structure enhancement, every pixel in the input - * image must be seen. To implement this functionality in a memory efficinet way, this - * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by - * restricting the output image region. + * This is an abstract class that computes a local-structure measure from an eigen-image. + * Any algorithm implementing a local-structure measure should inherit from this class + * so they can be used in the MultiScaleHessianEnhancementImageFilter framework. * * \sa MultiScaleHessianEnhancementImageFilter - * \sa UnaryFunctorImageFilter + * \sa EigenToMeasureParameterEstimationFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter { public: @@ -59,11 +52,12 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< itkTypeMacro(EigenToMeasureImageFilter, ImageToImageFilter); /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename InputImagePixelType::ValueType PixelValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ @@ -76,48 +70,14 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< typedef TInputSpatialObject SpatialObjectType; typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; - /** Functor typedefs. */ - typedef TFunction FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - typedef typename ParameterType::ValueType ParameterValueType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; - itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); - - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ - FunctorType & - GetFunctor() - { - return m_Functor; - } - const FunctorType & - GetFunctor() const - { - return m_Functor; - } - - /** Set the functor object. This replaces the current Functor with a - * copy of the specified Functor. This allows the user to specify a - * functor that has ivars set differently than the default functor. - * This method requires the following to be defined: - * Initialize() - * ProcessPixel() - * GetComputedParameters() - */ - void - SetFunctor(const FunctorType & functor) - { - if (m_Functor != functor) - { - m_Functor = functor; - this->Modified(); - } - } + /** Parameter typedefs. */ + typedef typename NumericTraits::RealType RealType; + typedef RealType ParameterType; + typedef Array ParameterArrayType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; /** Process object */ - itkSetGetDecoratedInputMacro(Parameters, ParameterType); + itkSetGetDecoratedInputMacro(Parameters, ParameterArrayType); /** Methods to set/get the mask image */ itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); @@ -139,29 +99,12 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< GetEigenValueOrder() const = 0; protected: - EigenToMeasureImageFilter(); - virtual ~EigenToMeasureImageFilter() ITK_OVERRIDE; - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() ITK_OVERRIDE; - void - ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId); - - void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + EigenToMeasureImageFilter() {}; + virtual ~EigenToMeasureImageFilter() {} private: ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); - - /* Private data members. */ - ParameterType m_Parameters; - FunctorType m_Functor; }; // end class } // namespace itk -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkEigenToMeasureImageFilter.hxx" -#endif - #endif /* itkEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index 8a08a093ba4..019a139f5a2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -26,24 +26,28 @@ namespace itk { /** \class EigenToMeasureParameterEstimationFilter - * \brief Abstract class for estimating local-structure parameters from eigenvalues. + * \brief Abstract class for estimating local-structure parameters from an eigen-image. * * This is an abstract class that estimates parameters for local-structure enhancement - * from eigen-images. Other classes should inherit from this class so they can be used - * in the MultiScaleHessianEnhancementImageFilter framework. + * from eigen-images. Any algorithm implementing a local-structure measure should inherit from this class + * so they can be used in the MultiScaleHessianEnhancementImageFilter framework. * - * To estimate the parameters for local-structure enhancement, every pixel in the input + * To estimate parameters for local-structure enhancement, every pixel in the input * image must be seen. To implement this functionality in a memory efficinet way, this * class inherits from itk::StreamingImageFilter. This algorithm can be spead up by * restricting the output image region. * - * \sa MultiScaleHessianEnhancementImageFilter + * The method GetParametersOutput can be used to insert this filter in a pipeline before + * EigenToMeasureImageFilter. + * * \sa StreamingImageFilter + * \sa MultiScaleHessianEnhancementImageFilter + * \sa EigenToMeasureImageFilter * * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter : public StreamingImageFilter { @@ -57,15 +61,13 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter /** Run-time type information (and related methods). */ itkTypeMacro(EigenToMeasureParameterEstimationFilter, StreamingImageFilter); - /** Method for creation through the object factory. */ - itkNewMacro(Self); - /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename InputImagePixelType::ValueType PixelValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ @@ -76,45 +78,11 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter typedef TInputSpatialObject SpatialObjectType; typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; - /** Functor typedefs. */ - typedef TFunction FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - typedef typename ParameterType::ValueType ParameterValueType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; - itkStaticConstMacro(NumberOfParameters, unsigned int, ParameterType::Length); - - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ - FunctorType & - GetFunctor() - { - return m_Functor; - } - const FunctorType & - GetFunctor() const - { - return m_Functor; - } - - /** Set the functor object. This replaces the current Functor with a - * copy of the specified Functor. This allows the user to specify a - * functor that has ivars set differently than the default functor. - * This method requires the following to be defined: - * Initialize() - * ProcessPixel() - * GetComputedParameters() - */ - void - SetFunctor(const FunctorType & functor) - { - if (m_Functor != functor) - { - m_Functor = functor; - this->Modified(); - } - } + /** Parameter typedefs. */ + typedef typename NumericTraits::RealType RealType; + typedef RealType ParameterType; + typedef Array ParameterArrayType; + typedef SimpleDataObjectDecorator ParameterDecoratedType; /** Decorators for parameters so they can be passed as a process object */ ParameterDecoratedType * @@ -123,7 +91,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter GetParametersOutput() const; /** Standard getters for the parameters */ - ParameterType + ParameterArrayType GetParameters() const { return this->GetParametersOutput()->Get(); @@ -145,11 +113,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter * library will call this routine for each thread, which will delegate the * control to ThreadedGenerateData(). */ static ITK_THREAD_RETURN_TYPE - ThreaderCallback(void * arg) ITK_OVERRIDE; - - /** Repeatedly call the functor for each pixel we index. */ - void - ThreadedGenerateData(const InputImageRegionType & region, unsigned int streamNumber); + ThreaderCallback(void * arg); struct ThreadStruct { @@ -158,17 +122,13 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter protected: EigenToMeasureParameterEstimationFilter(); - virtual ~EigenToMeasureParameterEstimationFilter() ITK_OVERRIDE; + virtual ~EigenToMeasureParameterEstimationFilter() {} void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; private: ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); - - /* Private data members. */ - FunctorType m_Functor; - unsigned int m_CurrentSplit; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx index c1b4177f207..317219ecbef 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -24,15 +24,18 @@ #include "itkImageAlgorithm.h" #include "itkImageRegionSplitterSlowDimension.h" #include "itkImageRegionConstIteratorWithIndex.h" -#include "itkImageRegionSplitterBase.h" +#include "itkImageRegionSplitterSlowDimension.h" namespace itk { -template -EigenToMeasureParameterEstimationFilter:: - EigenToMeasureParameterEstimationFilter() - : m_CurrentSplit(0) + +template +EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() { + /* Set stream parameters */ + this->SetNumberOfStreamDivisions(10); + this->SetRegionSplitter(ImageRegionSplitterSlowDimension::New()); + /* We require an input image */ this->SetNumberOfRequiredInputs(1); @@ -41,56 +44,14 @@ EigenToMeasureParameterEstimationFilterSet(initialParameters); - this->ProcessObject::SetNthOutput(1, output.GetPointer()); -} - -template -EigenToMeasureParameterEstimationFilter:: - ~EigenToMeasureParameterEstimationFilter() -{} - -template -void -EigenToMeasureParameterEstimationFilter::ThreadedGenerateData( - const InputImageRegionType & region, - unsigned int streamNumber) -{ - /* If size is zero, return */ - if (region.GetSize(0) == 0) - { - return; - } - - /* Get input pointers */ - InputImageConstPointer inputPointer = this->GetInput(); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); - typename InputImageType::PointType point; - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) - { - m_Functor.ProcessPixel(inputIt.Get(), streamNumber); - } - ++inputIt; - } + this->SetNthOutput(1, output.GetPointer()); } -template +template void -EigenToMeasureParameterEstimationFilter::UpdateOutputData( +EigenToMeasureParameterEstimationFilter::UpdateOutputData( DataObject * itkNotUsed(output)) { /** Prevent chasing our tail */ @@ -145,8 +106,10 @@ EigenToMeasureParameterEstimationFilterGetNumberOfStreamDivisions() * this->GetNumberOfThreads()); + // Call a method that can be overridden by a subclass to perform + // some calculations prior to splitting the main computations into + // separate threads + this->BeforeThreadedGenerateData(); /** * Loop over the number of pieces, execute the upstream pipeline on each @@ -154,45 +117,47 @@ EigenToMeasureParameterEstimationFilterGetAbortGenerateData(); piece++) { - /* Set the current peice */ - m_CurrentSplit = piece; - /* Determine the split region and calculate the input */ - InputImageRegionType streamRegion = outputRegion; + InputImageRegionType streamRegion; + this->CallCopyOutputRegionToInputRegion(streamRegion, outputRegion); + this->GetRegionSplitter()->GetSplit(piece, numDivisions, streamRegion); inputPtr->SetRequestedRegion(streamRegion); inputPtr->PropagateRequestedRegion(); inputPtr->UpdateOutputData(); - /* Setup a multithreadign process */ - ThreadStruct str; - str.Filter = this; + // /* Setup a multithreadign process */ + // ThreadStruct str; + // str.Filter = this; - // Get the output pointer - const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); - const unsigned int validThreads = splitter->GetNumberOfSplits(streamRegion, this->GetNumberOfThreads()); + // // Get the output pointer + // const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); + // const unsigned int validThreads = splitter->GetNumberOfSplits( streamRegion, this->GetNumberOfThreads() ); - this->GetMultiThreader()->SetNumberOfThreads(validThreads); - this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); + // this->GetMultiThreader()->SetNumberOfThreads( validThreads ); + // this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); - // multithread the execution - this->GetMultiThreader()->SingleMethodExecute(); + // // multithread the execution + // this->GetMultiThreader()->SingleMethodExecute(); + + this->ThreadedGenerateData(streamRegion, piece); // copy the result to the proper place in the output. the input // requested region determined by the RegionSplitter (as opposed // to what the pipeline might have enlarged it to) is used to // copy the regions from the input to output - if (inputPtr != outputPtr) - { - ImageAlgorithm::Copy(inputPtr, outputPtr, streamRegion, streamRegion); - } + // if (inputPtr != outputPtr) + // { + // ImageAlgorithm::Copy( inputPtr, outputPtr, streamRegion, streamRegion ); + // } /* Update progress and stream another chunk */ this->UpdateProgress(static_cast(piece) / static_cast(numDivisions)); } - /* Compute and set the parameters */ - this->GetParametersOutput()->Set(m_Functor.GetComputedParameters()); + // Call a method that can be overridden by a subclass to perform + // some calculations after all the threads have completed + this->AfterThreadedGenerateData(); /** * If we ended due to aborting, push the progress up to 1.0 @@ -209,9 +174,9 @@ EigenToMeasureParameterEstimationFilterGetNumberOfOutputs(); ++idx) { - if (this->GetOutput(idx)) + if (this->ProcessObject::GetOutput(idx)) { - this->GetOutput(idx)->DataHasBeenGenerated(); + this->ProcessObject::GetOutput(idx)->DataHasBeenGenerated(); } } @@ -222,57 +187,60 @@ EigenToMeasureParameterEstimationFilterm_Updating = false; } -template -ITK_THREAD_RETURN_TYPE -EigenToMeasureParameterEstimationFilter::ThreaderCallback(void * arg) -{ - ThreadStruct * str; - ThreadIdType total, threadId, threadCount; - - threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID; - threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads; - - str = (ThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData); - - // execute the actual method with appropriate output region - // first find out how many pieces extent can be split into. - typename OutputImageType::RegionType splitRegion; - total = str->Filter->SplitRequestedRegion(threadId, threadCount, splitRegion); - unsigned int streamNumber = str->Filter->m_CurrentSplit; - - if (threadId < total) - { - str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions() * threadId + streamNumber); - } - // else - // { - // otherwise don't use this thread. Sometimes the threads dont - // break up very well and it is just as efficient to leave a - // few threads idle. - // } - - return ITK_THREAD_RETURN_VALUE; -} - -template -typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() +// Threaded splitter +// template< typename TInputImage, typename TInputSpatialObject > +// ITK_THREAD_RETURN_TYPE +// EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject > +// ::ThreaderCallback(void *arg) +// { +// ThreadStruct *str; +// ThreadIdType total, threadId, threadCount; + +// threadId = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->ThreadID; +// threadCount = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->NumberOfThreads; + +// str = (ThreadStruct *)( ( (MultiThreader::ThreadInfoStruct *)( arg ) )->UserData ); + +// // execute the actual method with appropriate output region +// // first find out how many pieces extent can be split into. +// typename OutputImageType::RegionType splitRegion; +// total = str->Filter->SplitRequestedRegion(threadId, threadCount, +// splitRegion); +// unsigned int streamNumber = str->Filter->m_CurrentSplit; + +// if ( threadId < total ) +// { +// str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions()*threadId + +// streamNumber); +// } +// // else +// // { +// // otherwise don't use this thread. Sometimes the threads dont +// // break up very well and it is just as efficient to leave a +// // few threads idle. +// // } + +// return ITK_THREAD_RETURN_VALUE; +// } + +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() { return static_cast(this->ProcessObject::GetOutput(1)); } -template -const typename EigenToMeasureParameterEstimationFilter:: - ParameterDecoratedType * - EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +template +const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() const { return static_cast(this->ProcessObject::GetOutput(1)); } -template +template void -EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, - Indent indent) const +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h deleted file mode 100644 index 8b9e70bc792..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToScalarImageFilter.h +++ /dev/null @@ -1,88 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkEigenToScalarImageFilter_h -#define itkEigenToScalarImageFilter_h - -#include "itkImageToImageFilter.h" - -namespace itk -{ -/** \class EigenToScalarImageFilter - * \brief Abstract class for converting eigenvalue image to scalar image. - * - * This is an abstract class that converts an eigenvalue image to a scalar image based using a mathematical function. - * Other classes should inherit from this class so they can be used in the BoneEnhancement framework. This abstract - * class guarantees that the variable EigenValueOrder has a valid type and enforces some concept checking - * on the class template parameters: TInputImage and TOutputImage . - * - * \sa MultiScaleHessianEnhancementImageFilter. - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT EigenToScalarImageFilter : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenToScalarImageFilter); - - /** Standard Self type alias */ - using Self = EigenToScalarImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Run-time type information (and related methods). */ - itkTypeMacro(EigenToScalarImageFilter, ImageToImageFilter); - - /** Template the EigenValueOrderType. Methods that inherit from this class can override this function - * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from - * itkSymmetricEigenAnalysisImageFilter.h or itkSymmetricEigenAnalysis.h. That turns out to be non-trivial - * because the enumeration is hidden within the templated class. Therefore, you would need the hessian type - * and eigenvalue type to do such an operation. We do not necessarily have the hessian type information. - */ - typedef enum - { - OrderByValue = 1, - OrderByMagnitude, - DoNotOrder - } EigenValueOrderType; - virtual EigenValueOrderType - GetEigenValueOrder() const = 0; - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, - (Concept::SameDimension)); - // End concept checking -#endif -protected: - EigenToScalarImageFilter() {} - virtual ~EigenToScalarImageFilter() {} - - void - PrintSelf(std::ostream & os, Indent indent) const override - { - Superclass::PrintSelf(os, indent); - os << indent << "EigenValueOrder: " << this->GetEigenValueOrder() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index df685bdae4e..7decae47804 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -193,15 +193,16 @@ HessianGaussianImageFilter::GenerateData(void) // Setup Image Adaptor m_ImageAdaptor->SetImage(this->GetOutput()); - m_ImageAdaptor->SetLargestPossibleRegion(inputImage->GetLargestPossibleRegion()); + m_ImageAdaptor->SetLargestPossibleRegion(this->GetOutput()->GetLargestPossibleRegion()); - m_ImageAdaptor->SetBufferedRegion(inputImage->GetBufferedRegion()); + m_ImageAdaptor->SetBufferedRegion(this->GetOutput()->GetRequestedRegion()); - m_ImageAdaptor->SetRequestedRegion(inputImage->GetRequestedRegion()); + m_ImageAdaptor->SetRequestedRegion(this->GetOutput()->GetRequestedRegion()); m_ImageAdaptor->Allocate(); m_DerivativeFilter->SetInput(inputImage); + m_DerivativeFilter->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion()); unsigned int element = 0; int order[ImageDimension]; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h deleted file mode 100644 index 6caebe21057..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,250 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarFunctorImageFilter_h -#define itkKrcahEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class KrcahEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Krcah et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{tube} &=& \frac{\lambda_1|}{|\lambda_2| \cdot \lambda_3|} \\ - * R_{noise} &=& \lambda_1| + |\lambda_2| + \lambda_3| \\ - * s &=& sign(\lambda_3) \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \exp\left(- \frac{R_{tube}^2}{\beta^2} - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) - * \f} - * - * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. - * - * \sa KrcahEigentoScalarParameterEstimationImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - using RealType = typename NumericTraits::RealType; - - KrcahEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Avoid divisions by zero (or close to zero) */ - if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) - { - return static_cast(sheetness); - } - - /** - * Compute sheet, noise, and tube like measures. Note that the average trace of the - * Hessian matrix is implicitly included in \f$ \gamma \f$ here. - */ - const double Rsheet = l2 / l3; - const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma - const double Rtube = l1 / (l2 * l3); - - /* Multiply together to get sheetness */ - sheetness = (m_Direction * a3 / l3); - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); - sheetness *= vcl_exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetGamma(const RealType gamma) - { - this->m_Gamma = gamma; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetGamma() const - { - return this->m_Gamma; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_Gamma; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class KrcahEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. - * - * See functor for mathematics. - * - * \sa KrcahEigenToScalarFunctor - * \sa KrcahEigenToScalarImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor> -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarFunctorImageFilter; - using Superclass = UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor>; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Useful type alias for numerics */ - using KrcahFunctorType = - typename Functor::KrcahEigenToScalarFunctor; - using RealType = typename KrcahFunctorType::RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - using InputParameterDecoratorType = SimpleDataObjectDecorator; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(Gamma, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() override - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetGamma(this->GetGammaInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - KrcahEigenToScalarFunctorImageFilter() {} - virtual ~KrcahEigenToScalarFunctorImageFilter() {} - -private: - void - PrintSelf(std::ostream & os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "Gamma: " << GetGamma() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkKrcahEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h deleted file mode 100644 index b49c83d6855..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.h +++ /dev/null @@ -1,212 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarImageFilter_h -#define itkKrcahEigenToScalarImageFilter_h - -#include "itkEigenToScalarImageFilter.h" -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkKrcahEigenToScalarFunctorImageFilter.h" - -namespace itk -{ -/** \class KrcahEigenToScalarImageFilter - * \brief Compute the Krcah sheetness measure from the eigenvalues - * - * This is a convenience class implementing the EigenToScalarImageFilter - * abstract class. This class computes the Krcah sheetness measure for - * cortical bone. Internally, KrcahEigenToScalarParameterEstimationImageFilter - * and KrcahEigenToScalarFunctorImageFilter are used for automatic parameter - * estimation and implementation of the functor. - * - * Before passing an input to MultiScaleHessianEnhancementImageFilter, - * the KrcahEigenToScalarPreprocessingImageToImageFilter should be used. - * - * \sa MultiScaleHessianEnhancementImageFilter - * \sa EigenToScalarImageFilter - * \sa KrcahEigenToScalarParameterEstimationImageFilter - * \sa KrcahEigenToScalarFunctorImageFilter - * \sa KrcahEigenToScalarPreprocessingImageToImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template > -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarImageFilter : public EigenToScalarImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarImageFilter; - using Superclass = EigenToScalarImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); - - /** Useful template type alias. */ - using InputImagePointer = typename TInputImage::Pointer; - using InputImageConstPointer = typename TInputImage::ConstPointer; - using MaskImagePointer = typename TMaskImage::Pointer; - using MaskImageConstPointer = typename TMaskImage::ConstPointer; - using MaskPixelType = typename TMaskImage::PixelType; - - /** Procesing filters */ - using ParameterEstimationFilterType = KrcahEigenToScalarParameterEstimationImageFilter; - using KrcahImplementationType = typename ParameterEstimationFilterType::KrcahImplementationType; - using UnaryFunctorFilterType = KrcahEigenToScalarFunctorImageFilter; - - /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ - typename Superclass::EigenValueOrderType - GetEigenValueOrder() const override - { - return Superclass::OrderByMagnitude; - } - - /** Methods to set/get the mask image */ - void - SetMaskImage(const TMaskImage * mask) - { - this->m_ParameterEstimationFilter->SetMaskImage(mask); - this->Modified(); - } - virtual const TMaskImage * - GetMaskImage() const - { - return this->m_ParameterEstimationFilter->GetMaskImage(); - } - - /** Methods to set/get the background value */ - virtual void - SetBackgroundValue(const MaskPixelType back) - { - this->m_ParameterEstimationFilter->SetBackgroundValue(back); - this->Modified(); - } - virtual MaskPixelType - GetBackgroundValue() const - { - return this->m_ParameterEstimationFilter->GetBackgroundValue(); - } - - /** Methods to set/get the parameter set type */ - virtual void - SetParameterSet(const KrcahImplementationType back) - { - this->m_ParameterEstimationFilter->SetParameterSet(back); - this->Modified(); - } - virtual KrcahImplementationType - GetParameterSet() const - { - return this->m_ParameterEstimationFilter->GetParameterSet(); - } - virtual void - SetParameterSetToImplementation() - { - this->m_ParameterEstimationFilter->SetParameterSetToImplementation(); - this->Modified(); - } - virtual void - SetParameterSetToJournalArticle() - { - this->m_ParameterEstimationFilter->SetParameterSetToJournalArticle(); - this->Modified(); - } - - /** Methods to get the computed parameters */ - typename UnaryFunctorFilterType::RealType - GetAlpha() const - { - return m_UnaryFunctorFilter->GetAlpha(); - } - typename UnaryFunctorFilterType::RealType - GetBeta() const - { - return m_UnaryFunctorFilter->GetBeta(); - } - typename UnaryFunctorFilterType::RealType - GetGamma() const - { - return m_UnaryFunctorFilter->GetGamma(); - } - - /** Methods to set/get the enhancment method */ - void - SetEnhanceBrightObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceBrightObjects(); - this->Modified(); - } - void - SetEnhanceDarkObjects() - { - this->m_UnaryFunctorFilter->SetEnhanceDarkObjects(); - this->Modified(); - } - typename UnaryFunctorFilterType::RealType - GetEnhanceType() const - { - return this->m_UnaryFunctorFilter->GetEnhanceType(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(OutputHaveDimension3Check, (Concept::SameDimension)); - itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarImageFilter(); - virtual ~KrcahEigenToScalarImageFilter() {} - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() override; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) override; - - /** Single threaded since we are connecting data */ - void - GenerateData() override; - - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - /* Filter pipeline */ - typename ParameterEstimationFilterType::Pointer m_ParameterEstimationFilter; - typename UnaryFunctorFilterType::Pointer m_UnaryFunctorFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx deleted file mode 100644 index 68ab556a9a2..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarImageFilter.hxx +++ /dev/null @@ -1,99 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ -#ifndef itkKrcahEigenToScalarImageFilter_hxx -#define itkKrcahEigenToScalarImageFilter_hxx - -#include "itkKrcahEigenToScalarImageFilter.h" -#include "itkProgressAccumulator.h" - -namespace itk -{ -template -KrcahEigenToScalarImageFilter::KrcahEigenToScalarImageFilter() -{ - /* Instantiate filters. */ - m_ParameterEstimationFilter = ParameterEstimationFilterType::New(); - m_UnaryFunctorFilter = UnaryFunctorFilterType::New(); - - /* We require an input image */ - this->SetNumberOfRequiredInputs(1); -} - -template -void -KrcahEigenToScalarImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -KrcahEigenToScalarImageFilter::EnlargeOutputRequestedRegion(DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -KrcahEigenToScalarImageFilter::GenerateData() -{ - /* Get inputs */ - InputImageConstPointer input = this->GetInput(); - - /* Connect filters */ - m_ParameterEstimationFilter->SetInput(input); - m_UnaryFunctorFilter->SetInput(m_ParameterEstimationFilter->GetOutput()); - m_UnaryFunctorFilter->SetAlphaInput(m_ParameterEstimationFilter->GetAlphaOutput()); - m_UnaryFunctorFilter->SetBetaInput(m_ParameterEstimationFilter->GetBetaOutput()); - m_UnaryFunctorFilter->SetGammaInput(m_ParameterEstimationFilter->GetGammaOutput()); - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_ParameterEstimationFilter, 0.5); - progress->RegisterInternalFilter(m_UnaryFunctorFilter, 0.5); - - /* Graft output and we're done! */ - m_UnaryFunctorFilter->Update(); - this->GraftOutput(m_UnaryFunctorFilter->GetOutput()); -} - -template -void -KrcahEigenToScalarImageFilter::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "ParameterEstimationFilter: " << m_ParameterEstimationFilter.GetPointer() << std::endl; - os << indent << "UnaryFunctorFiler: " << m_UnaryFunctorFilter.GetPointer() << std::endl; -} - -} // namespace itk - -#endif // itkKrcahEigenToScalarImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h deleted file mode 100644 index 79361d0e07d..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ /dev/null @@ -1,239 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_h -#define itkKrcahEigenToScalarParameterEstimationImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkNumericTraits.h" -#include "itkSimpleDataObjectDecorator.h" -#include "itkArray.h" - -namespace itk -{ -/** \class KrcahEigenToScalarParameterEstimationImageFilter - * \brief Automatic parameter estimation for the Krcah method - * - * This class takes an image of eigenvalues and estimates the parameters for the Krcah - * bone enhanced filter. According to the original paper, - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.25 - * \f} - * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. - * The trace of the matrix can be computed directly from the eigenvalues as the sum - * of the eigenvalues. - * - * In this implementation, the average of the trace is moved into the constant - * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary - * functor. The modification is very simple. If the average of the trace is - * denoted \f$ T \f$ the new parameter becomes: - * \f{ - * \gamma &=& 0.25 \cdot T - * \f} - * - * However, the code was implemented different than described in the original - * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum - * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. - * Furthermore, all parameters were scaled by a factor of 2 in the implementation - * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the - * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType - * can be set which enables the implementation parameters: - * \f{eqnarray*}{ - * \alpha &=& \sqrt{2} \cdot 0.5 \\ - * \beta &=& \sqrt{2} \cdot 0.5 \\ - * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T - * \f} - * Default is to use parameters from the implementation, not the paper. - * - * Finally, a mask can be provided. Metal or non-standard objects in the field - * of view may throw off the parameter estimation. In those cases, a mask can - * be provided so those voxels are not factored into the calculation of \f$ T \f$. - * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter - : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarParameterEstimationImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /** Image related type alias. */ - using InputImagePointer = typename TInputImage::Pointer; - using InputImageConstPointer = typename TInputImage::ConstPointer; - using InputRegionType = typename TInputImage::RegionType; - using InputSizeType = typename TInputImage::SizeType; - using InputIndexType = typename TInputImage::IndexType; - using InputPixelType = typename TInputImage::PixelType; - using InputPixelValueType = typename InputPixelType::ValueType; - - /** Output region definitions */ - using OutputRegionType = InputRegionType; - - /** Mask related type alias. */ - using MaskImagePointer = typename TMaskImage::Pointer; - using MaskImageConstPointer = typename TMaskImage::ConstPointer; - using MaskPixelType = typename TMaskImage::PixelType; - using MaskRegionType = typename TMaskImage::RegionType; - - /** Methods to set/get the mask image */ - itkSetInputMacro(MaskImage, TMaskImage); - itkGetInputMacro(MaskImage, TMaskImage); - - /** Iterator types */ - itkSetMacro(BackgroundValue, MaskPixelType); - itkGetConstMacro(BackgroundValue, MaskPixelType); - - typedef enum - { - UseImplementationParameters = 1, - UseJournalParameters - } KrcahImplementationType; - itkSetMacro(ParameterSet, KrcahImplementationType); - itkGetConstMacro(ParameterSet, KrcahImplementationType); - - /* Set parameter set */ - void - SetParameterSetToImplementation() - { - this->SetParameterSet(UseImplementationParameters); - } - - void - SetParameterSetToJournalArticle() - { - this->SetParameterSet(UseJournalParameters); - } - - /** Parameters */ - using RealType = typename NumericTraits::RealType; - using RealTypeDecoratedType = SimpleDataObjectDecorator; - - /** Decorators for parameters so they can be passed as a process object */ - RealTypeDecoratedType * - GetAlphaOutput(); - const RealTypeDecoratedType * - GetAlphaOutput() const; - RealTypeDecoratedType * - GetBetaOutput(); - const RealTypeDecoratedType * - GetBetaOutput() const; - RealTypeDecoratedType * - GetGammaOutput(); - const RealTypeDecoratedType * - GetGammaOutput() const; - - /** Standard getters for the output parameters */ - RealType - GetAlpha() const - { - return this->GetAlphaOutput()->Get(); - } - RealType - GetBeta() const - { - return this->GetBetaOutput()->Get(); - } - RealType - GetGamma() const - { - return this->GetGammaOutput()->Get(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarParameterEstimationImageFilter(); - virtual ~KrcahEigenToScalarParameterEstimationImageFilter() {} - - /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ - void - AllocateOutputs() override; - - /** Initialize some accumulators before the threads run. */ - void - BeforeThreadedGenerateData() override; - - /** Do final mean and variance computation from data accumulated in threads. */ - void - AfterThreadedGenerateData() override; - - /** Multi-thread version GenerateData. */ - void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) override; - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() override; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) override; - - void - PrintSelf(std::ostream & os, Indent indent) const override; - - /** Calculation of \f$ T \f$ changes depending on the implementation */ - inline RealType - CalculateTraceAccordingToImplementation(InputPixelType pixel); - inline RealType - CalculateTraceAccordingToJournalArticle(InputPixelType pixel); - -private: - /* Parameters */ - KrcahImplementationType m_ParameterSet; - - /* Inputs */ - MaskPixelType m_BackgroundValue; - - /* Arrays for threads */ - Array m_AccumulatedAverageTrace; - Array m_NumVoxels; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarParameterEstimationImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index 85a90c1b2a3..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,309 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_hxx -#define itkKrcahEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarParameterEstimationImageFilter::KrcahEigenToScalarParameterEstimationImageFilter() - : m_ParameterSet(UseImplementationParameters) - , m_BackgroundValue(NumericTraits::Zero) - , m_NumVoxels(1) - , m_AccumulatedAverageTrace(1) -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Resize threads */ - m_AccumulatedAverageTrace.SetSize(numberOfThreads); - m_NumVoxels.SetSize(numberOfThreads); - - m_AccumulatedAverageTrace.Fill(NumericTraits::ZeroValue()); - m_NumVoxels.Fill(NumericTraits::ZeroValue()); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - - /* Determine default parameters */ - RealType alpha, beta, gamma; - switch (m_ParameterSet) - { - case UseImplementationParameters: - alpha = Math::sqrt2 * 0.5f; - beta = Math::sqrt2 * 0.5f; - gamma = Math::sqrt2 * 0.5f; - break; - case UseJournalParameters: - alpha = 0.5f; - beta = 0.5f; - gamma = 0.25f; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Accumulate over threads */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - numVoxels += m_NumVoxels[i]; - accumulatedAverageTrace += m_AccumulatedAverageTrace[i]; - } - - /* Do derived measure */ - if (numVoxels > 0) - { - RealType averageTrace = (RealType)accumulatedAverageTrace / (RealType)numVoxels; - gamma = gamma * averageTrace; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetGammaOutput()->Set(gamma); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Determine which function to call */ - RealType (Self::*traceFunction)(InputPixelType); - switch (m_ParameterSet) - { - case UseImplementationParameters: - traceFunction = &Self::CalculateTraceAccordingToImplementation; - break; - case UseJournalParameters: - traceFunction = &Self::CalculateTraceAccordingToJournalArticle; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Count starts zero */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - numVoxels++; - - /* Compute trace */ - accumulatedAverageTrace += (this->*traceFunction)(inputIt.Get()); - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_AccumulatedAverageTrace[threadId] = accumulatedAverageTrace; - m_NumVoxels[threadId] = numVoxels; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToImplementation( - InputPixelType pixel) -{ - /* Sum of the absolute value of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += Math::abs(pixel[i]); - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToJournalArticle( - InputPixelType pixel) -{ - /* Sum of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += pixel[i]; - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "m_Alpha: " << this->GetAlpha() << std::endl; - os << indent << "m_Beta: " << this->GetBeta() << std::endl; - os << indent << "m_Gamma: " << this->GetGamma() << std::endl; - os << indent << "m_BackgroundValue: " << m_BackgroundValue << std::endl; - os << indent << "m_ParameterSet: " << m_ParameterSet << std::endl; -} - -} // end namespace itk - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h deleted file mode 100644 index a1e2ceb0e06..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ /dev/null @@ -1,146 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_h -#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkDiscreteGaussianImageFilter.h" -#include "itkSubtractImageFilter.h" -#include "itkMultiplyImageFilter.h" -#include "itkAddImageFilter.h" - -namespace itk -{ -/** \class KrcahEigenToScalarPreprocessingImageToImageFilter - * \brief Perform preprocessing as defined by Krcah et al - * - * This filters performs an unsharp filter as defined by Krcah - * et al. The unsharp filter is defined by: - * \f{ - * J = I+k*(I-(I*G)) - * \f} - * - * Where \f$ k \f$ is a scaling constant set to 5 and the Guassian - * filter has smoothing parameter \f$ s = 1 mm \f$. A user can modify - * these defaults using the appropriate setter methods. - * - * Additionally, this filter provides the ReleaseInternalFilterData - * flag. When this flag is set, the internal filters used to compute - * the unsharp filter will release their data after processing. This - * conserves memory at the expense of computation time if ScalingConstant - * or Sigma are changed. This flag is on by default. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter - : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarPreprocessingImageToImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarPreprocessingImageToImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); - - /** Extract some information from the image types. Dimensionality - * of the two images is assumed to be the same. */ - static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension; - - /** Image related type alias. */ - using PixelType = typename TInputImage::PixelType; - using OutputPixelType = typename TOutputImage::PixelType; - using RealType = typename NumericTraits::RealType; - using OutputPixelValueType = typename NumericTraits::ValueType; - - /** Typedefs for internal filters */ - using GaussianFilterType = DiscreteGaussianImageFilter; - using SubstractFilterType = SubtractImageFilter; - using MultiplyFilterType = MultiplyImageFilter; - using AddFilterType = AddImageFilter; - - /** Flag to release data or not */ - itkSetMacro(ReleaseInternalFilterData, bool); - itkGetConstMacro(ReleaseInternalFilterData, bool); - itkBooleanMacro(ReleaseInternalFilterData); - - /** Flag to release data or not */ - itkSetMacro(Sigma, RealType); - itkGetConstMacro(Sigma, RealType); - - /** Flag to release data or not */ - itkSetMacro(ScalingConstant, RealType); - itkGetConstMacro(ScalingConstant, RealType); - - /** DiscreteGaussianImageFilter needs a larger input requested region - * than the output requested region (larger by the size of the - * Gaussian kernel). As such, DiscreteGaussianImageFilter needs to - * provide an implementation for GenerateInputRequestedRegion() in - * order to inform the pipeline execution model. - * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - virtual void - GenerateInputRequestedRegion(); - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, - (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarPreprocessingImageToImageFilter(); - virtual ~KrcahEigenToScalarPreprocessingImageToImageFilter() {} - - /** Single threaded since we are connecting data */ - void - GenerateData() override; - - void - PrintSelf(std::ostream & os, Indent indent) const override; - -private: - /* Internal member variables */ - RealType m_Sigma; - RealType m_ScalingConstant; - bool m_ReleaseInternalFilterData; - - /* Filter member variables */ - typename GaussianFilterType::Pointer m_GaussianFilter; - typename SubstractFilterType::Pointer m_SubtractFilter; - typename MultiplyFilterType::Pointer m_MultiplyFilter; - typename AddFilterType::Pointer m_AddFilter; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx deleted file mode 100644 index eddf59a3679..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ /dev/null @@ -1,192 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx -#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx - -#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" -#include "itkGaussianOperator.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarPreprocessingImageToImageFilter::KrcahEigenToScalarPreprocessingImageToImageFilter() - : m_Sigma(1.0f) - , m_ScalingConstant(10.0f) - , m_ReleaseInternalFilterData(true) -{ - /* Only need the input image */ - this->SetNumberOfRequiredInputs(1); - - /* Instantiate all filters */ - m_GaussianFilter = GaussianFilterType::New(); - m_SubtractFilter = SubstractFilterType::New(); - m_MultiplyFilter = MultiplyFilterType::New(); - m_AddFilter = AddFilterType::New(); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() -{ - // This implementation is copied from itkDiscreteGaussianImageFilter - - // call the superclass' implementation of this method. this should - // copy the output requested region to the input requested region - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the input and output - typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); - - if (!inputPtr) - { - return; - } - - // Build an operator so that we can determine the kernel size - GaussianOperator oper; - - typename TInputImage::SizeType radius; - - for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) - { - // Determine the size of the operator in this dimension. Note that the - // Gaussian is built as a 1D operator in each of the specified directions. - oper.SetDirection(i); - if (m_GaussianFilter->GetUseImageSpacing() == true) - { - if (this->GetInput()->GetSpacing()[i] == 0.0) - { - itkExceptionMacro(<< "Pixel spacing cannot be zero"); - } - else - { - // convert the variance from physical units to pixels - double s = this->GetInput()->GetSpacing()[i]; - s = s * s; - oper.SetVariance(m_GaussianFilter->GetVariance()[i] / s); - } - } - else - { - oper.SetVariance(m_GaussianFilter->GetVariance()[i]); - } - oper.SetMaximumError(m_GaussianFilter->GetMaximumError()[i]); - oper.SetMaximumKernelWidth(m_GaussianFilter->GetMaximumKernelWidth()); - oper.CreateDirectional(); - - radius[i] = oper.GetRadius(i); - } - - // get a copy of the input requested region (should equal the output - // requested region) - typename TInputImage::RegionType inputRequestedRegion; - inputRequestedRegion = inputPtr->GetRequestedRegion(); - - // pad the input requested region by the operator radius - inputRequestedRegion.PadByRadius(radius); - - // crop the input requested region at the input's largest possible region - if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) - { - inputPtr->SetRequestedRegion(inputRequestedRegion); - return; - } - else - { - // Couldn't crop the region (requested region is outside the largest - // possible region). Throw an exception. - - // store what we tried to request (prior to trying to crop) - inputPtr->SetRequestedRegion(inputRequestedRegion); - - // build an exception - InvalidRequestedRegionError e(__FILE__, __LINE__); - e.SetLocation(ITK_LOCATION); - e.SetDescription("Requested region is (at least partially) outside the largest possible region."); - e.SetDataObject(inputPtr); - throw e; - } -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateData() -{ - /* Get Input */ - typename TInputImage::Pointer input = TInputImage::New(); - input->Graft(const_cast(this->GetInput())); - - /* I*G */ - m_GaussianFilter->SetInput(input); - m_GaussianFilter->SetVariance(Math::squared_magnitude(this->GetSigma())); - - /* I - I*G */ - m_SubtractFilter->SetInput1(input); - m_SubtractFilter->SetInput2(m_GaussianFilter->GetOutput()); - - /* k(I-(I*G)) */ - m_MultiplyFilter->SetInput(m_SubtractFilter->GetOutput()); - m_MultiplyFilter->SetConstant(this->GetScalingConstant()); - - /* I+k*(I-(I*G)) */ - m_AddFilter->SetInput1(input); - m_AddFilter->SetInput2(m_MultiplyFilter->GetOutput()); - - /* Release data if asked */ - if (this->GetReleaseInternalFilterData()) - { - m_GaussianFilter->ReleaseDataFlagOn(); - m_SubtractFilter->ReleaseDataFlagOn(); - m_MultiplyFilter->ReleaseDataFlagOn(); - m_AddFilter->ReleaseDataFlagOn(); - } - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_GaussianFilter, 0.25); - progress->RegisterInternalFilter(m_SubtractFilter, 0.25); - progress->RegisterInternalFilter(m_MultiplyFilter, 0.25); - progress->RegisterInternalFilter(m_AddFilter, 0.25); - - /* Graft Output */ - m_AddFilter->Update(); - this->GraftOutput(m_AddFilter->GetOutput()); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "GaussianFilter: " << m_GaussianFilter.GetPointer() << std::endl; - os << indent << "SubtractFilter: " << m_SubtractFilter.GetPointer() << std::endl; - os << indent << "MultiplyFilter: " << m_MultiplyFilter.GetPointer() << std::endl; - os << indent << "AddFilter: " << m_AddFilter.GetPointer() << std::endl; - os << indent << "Sigma: " << GetSigma() << std::endl; - os << indent << "ScalingConstant: " << GetScalingConstant() << std::endl; - os << indent << "ReleaseInternalFilterData: " << GetReleaseInternalFilterData() << std::endl; -} - -} // namespace itk - -#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h index ab8636b60d2..014c44178f8 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMaximumAbsoluteValueImageFilter.h @@ -81,7 +81,7 @@ class MaximumAbsoluteValue * \ingroup BoneEnhancement */ template -class MaximumAbsoluteValueImageFilter +class ITK_TEMPLATE_EXPORT MaximumAbsoluteValueImageFilter : public BinaryFunctorImageFilter; - using HessianImageType = typename HessianFilterType::OutputImageType; - using HessianPixelType = typename HessianImageType::PixelType; + /** Input Image typedefs. */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); + + /** Output image typedefs. */ + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointer; + typedef typename OutputImageType::ConstPointer OutputImageConstPointer; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + + /** Mask related typedefs. */ + typedef ImageMaskSpatialObject SpatialObjectType; + typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + + /** Methods to set/get the mask image */ + itkSetInputMacro(ImageMask, SpatialObjectType); + itkGetInputMacro(ImageMask, SpatialObjectType); + + /** Hessian related typedefs. */ + // typedef HessianRecursiveGaussianImageFilter< TInputImage > HessianFilterType; + typedef HessianGaussianImageFilter HessianFilterType; + typedef typename HessianFilterType::OutputImageType HessianImageType; + typedef typename HessianImageType::PixelType HessianPixelType; + typedef typename HessianFilterType::InternalRealType InternalRealType; /** Eigenvalue analysis related type alias. The ITK python wrapping usually wraps floating types * and not double types. For this reason, the eigenvalues are of type float. */ - using RealType = typename NumericTraits::RealType; - using FloatType = typename NumericTraits::FloatType; - using EigenValueArrayType = Vector; - using EigenValueImageType = Image; - using EigenAnalysisFilterType = SymmetricEigenAnalysisImageFilter; + typedef typename NumericTraits::RealType RealType; + typedef typename NumericTraits::FloatType FloatType; + typedef Vector EigenValueArrayType; + typedef Image EigenValueImageType; + typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; /** Maximum over scale related type alias. */ using MaximumAbsoluteValueFilterType = MaximumAbsoluteValueImageFilter; - /** Eigenvalue image to scalar image related type alias */ - using EigenToScalarImageFilterType = EigenToScalarImageFilter; + /** Eigenvalue image to measure image related typedefs */ + typedef EigenToMeasureImageFilter EigenToMeasureImageFilterType; + typedef EigenToMeasureParameterEstimationFilter + EigenToMeasureParameterEstimationFilterType; /** Need some types to determine how to order the eigenvalues */ - // using InternalEigenValueOrderType = typename Functor::SymmetricEigenAnalysisFunction::EigenValueOrderType; - using InternalEigenValueOrderType = typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType; - using ExternalEigenValueOrderType = typename EigenToScalarImageFilterType::EigenValueOrderType; + typedef typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType InternalEigenValueOrderType; + typedef typename EigenToMeasureImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; + + /** Set/Get the EigenToMeasureImageFilter. */ + itkSetObjectMacro(EigenToMeasureImageFilter, EigenToMeasureImageFilterType); + itkGetModifiableObjectMacro(EigenToMeasureImageFilter, EigenToMeasureImageFilterType); - /** Set/Get the EigenToScalarImageFilter. */ - itkSetObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); - itkGetModifiableObjectMacro(EigenToScalarImageFilter, EigenToScalarImageFilterType); + /** Set/Get the EigenToMeasureParameterEstimationFilter. */ + itkSetObjectMacro(EigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilterType); + itkGetModifiableObjectMacro(EigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilterType); /** Sigma values. */ using SigmaType = RealType; @@ -126,9 +154,9 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image /** * Static methods for generating an array of sigma values. Note that these still need to be passed - * into the class using SetSigmaArray . Implementation taken from itkMultiScaleHessianBasedMeasureImageFilter. + * into the class using SetSigmaArray. Implementation taken from itkMultiScaleHessianBasedMeasureImageFilter. * Note that these methods cannot throw exceptions according to the standard itkExceptionMacro since they are static - * methods. Instead, they will return an empty sigma array on error. + * methods. Instead, they will return an empty sigma array on error. TODO: Not ture any more. */ static SigmaArrayType GenerateSigmaArray(SigmaType SigmaMinimum, @@ -146,7 +174,6 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image (Concept::SameDimension)); // End concept checking #endif - protected: MultiScaleHessianEnhancementImageFilter(); virtual ~MultiScaleHessianEnhancementImageFilter() {} @@ -167,6 +194,9 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image void GenerateInputRequestedRegion() override; + OutputImageRegionType + GetOutputRegion(); + /** Override since the filter produces all of its output */ void EnlargeOutputRequestedRegion(DataObject * data) override; @@ -176,10 +206,11 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image private: /** Internal filters. */ - typename HessianFilterType::Pointer m_HessianFilter; - typename EigenAnalysisFilterType::Pointer m_EigenAnalysisFilter; - typename MaximumAbsoluteValueFilterType::Pointer m_MaximumAbsoluteValueFilter; - typename EigenToScalarImageFilterType::Pointer m_EigenToScalarImageFilter; + typename HessianFilterType::Pointer m_HessianFilter; + typename EigenAnalysisFilterType::Pointer m_EigenAnalysisFilter; + typename MaximumAbsoluteValueFilterType::Pointer m_MaximumAbsoluteValueFilter; + typename EigenToMeasureImageFilterType::Pointer m_EigenToMeasureImageFilter; + typename EigenToMeasureParameterEstimationFilterType::Pointer m_EigenToMeasureParameterEstimationFilter; /** Sigma member variables. */ SigmaArrayType m_SigmaArray; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 1268a198f31..7077fc9845d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -35,7 +35,8 @@ MultiScaleHessianEnhancementImageFilter::MultiScaleHe m_HessianFilter = HessianFilterType::New(); m_EigenAnalysisFilter = EigenAnalysisFilterType::New(); m_MaximumAbsoluteValueFilter = MaximumAbsoluteValueFilterType::New(); - m_EigenToScalarImageFilter = nullptr; // has to be provided by the user. + m_EigenToMeasureImageFilter = nullptr; // has to be provided by the user. + m_EigenToMeasureParameterEstimationFilter = nullptr; // has to be provided by the user. /* We require an input image */ this->SetNumberOfRequiredInputs(1); @@ -46,11 +47,16 @@ void MultiScaleHessianEnhancementImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); - if (this->GetInput()) + + // get pointers to the input + typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) { - typename TInputImage::Pointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); + return; } + + inputPtr->SetRequestedRegionToLargestPossibleRegion(); } template @@ -58,7 +64,38 @@ void MultiScaleHessianEnhancementImageFilter::EnlargeOutputRequestedRegion(DataObject * data) { Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); + OutputImagePointer imgData = dynamic_cast(data); + + // if ( this->GetInput() ) + // { + // OutputImageRegionType region = this->GetOutputRegion(); + // // crop the input requested region at the input's largest possible region + // if ( region.Crop( imgData->GetLargestPossibleRegion() ) ) + // { + // imgData->SetRequestedRegion(region); + // return; + // } + // else + // { + // // Couldn't crop the region (requested region is outside the largest + // // possible region). Throw an exception. + + // // store what we tried to request (prior to trying to crop) + // imgData->SetRequestedRegion(region); + + // // build an exception + // InvalidRequestedRegionError e(__FILE__, __LINE__); + // e.SetLocation(ITK_LOCATION); + // e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + // e.SetDataObject(imgData); + // throw e; + // } + // } + // else + if (imgData) + { + imgData->SetRequestedRegionToLargestPossibleRegion(); + } } template @@ -66,9 +103,14 @@ void MultiScaleHessianEnhancementImageFilter::GenerateData() { /* Test all inputs are set */ - if (!m_EigenToScalarImageFilter) + if (!m_EigenToMeasureImageFilter) { - itkExceptionMacro(<< "EigenToScalarImageFilter is not present"); + itkExceptionMacro(<< "m_EigenToMeasureImageFilter is not present"); + } + + if (!m_EigenToMeasureParameterEstimationFilter) + { + itkExceptionMacro(<< "m_EigenToMeasureParameterEstimationFilter is not present"); } if (m_SigmaArray.GetSize() < 1) @@ -80,17 +122,29 @@ MultiScaleHessianEnhancementImageFilter::GenerateData /* Set filters parameters */ m_HessianFilter->SetNormalizeAcrossScale(true); m_EigenAnalysisFilter->SetDimension(ImageDimension); - m_EigenAnalysisFilter->OrderEigenValuesBy(this->ConvertType(m_EigenToScalarImageFilter->GetEigenValueOrder())); + m_EigenAnalysisFilter->OrderEigenValuesBy(this->ConvertType(m_EigenToMeasureImageFilter->GetEigenValueOrder())); /* Connect filters */ m_HessianFilter->SetInput(this->GetInput()); m_EigenAnalysisFilter->SetInput(m_HessianFilter->GetOutput()); - m_EigenToScalarImageFilter->SetInput(m_EigenAnalysisFilter->GetOutput()); + m_EigenToMeasureParameterEstimationFilter->SetInput(m_EigenAnalysisFilter->GetOutput()); + m_EigenToMeasureImageFilter->SetInput(m_EigenToMeasureParameterEstimationFilter->GetOutput()); + m_EigenToMeasureImageFilter->SetParametersInput(m_EigenToMeasureParameterEstimationFilter->GetParametersOutput()); + + /* Set the mask */ + SpatialObjectConstPointer mask = this->GetImageMask(); + if (mask) + { + m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); + m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); + } /* After executing we want to release data to save memory */ - m_HessianFilter->ReleaseDataFlagOn(); - m_EigenAnalysisFilter->ReleaseDataFlagOn(); - m_EigenToScalarImageFilter->ReleaseDataFlagOn(); + // m_HessianFilter->ReleaseDataFlagOn(); + // m_EigenAnalysisFilter->ReleaseDataFlagOn(); + // m_EigenToMeasureImageFilter->ReleaseDataFlagOn(); + // m_EigenToMeasureParameterEstimationFilter->ReleaseDataFlagOn(); + // m_MaximumAbsoluteValueFilter->ReleaseDataFlagOn(); /* Setup progress reporter */ ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); @@ -100,16 +154,20 @@ MultiScaleHessianEnhancementImageFilter::GenerateData * We checked that m_SigmaArray.GetSize() > 0 above and do not need to repeat the check. However, * if we are only given one sigma value we do not need to take the maximum over scales. * - * Three filters, ran m_SigmaArray.GetSize() times + * Two filters, ran m_SigmaArray.GetSize() times * One filter, ran (m_SigmaArray.GetSize() - 1) times + * + * We do not count the hessian or eigenanalysis filters since they will be streamed many times. */ - float numberOfFiltersToProcess = 3 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); + float numberOfFiltersToProcess = 2 * m_SigmaArray.GetSize() + 1 * (m_SigmaArray.GetSize() - 1); float perFilterProccessPercentage = 1.0 / numberOfFiltersToProcess; itkDebugMacro(<< "each filter accounts for " << perFilterProccessPercentage * 100.0 << "% of processing"); - progress->RegisterInternalFilter(m_HessianFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenAnalysisFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); - progress->RegisterInternalFilter(m_EigenToScalarImageFilter, m_SigmaArray.GetSize() * perFilterProccessPercentage); + + progress->RegisterInternalFilter(m_EigenToMeasureParameterEstimationFilter, + 1.5 * m_SigmaArray.GetSize() * perFilterProccessPercentage); + progress->RegisterInternalFilter(m_EigenToMeasureImageFilter, + 0.5 * m_SigmaArray.GetSize() * perFilterProccessPercentage); /* Check if we need to run the MaximumAbsoluteValueFilter at all */ if (m_SigmaArray.GetSize() > 1) @@ -123,28 +181,29 @@ MultiScaleHessianEnhancementImageFilter::GenerateData } /* We store a single pointer that we will graft to the output */ - typename TOutputImage::Pointer outputImageTypePointer; + typename TOutputImage::Pointer outputImagePointer; /* Process the first scale */ - outputImageTypePointer = generateResponseAtScale((SigmaStepsType)0); + outputImagePointer = generateResponseAtScale((SigmaStepsType)0); /* Process the remaining sigma values */ for (SigmaStepsType scaleLevel = 1; scaleLevel < m_SigmaArray.GetSize(); ++scaleLevel) { /* Calculate next response value */ - typename TOutputImage::Pointer tempResponseOutputImageTypePointer = generateResponseAtScale(scaleLevel); + typename TOutputImage::Pointer tempResponseImagePointer = generateResponseAtScale(scaleLevel); /* Take absolute value maximum */ - m_MaximumAbsoluteValueFilter->SetInput1(outputImageTypePointer); - m_MaximumAbsoluteValueFilter->SetInput2(tempResponseOutputImageTypePointer); + m_MaximumAbsoluteValueFilter->SetInput1(outputImagePointer); + m_MaximumAbsoluteValueFilter->SetInput2(tempResponseImagePointer); + // m_MaximumAbsoluteValueFilter->GetOutput()->SetRequestedRegion(this->GetOutputRegion()); m_MaximumAbsoluteValueFilter->Update(); /* Save max and go to next sigma value */ - outputImageTypePointer = m_MaximumAbsoluteValueFilter->GetOutput(); + outputImagePointer = m_MaximumAbsoluteValueFilter->GetOutput(); } /* Graft output and we're done! */ - this->GraftOutput(outputImageTypePointer); + this->GraftOutput(outputImagePointer); } template @@ -156,8 +215,40 @@ MultiScaleHessianEnhancementImageFilter::generateResp /* Process pipeline and return */ m_HessianFilter->SetSigma(thisSigma); - m_EigenToScalarImageFilter->Update(); - return m_EigenToScalarImageFilter->GetOutput(); + // m_EigenToMeasureImageFilter->GetOutput()->SetRequestedRegion(this->GetOutputRegion()); + m_EigenToMeasureImageFilter->Update(); + return m_EigenToMeasureImageFilter->GetOutput(); +} + +template +typename MultiScaleHessianEnhancementImageFilter::OutputImageRegionType +MultiScaleHessianEnhancementImageFilter::GetOutputRegion() +{ + /* Create region */ + OutputImageRegionType region; + + /* Get and test input */ + InputImagePointer inputPtr = const_cast(this->GetInput()); + + if (!inputPtr) + { + itkExceptionMacro(<< "Input image must be set to run this filter."); + } + region = inputPtr->GetLargestPossibleRegion(); + + /* Grab the mask pointer */ + SpatialObjectConstPointer mask = this->GetImageMask(); + if (!mask) + { + // No mask was set so we need to estimate parameters across the whole image + return region; + } + + /* Crop the region */ + typename SpatialObjectType::RegionType maskRegion = mask->GetAxisAlignedBoundingBoxRegion(); + region.Crop(maskRegion); + + return region; } template @@ -249,11 +340,11 @@ MultiScaleHessianEnhancementImageFilter::ConvertType( { switch (order) { - case EigenToScalarImageFilterType::OrderByValue: + case EigenToMeasureImageFilterType::OrderByValue: return EigenAnalysisFilterType::FunctorType::OrderByValue; - case EigenToScalarImageFilterType::OrderByMagnitude: + case EigenToMeasureImageFilterType::OrderByMagnitude: return EigenAnalysisFilterType::FunctorType::OrderByMagnitude; - case EigenToScalarImageFilterType::DoNotOrder: + case EigenToMeasureImageFilterType::DoNotOrder: return EigenAnalysisFilterType::FunctorType::DoNotOrder; default: itkExceptionMacro(<< "Trying to convert bad order " << order); @@ -268,7 +359,9 @@ MultiScaleHessianEnhancementImageFilter::PrintSelf(st os << indent << "HessianFilter: " << m_HessianFilter.GetPointer() << std::endl; os << indent << "EigenAnalysisFilter: " << m_EigenAnalysisFilter.GetPointer() << std::endl; os << indent << "MaximumAbsoluteValueFilter: " << m_MaximumAbsoluteValueFilter.GetPointer() << std::endl; - os << indent << "EigenToScalarImageFilter: " << m_EigenToScalarImageFilter.GetPointer() << std::endl; + os << indent << "EigenToMeasureImageFilter: " << m_EigenToMeasureImageFilter.GetPointer() << std::endl; + os << indent << "EigenToMeasureParameterEstimationFilter: " << m_EigenToMeasureParameterEstimationFilter.GetPointer() + << std::endl; os << indent << "SigmaArray: " << m_SigmaArray << std::endl; } diff --git a/Modules/Filtering/BoneEnhancement/itk-module.cmake b/Modules/Filtering/BoneEnhancement/itk-module.cmake index 511c4ba5f46..f019f3e57c3 100644 --- a/Modules/Filtering/BoneEnhancement/itk-module.cmake +++ b/Modules/Filtering/BoneEnhancement/itk-module.cmake @@ -15,7 +15,6 @@ itk_module( ITKStatistics ITKImageFilterBase ITKImageFeature - ITKReview ITKSpatialObjects COMPILE_DEPENDS ITKImageSources diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 80fec36e66d..330740fa631 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -32,9 +32,7 @@ itk_add_test( set( BoneEnhancementUnitTests - itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx - itkDescoteauxEigenToMeasureFunctorUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx ) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx deleted file mode 100644 index f30077f7e74..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureFunctorUnitTest.cxx +++ /dev/null @@ -1,276 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureImageFilter.h" - -namespace -{ -template -class itkDescoteauxEigenToMeasureFunctorUnitTest : public ::testing::Test -{ -public: - /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenImageType; - typedef itk::Image ImageType; - typedef typename itk::Functor::DescoteauxEigenToMeasureFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - - itkDescoteauxEigenToMeasureFunctorUnitTest() - { - m_Functor = FunctorType(); - m_EigenPixel = EigenValueArrayType(); - } - ~itkDescoteauxEigenToMeasureFunctorUnitTest() override {} - -protected: - void - SetUp() override - {} - void - TearDown() override - {} - - FunctorType m_Functor; - EigenValueArrayType m_EigenPixel; - ParameterType m_Parameters; -}; -} // namespace - -// Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; -TYPED_TEST_CASE(itkDescoteauxEigenToMeasureFunctorUnitTest, TestingLabelTypes); - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, InitialParameters) -{ - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetEnhanceType) -{ - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); - this->m_Functor.SetEnhanceDarkObjects(); - EXPECT_DOUBLE_EQ(1.0, this->m_Functor.GetEnhanceType()); - this->m_Functor.SetEnhanceBrightObjects(); - EXPECT_DOUBLE_EQ(-1.0, this->m_Functor.GetEnhanceType()); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, SetGetParameters) -{ - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); - - this->m_Parameters[0] = 100; - this->m_Parameters[1] = 200; - this->m_Parameters[2] = 300; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Parameters = this->m_Functor.GetParameters(); - EXPECT_DOUBLE_EQ(100.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(200.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(300.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFirstParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFirstParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - EXPECT_NEAR(0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSecondParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSecondParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightThirdParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkThirdParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFourthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFourthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.999329187279, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightFifthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkFifthParameterSet) -{ - this->m_Parameters[0] = 0.5; - this->m_Parameters[1] = 0.5; - this->m_Parameters[2] = 0.25; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.0913983433747, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, BrightSixthParameterSet) -{ - this->m_Parameters[0] = 0.25; - this->m_Parameters[1] = 0.25; - this->m_Parameters[2] = 0.5; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = -1; - EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureFunctorUnitTest, DarkSixthParameterSet) -{ - this->m_Parameters[0] = 0.25; - this->m_Parameters[1] = 0.25; - this->m_Parameters[2] = 0.5; - this->m_Functor.SetParameters(this->m_Parameters); - this->m_Functor.SetEnhanceDarkObjects(); - - /* All zeros returns zero */ - this->m_EigenPixel[0] = 0.25; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - EXPECT_NEAR((TypeParam)0.000326373962098, this->m_Functor(this->m_EigenPixel), 1e-6); -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx index 78bb12a4925..b64a9026f93 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -38,15 +38,18 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test typedef itk::ImageMaskSpatialObject SpatialObjectType; typedef itk::Image MaskImageType; typedef typename itk::DescoteauxEigenToMeasureImageFilter - FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterType ParameterType; + FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; itkDescoteauxEigenToMeasureImageFilterUnitTest() { /* Instantiate filter */ m_Filter = FilterType::New(); + /* Set parameter size */ + m_Parameters.SetSize(3); + /* Create EigenPixels */ for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) { @@ -154,7 +157,7 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test EigenValueArrayType m_ZeroEigenPixel; EigenValueArrayType m_NonZeroEigenPixel; EigenValueArrayType m_NonZeroDarkEigenPixel; - ParameterType m_Parameters; + ParameterArrayType m_Parameters; typename EigenImageType::RegionType m_Region; typename EigenImageType::RegionType m_MaskRegion; typename SpatialObjectType::Pointer m_SpatialObject; @@ -202,7 +205,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelBri this->m_Parameters[2] = 0.25; this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -225,7 +227,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelDar this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); this->m_Filter->SetEnhanceDarkObjects(); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -247,7 +248,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe this->m_Parameters[2] = 0.25; this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -270,7 +270,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroDarkEigenImage); this->m_Filter->SetEnhanceDarkObjects(); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -293,7 +292,6 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); - this->m_Filter->Update(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx index 07913da2dda..82477c99be6 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -36,8 +36,8 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te typedef itk::ImageMaskSpatialObject SpatialObjectType; typedef itk::Image MaskImageType; typedef typename itk::DescoteauxEigenToMeasureParameterEstimationFilter FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterType ParameterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() { @@ -138,14 +138,14 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te EigenValueArrayType m_OneEigenPixel; EigenValueArrayType m_ZeroEigenPixel; EigenValueArrayType m_LargeEigenPixel; - ParameterType m_Parameters; + ParameterArrayType m_Parameters; typename EigenImageType::RegionType m_Region; typename SpatialObjectType::Pointer m_SpatialObject; }; } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +typedef ::testing::Types TestingLabelTypes; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) @@ -153,9 +153,9 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, Initial EXPECT_DOUBLE_EQ(0.5, this->m_Filter->GetFrobeniusNormWeight()); this->m_Parameters = this->m_Filter->GetParameters(); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(1.0, this->m_Parameters[2]); } TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImage) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx deleted file mode 100644 index c4583e6f8a3..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterFunctorUnitTest.cxx +++ /dev/null @@ -1,141 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkGTest.h" -#include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" - -namespace -{ -template -class itkDescoteauxEigenToMeasureParameterFunctorUnitTest : public ::testing::Test -{ -public: - /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Functor::DescoteauxEigenToMeasureParameterFunctor FunctorType; - typedef typename FunctorType::ParameterType ParameterType; - - itkDescoteauxEigenToMeasureParameterFunctorUnitTest() - { - m_Functor = FunctorType(); - m_EigenPixel = EigenValueArrayType(); - } - ~itkDescoteauxEigenToMeasureParameterFunctorUnitTest() override {} - -protected: - void - SetUp() override - {} - void - TearDown() override - {} - - FunctorType m_Functor; - EigenValueArrayType m_EigenPixel; - ParameterType m_Parameters; -}; -} // namespace - -// Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; -TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestingLabelTypes); - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, InitialParameters) -{ - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, SetGetFrobeniusNormWeight) -{ - EXPECT_DOUBLE_EQ(0.5, this->m_Functor.GetFrobeniusNormWeight()); - this->m_Functor.SetFrobeniusNormWeight(0.1); - EXPECT_DOUBLE_EQ(0.1, this->m_Functor.GetFrobeniusNormWeight()); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfZero) -{ - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOne) -{ - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.86602540378, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.5 -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestPixelOfOneWithDifferentWeight) -{ - this->m_EigenPixel[0] = 1; - this->m_EigenPixel[1] = 1; - this->m_EigenPixel[2] = 1; - this->m_Functor.Initialize(1); - this->m_Functor.ProcessPixel(this->m_EigenPixel, 0); - this->m_Functor.SetFrobeniusNormWeight(0.1); - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(0.17320508075, this->m_Parameters[2], 1e-6); // sqrt(3) * 0.1 -} - -TYPED_TEST(itkDescoteauxEigenToMeasureParameterFunctorUnitTest, TestMultiplePixels) -{ - unsigned int num = 10; - this->m_EigenPixel[0] = 0; - this->m_EigenPixel[1] = 0; - this->m_EigenPixel[2] = 0; - this->m_Functor.Initialize(num); - for (unsigned int i = 0; i < num; ++i) - { - for (unsigned int j = 0; j < this->m_EigenPixel.Length; ++j) - { - this->m_EigenPixel[j] = this->m_EigenPixel[j] + 2; - } - - this->m_Functor.ProcessPixel(this->m_EigenPixel, i); - } - - this->m_Parameters = this->m_Functor.GetComputedParameters(); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); - EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); - EXPECT_NEAR(17.3205080757, this->m_Parameters[2], 1e-6); // sqrt(3*20^2) * 0.5 -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx deleted file mode 100644 index 344acd4a248..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx +++ /dev/null @@ -1,121 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" -#include "itkUnaryFunctorImageFilter.h" -#include "itkTestingMacros.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkMath.h" - -int -itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) -{ - /* type alias, instantiate filter */ - constexpr unsigned int Dimension = 3; - using ImagePixelType = double; - using ImageType = itk::Image; - - using EigenValueType = double; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using FilterType = itk::DescoteauxEigenToScalarFunctorImageFilter; - FilterType::Pointer descoFilter = FilterType::New(); - - /* Basic tests. Need to set parameters first. */ - descoFilter->SetAlpha(0.5); - descoFilter->SetBeta(0.5); - descoFilter->SetC(0.25); - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /* Exercise basic set/get methods */ - descoFilter->SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetAlpha()); - descoFilter->SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetBeta()); - descoFilter->SetC(0.25); - TEST_SET_GET_VALUE(0.25, descoFilter->GetC()); - // Default should be 1 - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); - descoFilter->SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, descoFilter->GetEnhanceType()); - descoFilter->SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, 0); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - itk::ImageRegionIteratorWithIndex input(descoFilter->GetOutput(), region); - - input.GoToBegin(); - while (!input.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); - ++input; - } - - /* Create some test data which is computable */ - simpleEigenPixel.SetElement(0, 0.25); - simpleEigenPixel.SetElement(1, 1); - simpleEigenPixel.SetElement(2, -1); - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - descoFilter->SetInput(image2); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - itk::ImageRegionIteratorWithIndex input2(descoFilter->GetOutput(), region); - - input2.GoToBegin(); - while (!input2.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.0913983433747, 6, 0.000001)); - ++input2; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx deleted file mode 100644 index 44fc42de65e..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ /dev/null @@ -1,121 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarFunctorImageFilter.h" -#include "itkTestingMacros.h" - -int -itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) -{ - /* type alias, instantiate functor */ - constexpr unsigned int Dimension = 3; - using ImagePixelType = double; - using ImageType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using FunctorType = itk::Functor::DescoteauxEigenToScalarFunctor; - FunctorType functor = FunctorType(); - - /* Exercise basic set/get methods */ - functor.SetAlpha(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetAlpha()); - functor.SetBeta(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetBeta()); - functor.SetC(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetC()); - // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); - functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - - /* Test a few calculations */ - EigenValueArrayType mEigenValueArray; - functor.SetAlpha(0.5); - functor.SetBeta(0.5); - functor.SetC(0.25); - functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* Return zero on positive l3 with bright sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* Return zero on positive l3 with dark sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = -1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 0, 0, -1; bright sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); - - /* 0, 0, 1; dark sheets */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); - - /* 1, 1, -1; bright sheets */ - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 1, 1, 1; dark sheets */ - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* 0.25, 1, -1; bright sheets */ - mEigenValueArray[0] = 0.25; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = -1; - functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); - - /* 0.25, 1, 1; dark sheets */ - mEigenValueArray[0] = 0.25; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx deleted file mode 100644 index b5e4221ee2c..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx +++ /dev/null @@ -1,94 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) -{ - constexpr unsigned int Dimension = 3; - using MaskPixelType = unsigned int; - using MaskType = itk::Image; - - using OutputPixelType = double; - using OutputType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using DescoteauxEigenToScalarImageFilterType = - itk::DescoteauxEigenToScalarImageFilter; - - DescoteauxEigenToScalarImageFilterType::Pointer descoFilter = DescoteauxEigenToScalarImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); - - /* Test defaults */ - TEST_EXPECT_EQUAL(descoFilter->GetEigenValueOrder(), - DescoteauxEigenToScalarImageFilterType::Superclass::OrderByMagnitude); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - simpleEigenPixel.SetElement(0, 0.5); - simpleEigenPixel.SetElement(1, 1.25); - simpleEigenPixel.SetElement(2, -2); - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - /* Run with no exceptions */ - descoFilter->SetEnhanceBrightObjects(); - descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); - - /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetC(), 2.41091269 * 0.5, 6, 0.000001)); - - itk::ImageRegionIteratorWithIndex it(descoFilter->GetOutput(), region); - - it.GoToBegin(); - while (!it.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.364376944099, 6, 0.000001)); - ++it; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx deleted file mode 100644 index 97a3679c76a..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ /dev/null @@ -1,170 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) -{ - constexpr unsigned int Dimension = 3; - using MaskPixelType = unsigned int; - using MaskType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using DescoteauxEigenToScalarParameterEstimationImageFilterType = - itk::DescoteauxEigenToScalarParameterEstimationImageFilter; - - DescoteauxEigenToScalarParameterEstimationImageFilterType::Pointer descoteauxParameterEstimator = - DescoteauxEigenToScalarParameterEstimationImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS( - descoteauxParameterEstimator, DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /* Test defaults */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetCOutput()->Get(), 0.5, 6, 0.000001)); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, -1); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - EigenValueImageType::IndexType maskStart; - maskStart[0] = 2; - maskStart[1] = 2; - maskStart[2] = 2; - - EigenValueImageType::SizeType maskSize; - maskSize[0] = 8; - maskSize[1] = 8; - maskSize[2] = 8; - - MaskPixelType backgroundValue = 1; - MaskPixelType foregroundValue = 2; - MaskType::Pointer mask = MaskType::New(); - mask->SetRegions(region); - mask->Allocate(); - mask->FillBuffer(backgroundValue); - - EigenValueArrayType newEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - newEigenPixel.SetElement(i, 3); - } - - EigenValueImageType::RegionType maskRegion; - maskRegion.SetSize(maskSize); - maskRegion.SetIndex(maskStart); - - itk::ImageRegionIteratorWithIndex input2It(image2, maskRegion); - itk::ImageRegionIteratorWithIndex maskIt(mask, maskRegion); - - input2It.GoToBegin(); - maskIt.GoToBegin(); - while (!input2It.IsAtEnd()) - { - input2It.Set(newEigenPixel); - maskIt.Set(foregroundValue); - ++input2It; - ++maskIt; - } - - /* Test an empty pixel value */ - descoteauxParameterEstimator->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - /* Test an empty pixel value */ - descoteauxParameterEstimator->SetFrobeniusNormWeight(0.25); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.25, 6, 0.000001)); - - /* Test with a mask */ - descoteauxParameterEstimator->SetInput(image2); - descoteauxParameterEstimator->SetMaskImage(mask); - descoteauxParameterEstimator->SetBackgroundValue(foregroundValue); - descoteauxParameterEstimator->SetFrobeniusNormWeight(0.5); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - descoteauxParameterEstimator->SetInput(image2); - descoteauxParameterEstimator->SetMaskImage(mask); - descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); - - MaskType::Pointer mask2 = MaskType::New(); - mask2->SetRegions(maskRegion); - mask2->Allocate(); - mask2->FillBuffer(foregroundValue); - - descoteauxParameterEstimator->SetInput(image); - descoteauxParameterEstimator->SetMaskImage(mask2); - descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx deleted file mode 100644 index 38d282791d9..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ /dev/null @@ -1,155 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarFunctorImageFilter.h" -#include "itkTestingMacros.h" - -int -itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) -{ - /* type alias, instantiate functor */ - constexpr unsigned int Dimension = 3; - using ImagePixelType = double; - using ImageType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using FunctorType = itk::Functor::KrcahEigenToScalarFunctor; - FunctorType functor = FunctorType(); - - /* Exercise basic set/get methods */ - functor.SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetAlpha()); - functor.SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetBeta()); - functor.SetGamma(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetGamma()); - // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); - functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); - - /* Test a few calculations */ - EigenValueArrayType mEigenValueArray; - functor.SetAlpha(0.5); - functor.SetBeta(0.5); - functor.SetGamma(0.25); - functor.SetEnhanceBrightObjects(); - - /* All zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* lambda_2 zeros returns zero */ - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 0; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); - - /* lambda_1 zero */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.0183156368276, 6, 0.000001)); - - /* lambda_1 zero; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0183156368276, 6, 0.000001)); - - /* one, one, one */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); - - /* one, one, one; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 1; - mEigenValueArray[1] = 1; - mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); - - /* one, one, one negative */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -1; - mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); - - /* one, one, one negative; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -1; - mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); - - /* -1, -2, 3 */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -2; - mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.15123975969, 6, 0.000001)); - - /* -1, -2, 3; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = -1; - mEigenValueArray[1] = -2; - mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.15123975969, 6, 0.000001)); - - /* Perfect Joint */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1000; - mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); - - /* Perfect Joint; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = 1000; - mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); - - /* Perfect Bone */ - functor.SetEnhanceBrightObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = -1000; - mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); - - /* Perfect Bone; dark sheets */ - functor.SetEnhanceDarkObjects(); - mEigenValueArray[0] = 0; - mEigenValueArray[1] = -1000; - mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx deleted file mode 100644 index e16178cab7a..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx +++ /dev/null @@ -1,43 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" -#include "itkTestingMacros.h" - -int -itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) -{ - constexpr unsigned int Dimension = 3; - using InputPixelType = char; - using InputImageType = itk::Image; - - using FilterType = itk::KrcahEigenToScalarPreprocessingImageToImageFilter; - FilterType::Pointer filter = FilterType::New(); - - /* Basic test */ - EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); - - /* Default parameters */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetScalingConstant(), 10.0, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetSigma(), 1.0, 6, 0.000001)); - TEST_EXPECT_TRUE(filter->GetReleaseInternalFilterData()); - - /* TODO: Regression test */ - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap deleted file mode 100644 index d5ce1a5acc1..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,13 +0,0 @@ -itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap deleted file mode 100644 index 4f4a7ee5eb9..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,11 +0,0 @@ -itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap deleted file mode 100644 index 273175aba3b..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ /dev/null @@ -1,22 +0,0 @@ -itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t3}3}") - endforeach() -endforeach() -itk_end_wrap_class() - -itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap deleted file mode 100644 index 588cba91429..00000000000 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap +++ /dev/null @@ -1,3 +0,0 @@ -itk_wrap_class("itk::KrcahEigenToScalarPreprocessingImageToImageFilter" POINTER_WITH_SUPERCLASS) -itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}") -itk_end_wrap_class() From 7324492cbc2d77c4dfaab4c966e11c80e261871a Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 16:56:38 -0700 Subject: [PATCH 087/150] ENH: Move itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 9 +- ...nhancementImageFilterStaticMethodsTest.cxx | 109 ------------ ...cementImageFilterStaticMethodsUnitTest.cxx | 163 ++++++++++++++++++ 3 files changed, 164 insertions(+), 117 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 330740fa631..2bfc4e9a0ea 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -3,7 +3,6 @@ itk_module_test() set( BoneEnhancementTests itkMaximumAbsoluteValueImageFilterTest.cxx - itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx itkHessianGaussianImageFilterTest.cxx ) @@ -16,13 +15,6 @@ itk_add_test( itkMaximumAbsoluteValueImageFilterTest ) -itk_add_test( - NAME itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest - COMMAND - BoneEnhancementTestDriver - itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest -) - itk_add_test( NAME itkHessianGaussianImageFilterTest COMMAND @@ -34,6 +26,7 @@ set( BoneEnhancementUnitTests itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx + itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx deleted file mode 100644 index c4c0914e2e0..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ /dev/null @@ -1,109 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkMultiScaleHessianEnhancementImageFilter.h" -#include "itkArray.h" -#include "itkTestingMacros.h" -#include "itkMath.h" - -int -itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) -{ - constexpr unsigned int Dimension = 2; - using PixelType = int; - using ImageType = itk::Image; - using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; - using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; - - /* Test the two cases of step size zero */ - ArrayType sigmaArray; - bool exceptionCaught = false; - - TRY_EXPECT_EXCEPTION(sigmaArray = - MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); - - TRY_EXPECT_EXCEPTION(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); - - /* Test that we get one when min equals max */ - ArrayType expectedOneSigmaArray; - expectedOneSigmaArray.SetSize(1); - expectedOneSigmaArray.SetElement(0, 1); - - /* Test the two cases of min equals max with a large number of values */ - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); - sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); - - /* Test the Logarithmic method */ - ArrayType expectedLogarithmicArray; - expectedLogarithmicArray.SetSize(5); - expectedLogarithmicArray.SetElement(0, 1); - expectedLogarithmicArray.SetElement(1, 1.4953487812212205); - expectedLogarithmicArray.SetElement(2, 2.23606797749979); - expectedLogarithmicArray.SetElement(3, 3.3437015248821096); - expectedLogarithmicArray.SetElement(4, 5); - - ArrayType logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); - /* Here we need to do some floating point comparisons */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); - } - - logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); - /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); - } - - /* Test the Equidistance method */ - ArrayType expectedEquidistanceArray; - expectedEquidistanceArray.SetSize(5); - expectedEquidistanceArray.SetElement(0, 1.0); - expectedEquidistanceArray.SetElement(1, 2.0); - expectedEquidistanceArray.SetElement(2, 3.0); - expectedEquidistanceArray.SetElement(3, 4.0); - expectedEquidistanceArray.SetElement(4, 5.0); - - ArrayType equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); - /* Here we need to do some floating point comparisons. These are exact, but we should still do a floating point - * comparison to be sure */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( - expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); - } - - equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); - /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) - for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( - expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx new file mode 100644 index 00000000000..206d1f91761 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx @@ -0,0 +1,163 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkMultiScaleHessianEnhancementImageFilter.h" +#include "gtest/gtest.h" +#include "itkMath.h" + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithSizeZero) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + ArrayType sigmaArray; + EXPECT_ANY_THROW(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); + EXPECT_ANY_THROW(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithMinEqualMax) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Test that we get one when min equals max */ + ArrayType expectedOneSigmaArray; + expectedOneSigmaArray.SetSize(1); + expectedOneSigmaArray.SetElement(0, 1); + + /* Test the two cases of min equals max with a large number of values */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); + EXPECT_EQ(expectedOneSigmaArray, sigmaArray); + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); + EXPECT_EQ(expectedOneSigmaArray, sigmaArray); +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArray) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 2); + expectedArray.SetElement(2, 3); + expectedArray.SetElement(3, 4); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArrayWithFlip) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 2); + expectedArray.SetElement(2, 3); + expectedArray.SetElement(3, 4); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArray) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 1.4953487812212205); + expectedArray.SetElement(2, 2.23606797749979); + expectedArray.SetElement(3, 3.3437015248821096); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} + +TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArrayWithFlip) +{ + const unsigned int Dimension = 3; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; + typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + + /* Expected array */ + ArrayType expectedArray; + expectedArray.SetSize(5); + expectedArray.SetElement(0, 1); + expectedArray.SetElement(1, 1.4953487812212205); + expectedArray.SetElement(2, 2.23606797749979); + expectedArray.SetElement(3, 3.3437015248821096); + expectedArray.SetElement(4, 5); + + /* Test */ + ArrayType sigmaArray; + sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); + EXPECT_EQ(expectedArray.GetSize(), sigmaArray.GetSize()); + for (unsigned int i = 0; i < expectedArray.GetSize(); ++i) + { + EXPECT_DOUBLE_EQ(expectedArray.GetElement(i), sigmaArray.GetElement(i)); + } +} From f2357432fc7f4dafbfcd8c4c838a96291d93f535 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 17:07:28 -0700 Subject: [PATCH 088/150] ENH: Move itkMaximumAbsoluteValueImageFilterTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 16 ++------- ...ximumAbsoluteValueImageFilterUnitTest.cxx} | 34 +++++++++---------- 2 files changed, 19 insertions(+), 31 deletions(-) rename Modules/Filtering/BoneEnhancement/test/{itkMaximumAbsoluteValueImageFilterTest.cxx => itkMaximumAbsoluteValueImageFilterUnitTest.cxx} (68%) diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 2bfc4e9a0ea..31ea20400b2 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -1,20 +1,9 @@ itk_module_test() -set( - BoneEnhancementTests - itkMaximumAbsoluteValueImageFilterTest.cxx - itkHessianGaussianImageFilterTest.cxx -) +set(BoneEnhancementTests itkHessianGaussianImageFilterTest.cxx) createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") -itk_add_test( - NAME itkMaximumAbsoluteValueImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkMaximumAbsoluteValueImageFilterTest -) - itk_add_test( NAME itkHessianGaussianImageFilterTest COMMAND @@ -24,9 +13,10 @@ itk_add_test( set( BoneEnhancementUnitTests + itkMaximumAbsoluteValueImageFilterUnitTest.cxx + itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx - itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx similarity index 68% rename from Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx rename to Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx index c42e1ba1b98..ba218333b66 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx @@ -17,24 +17,20 @@ *=========================================================================*/ #include "itkMaximumAbsoluteValueImageFilter.h" -#include "itkTestingMacros.h" +#include "gtest/gtest.h" #include "itkImageRegionIterator.h" -int -itkMaximumAbsoluteValueImageFilterTest(int, char *[]) +TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) { - constexpr unsigned int Dimension = 2; - using PixelType = int; - using ImageType = itk::Image; - using MaximumAbsoluteValueImageFilterType = itk::MaximumAbsoluteValueImageFilter; - MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); + const unsigned int Dimension = 2; + typedef int PixelType; + typedef itk::Image ImageType; + typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; + MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); /** Create an image and run a basic test */ ImageType::RegionType region; ImageType::IndexType start; - start[0] = 0; start[1] = 0; @@ -53,7 +49,12 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) image2->SetRegions(region); image2->Allocate(); +<<<<<<< HEAD:test/itkMaximumAbsoluteValueImageFilterTest.cxx using IteratorType = itk::ImageRegionIterator; +======= + /* Iterate over images and set */ + typedef itk::ImageRegionIterator IteratorType; +>>>>>>> ENH: Move itkMaximumAbsoluteValueImageFilterTest to GTest:test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx IteratorType it1(image1, region); IteratorType it2(image2, region); it1.GoToBegin(); @@ -75,9 +76,10 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) ++it2; } + /* Apply filter */ maxAbsFilter->SetInput1(image1); maxAbsFilter->SetInput2(image2); - maxAbsFilter->Update(); + EXPECT_NO_THROW(maxAbsFilter->Update()); ImageType::Pointer outputImage = maxAbsFilter->GetOutput(); IteratorType ot(outputImage, region); @@ -87,16 +89,12 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) { if ((i % 2) == 0) { - TEST_EXPECT_EQUAL(ot.Get(), -2); + EXPECT_EQ(ot.Get(), -2); } else { - TEST_EXPECT_EQUAL(ot.Get(), 2); + EXPECT_EQ(ot.Get(), 2); } ++ot; } - - /** TODO: Write an integration test */ - - return EXIT_SUCCESS; } From 6262ab3d40827561620ce8b95a9ef72f7bd16691 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Sat, 3 Mar 2018 17:12:04 -0700 Subject: [PATCH 089/150] ENH: Move itkHessianGaussianImageFilterTest to GTest --- .../BoneEnhancement/test/CMakeLists.txt | 16 +++++------ ...itkHessianGaussianImageFilterUnitTest.cxx} | 28 ++++++------------- 2 files changed, 17 insertions(+), 27 deletions(-) rename Modules/Filtering/BoneEnhancement/test/{itkHessianGaussianImageFilterTest.cxx => itkHessianGaussianImageFilterUnitTest.cxx} (61%) diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 31ea20400b2..6d723fe1718 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -1,19 +1,19 @@ itk_module_test() -set(BoneEnhancementTests itkHessianGaussianImageFilterTest.cxx) +# set(BoneEnhancementTests +# itkHessianGaussianImageFilterTest.cxx +# ) -createtestdriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") +# CreateTestDriver(BoneEnhancement "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementTests}") -itk_add_test( - NAME itkHessianGaussianImageFilterTest - COMMAND - BoneEnhancementTestDriver - itkHessianGaussianImageFilterTest -) +# itk_add_test(NAME itkHessianGaussianImageFilterTest +# COMMAND BoneEnhancementTestDriver itkHessianGaussianImageFilterTest +# ) set( BoneEnhancementUnitTests itkMaximumAbsoluteValueImageFilterUnitTest.cxx + itkHessianGaussianImageFilterUnitTest.cxx itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx similarity index 61% rename from Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx rename to Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx index 186ab1f10cf..4563e8203d4 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx @@ -17,36 +17,26 @@ *=========================================================================*/ #include "itkHessianGaussianImageFilter.h" -#include "itkUnaryFunctorImageFilter.h" -#include "itkTestingMacros.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkMath.h" +#include "gtest/gtest.h" -int -itkHessianGaussianImageFilterTest(int argc, char * argv[]) +TEST(itkHessianGaussianImageFilterTest, ExerciseBasicMethods) { const unsigned int Dimension = 2; typedef int PixelType; typedef itk::Image ImageType; typedef itk::HessianGaussianImageFilter HessianGaussianImageFilterType; - - HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); - - /* Basic tests. */ - EXERCISE_BASIC_OBJECT_METHODS(hess_filter, HessianGaussianImageFilter, ImageToImageFilter); + HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); /* Exercise basic set/get methods */ - TEST_SET_GET_VALUE(1.0, hess_filter->GetSigma()); + EXPECT_EQ(1.0, hess_filter->GetSigma()) << "Initial value of Sigma should be 1"; hess_filter->SetSigma(0.5); - TEST_SET_GET_VALUE(0.5, hess_filter->GetSigma()); + EXPECT_EQ(0.5, hess_filter->GetSigma()); - TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(false, hess_filter->GetNormalizeAcrossScale()) << "Initial value of NormalizeAcrossScale should be false"; hess_filter->SetNormalizeAcrossScale(true); - TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(true, hess_filter->GetNormalizeAcrossScale()); hess_filter->NormalizeAcrossScaleOff(); - TEST_SET_GET_VALUE(false, hess_filter->GetNormalizeAcrossScale()); + EXPECT_EQ(false, hess_filter->GetNormalizeAcrossScale()); hess_filter->NormalizeAcrossScaleOn(); - TEST_SET_GET_VALUE(true, hess_filter->GetNormalizeAcrossScale()); - - return EXIT_SUCCESS; + EXPECT_EQ(true, hess_filter->GetNormalizeAcrossScale()); } From b898f6c52a51055391a410f9e68749738e781333 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Thu, 18 Oct 2018 13:52:32 -0600 Subject: [PATCH 090/150] ENH: Update Descoteaux filter to ITKv5 DynamicThreadedGenerateData --- .../itkDescoteauxEigenToMeasureImageFilter.h | 2 +- ...itkDescoteauxEigenToMeasureImageFilter.hxx | 8 +--- ...xEigenToMeasureParameterEstimationFilter.h | 9 ++-- ...igenToMeasureParameterEstimationFilter.hxx | 45 +++++-------------- 4 files changed, 21 insertions(+), 43 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index 04d79a467c3..95d05d92d91 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -125,7 +125,7 @@ class DescoteauxEigenToMeasureImageFilter /** Multi-thread version GenerateData. */ void - ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) ITK_OVERRIDE; + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index ff7239d8941..686422d4480 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -35,9 +35,8 @@ DescoteauxEigenToMeasureImageFilter void -DescoteauxEigenToMeasureImageFilter::ThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread, - ThreadIdType threadId) +DescoteauxEigenToMeasureImageFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) { /* Get Inputs */ ParameterArrayType parameters = this->GetParametersInput()->Get(); @@ -63,8 +62,6 @@ DescoteauxEigenToMeasureImageFilter inputIt(inputPtr, inputRegionForThread); ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); - inputIt.GoToBegin(); outputIt.GoToBegin(); @@ -81,7 +78,6 @@ DescoteauxEigenToMeasureImageFilter m_MaxFrobeniusNorm; + RealType m_FrobeniusNormWeight; + RealType m_MaxFrobeniusNorm; + + SimpleFastMutexLock m_Mutex; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index 5ef31795fd3..aabbb818bba 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -20,6 +20,7 @@ #define itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx #include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" +#include "itkMutexLockHolder.h" namespace itk { @@ -43,40 +44,23 @@ template void DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { - ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); - - /* Resize threads */ - m_MaxFrobeniusNorm.SetSize(numberOfCalls); - m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); + m_MaxFrobeniusNorm = NumericTraits::NonpositiveMin(); } template void DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { - ThreadIdType numberOfCalls = this->GetNumberOfThreads() * this->GetNumberOfStreamDivisions(); - /* Determine default parameters */ RealType alpha, beta, c; alpha = 0.5f; beta = 0.5f; c = 0.0f; - /* Accumulate over threads */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfCalls; ++i) - { - if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) - { - maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; - } - } - /* Scale c */ - if (maxFrobeniusNorm > 0) + if (m_MaxFrobeniusNorm > 0) { - c = m_FrobeniusNormWeight * maxFrobeniusNorm; + c = m_FrobeniusNormWeight * m_MaxFrobeniusNorm; } /* Assign outputs parameters */ @@ -90,9 +74,8 @@ DescoteauxEigenToMeasureParameterEstimationFilter void -DescoteauxEigenToMeasureParameterEstimationFilter::ThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread, - ThreadIdType threadId) +DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ const SizeValueType size0 = outputRegionForThread.GetSize(0); @@ -101,9 +84,8 @@ DescoteauxEigenToMeasureParameterEstimationFilter::ZeroValue(); - RealType thisFrobeniusNorm; + /* Keep track of the current max */ + RealType max = NumericTraits::NonpositiveMin(); /* Get input and mask pointer */ InputImageConstPointer inputPointer = this->GetInput(); @@ -133,11 +115,7 @@ DescoteauxEigenToMeasureParameterEstimationFilterIsInside(point))) { /* Compute max norm */ - thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); - if (thisFrobeniusNorm > maxFrobeniusNorm) - { - maxFrobeniusNorm = thisFrobeniusNorm; - } + max = std::max(max, this->CalculateFrobeniusNorm(inputIt.Get())); } // Set @@ -148,8 +126,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter mutexHolder(m_Mutex); + m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); } template From 6778e788c4a5f8e227fd4bf5eb5e8003908a8d66 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 19 Oct 2018 16:31:00 -0600 Subject: [PATCH 091/150] ENH: Implement Krcah parameter estimation filter and unit test --- ...hEigenToMeasureParameterEstimationFilter.h | 184 ++++++++++++ ...igenToMeasureParameterEstimationFilter.hxx | 211 +++++++++++++ .../BoneEnhancement/test/CMakeLists.txt | 1 + ...asureParameterEstimationFilterUnitTest.cxx | 278 ++++++++++++++++++ 4 files changed, 674 insertions(+) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx create mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h new file mode 100644 index 00000000000..cf8c8b819c1 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h @@ -0,0 +1,184 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToMeasureParameterEstimationFilter_h +#define itkKrcahEigenToMeasureParameterEstimationFilter_h + +#include "itkMath.h" +#include "itkEigenToMeasureParameterEstimationFilter.h" +#include "itkSimpleFastMutexLock.h" +#include "itkCompensatedSummation.h" + +namespace itk +{ +/** \class KrcahEigenToMeasureParameterEstimationFilter + * \brief Automatic parameter estimation as defined by Krcah et al. + * + * This class takes an image of eigenvalues and estimates the parameters for the Krcah + * bone enhanced filter. According to the original paper, + * \f{eqnarray*}{ + * \alpha &=& 0.5 \\ + * \beta &=& 0.5 \\ + * \gamma &=& 0.25 + * \f} + * + * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. + * The trace of the matrix can be computed directly from the eigenvalues as the sum + * of the eigenvalues. + * + * In this implementation, the average of the trace is moved into the constant + * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary + * functor. The modification is very simple. If the average of the trace is + * denoted \f$ T \f$ the new parameter becomes: + * \f{ + * \gamma &=& 0.25 \cdot T + * \f} + * + * However, the code was implemented different than described in the original + * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum + * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. + * Furthermore, all parameters were scaled by a factor of 2 in the implementation + * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the + * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType + * can be set which enables the implementation parameters: + * \f{eqnarray*}{ + * \alpha &=& \sqrt{2} \cdot 0.5 \\ + * \beta &=& \sqrt{2} \cdot 0.5 \\ + * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T + * \f} + * Default is to use parameters from the implementation, not the paper. + * + * The parameters are estimated over the whole volume unless a mask is given. + * If a mask is given, parameters are evaluated only where IsInside returns + * true. + * + * \sa KrcahEigenToMeasureImageFilter + * \sa EigenToMeasureParameterEstimationFilter + * \sa MultiScaleHessianEnhancementImageFilter + * + * \author: Bryce Besler + * \ingroup BoneEnhancement + */ +template +class KrcahEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter +{ +public: + /** Standard Self typedef */ + typedef KrcahEigenToMeasureParameterEstimationFilter Self; + typedef EigenToMeasureParameterEstimationFilter Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** Input typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::InputImagePointer InputImagePointer; + typedef typename Superclass::InputImageConstPointer InputImageConstPointer; + typedef typename Superclass::InputImageRegionType InputImageRegionType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::PixelValueType PixelValueType; + + /** Output typedefs */ + typedef typename Superclass::OutputImageType OutputImageType; + typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + + /** Input SpatialObject typedefs. */ + typedef typename Superclass::SpatialObjectType SpatialObjectType; + typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + + /** Parameter typedefs */ + typedef typename Superclass::RealType RealType; + typedef typename Superclass::ParameterArrayType ParameterArrayType; + typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(KrcahEigenToMeasureParameterEstimationFilter, EigenToMeasureParameterEstimationFilter); + + typedef enum + { + UseImplementationParameters = 1, + UseJournalParameters + } KrcahImplementationType; + itkSetMacro(ParameterSet, KrcahImplementationType); + itkGetConstMacro(ParameterSet, KrcahImplementationType); + + /* Set parameter set */ + void + SetParameterSetToImplementation() + { + this->SetParameterSet(UseImplementationParameters); + } + + void + SetParameterSetToJournalArticle() + { + this->SetParameterSet(UseJournalParameters); + } + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); + itkConceptMacro(InputFixedArrayHasDimension3Check, (Concept::SameDimension)); + // End concept checking +#endif +protected: + KrcahEigenToMeasureParameterEstimationFilter(); + virtual ~KrcahEigenToMeasureParameterEstimationFilter() {} + + /** Initialize some accumulators before the threads run. */ + void + BeforeThreadedGenerateData() ITK_OVERRIDE; + + /** Do final mean and variance computation from data accumulated in threads. */ + void + AfterThreadedGenerateData() ITK_OVERRIDE; + + /** Multi-thread version GenerateData. */ + void + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; + + /** Calculation of \f$ T \f$ changes depending on the implementation */ + inline RealType + CalculateTraceAccordingToImplementation(InputImagePixelType pixel); + inline RealType + CalculateTraceAccordingToJournalArticle(InputImagePixelType pixel); + + void + PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); + + /* Member variables */ + KrcahImplementationType m_ParameterSet; + CompensatedSummation m_ThreadCount; + CompensatedSummation m_ThreadAccumulatedTrace; + + SimpleFastMutexLock m_Mutex; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahEigenToMeasureParameterEstimationFilter.hxx" +#endif + +#endif /* itkKrcahEigenToMeasureParameterEstimationFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx new file mode 100644 index 00000000000..96b1a04a844 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -0,0 +1,211 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahEigenToMeasureParameterEstimationFilter_hxx +#define itkKrcahEigenToMeasureParameterEstimationFilter_hxx + +#include "itkKrcahEigenToMeasureParameterEstimationFilter.h" +#include "itkMutexLockHolder.h" + +namespace itk +{ + +template +KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() + : m_ParameterSet(UseImplementationParameters) +{ + /* Set parameter size to 3 */ + ParameterArrayType parameters = this->GetParametersOutput()->Get(); + parameters.SetSize(3); + parameters[0] = 0.5; + parameters[1] = 0.5; + parameters[2] = 1; + this->GetParametersOutput()->Set(parameters); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +{ + m_ThreadAccumulatedTrace = NumericTraits::ZeroValue(); + m_ThreadCount = NumericTraits::ZeroValue(); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +{ + /* Determine default parameters */ + RealType alpha, beta, gamma; + switch (m_ParameterSet) + { + case UseImplementationParameters: + alpha = Math::sqrt2 * 0.5f; + beta = Math::sqrt2 * 0.5f; + gamma = Math::sqrt2 * 0.5f; + break; + case UseJournalParameters: + alpha = 0.5f; + beta = 0.5f; + gamma = 0.25f; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Do derived measures */ + const RealType accum(m_ThreadAccumulatedTrace); + const RealType count(m_ThreadCount); + if (count > 0) + { + RealType averageTrace = accum / count; + gamma = gamma * averageTrace; + } + else + { + gamma = NumericTraits::ZeroValue(); + } + + /* Assign outputs parameters */ + ParameterArrayType parameters; + parameters.SetSize(3); + parameters[0] = alpha; + parameters[1] = beta; + parameters[2] = gamma; + this->GetParametersOutput()->Set(parameters); +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) +{ + /* If size is zero, return */ + const SizeValueType size0 = outputRegionForThread.GetSize(0); + if (size0 == 0) + { + return; + } + + /* Determine which function to call */ + RealType (Self::*traceFunction)(InputImagePixelType); + switch (m_ParameterSet) + { + case UseImplementationParameters: + traceFunction = &Self::CalculateTraceAccordingToImplementation; + break; + case UseJournalParameters: + traceFunction = &Self::CalculateTraceAccordingToJournalArticle; + break; + default: + itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); + break; + } + + /* Keep track of the current max */ + RealType accum = NumericTraits::ZeroValue(); + RealType count = NumericTraits::ZeroValue(); + + /* Get input and mask pointer */ + InputImageConstPointer inputPointer = this->GetInput(); + SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + typename InputImageType::PointType point; + + OutputImageType * outputPtr = this->GetOutput(0); + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + /* Iterate and count */ + inputIt.GoToBegin(); + outputIt.GoToBegin(); + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + /* Compute trace */ + count++; + accum += (this->*traceFunction)(inputIt.Get()); + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + /* Block and store */ + MutexLockHolder mutexHolder(m_Mutex); + m_ThreadCount += count; + m_ThreadAccumulatedTrace += accum; +} + +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( + InputImagePixelType pixel) +{ + /* Sum of the absolute value of the eigenvalues */ + RealType trace = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + trace += Math::abs(pixel[i]); + } + return trace; +} + +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( + InputImagePixelType pixel) +{ + /* Sum of the eigenvalues */ + RealType trace = 0; + for (unsigned int i = 0; i < pixel.Length; ++i) + { + trace += pixel[i]; + } + return trace; +} + +template +void +KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "ParameterSet: " << GetParameterSet() << std::endl; +} + +} // namespace itk + +#endif /* itkKrcahEigenToMeasureParameterEstimationFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt index 6d723fe1718..5b72f251ba2 100644 --- a/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/test/CMakeLists.txt @@ -17,6 +17,7 @@ set( itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx + itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx ) creategoogletestdriver(BoneEnhancementUnitTests "${BoneEnhancement-Test_LIBRARIES}" "${BoneEnhancementUnitTests}") diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx new file mode 100644 index 00000000000..4313686abf9 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -0,0 +1,278 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#include "itkGTest.h" +#include "itkKrcahEigenToMeasureParameterEstimationFilter.h" +#include "itkImageMaskSpatialObject.h" +#include "itkImage.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace +{ +template +class itkKrcahEigenToMeasureParameterEstimationFilterUnitTest : public ::testing::Test +{ +public: + /* Useful typedefs */ + static const unsigned int DIMENSION = 3; + typedef T PixelType; + typedef itk::FixedArray EigenValueArrayType; + typedef itk::Image EigenImageType; + typedef itk::ImageMaskSpatialObject SpatialObjectType; + typedef itk::Image MaskImageType; + typedef typename itk::KrcahEigenToMeasureParameterEstimationFilter FilterType; + typedef typename FilterType::Pointer FilterPointerType; + typedef typename FilterType::ParameterArrayType ParameterArrayType; + + itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() + { + /* Instantiate filter */ + m_Filter = FilterType::New(); + + /* Create EigenPixels */ + for (unsigned int i = 0; i < m_OneEigenPixel.Length; ++i) + { + m_OneEigenPixel[i] = 1; + m_ZeroEigenPixel[i] = 0; + m_LargeEigenPixel[i] = 100; + } + + /* Create ImageRegion */ + typename EigenImageType::IndexType start; + start[0] = 0; + start[1] = 0; + start[2] = 0; + + typename EigenImageType::SizeType size; + size[0] = 10; + size[1] = 10; + size[2] = 10; + + m_Region.SetSize(size); + m_Region.SetIndex(start); + + /* Create EigenImage */ + m_OnesEigenImage = EigenImageType::New(); + m_OnesEigenImage->SetRegions(m_Region); + m_OnesEigenImage->Allocate(); + m_OnesEigenImage->FillBuffer(m_OneEigenPixel); + + m_ZerosEigenImage = EigenImageType::New(); + m_ZerosEigenImage->SetRegions(m_Region); + m_ZerosEigenImage->Allocate(); + m_ZerosEigenImage->FillBuffer(m_ZeroEigenPixel); + + m_MaskingEigenImage = EigenImageType::New(); + m_MaskingEigenImage->SetRegions(m_Region); + m_MaskingEigenImage->Allocate(); + m_MaskingEigenImage->FillBuffer(m_OneEigenPixel); + + /* Create MaskImage */ + typename EigenImageType::IndexType maskStart; + maskStart[0] = 2; + maskStart[1] = 2; + maskStart[2] = 2; + + typename EigenImageType::SizeType maskSize; + maskSize[0] = 12; + maskSize[1] = 12; + maskSize[2] = 12; + + typename EigenImageType::RegionType maskRegion; + maskRegion.SetSize(maskSize); + maskRegion.SetIndex(maskStart); + + m_MaskImage = MaskImageType::New(); + m_MaskImage->SetRegions(maskRegion); + m_MaskImage->Allocate(); + m_MaskImage->FillBuffer(0); + + maskRegion.Crop(m_Region); + itk::ImageRegionIteratorWithIndex input(m_MaskingEigenImage, maskRegion); + itk::ImageRegionIteratorWithIndex maskIt(m_MaskImage, maskRegion); + + input.GoToBegin(); + maskIt.GoToBegin(); + while (!input.IsAtEnd()) + { + input.Set(m_LargeEigenPixel); + maskIt.Set(1); + ++input; + ++maskIt; + } + + /* Create Spatial Object */ + m_SpatialObject = SpatialObjectType::New(); + m_SpatialObject->SetImage(m_MaskImage); + } + ~itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() override {} + +protected: + void + SetUp() override + {} + void + TearDown() override + {} + + FilterPointerType m_Filter; + typename MaskImageType::Pointer m_MaskImage; + typename EigenImageType::Pointer m_ZerosEigenImage; + typename EigenImageType::Pointer m_OnesEigenImage; + typename EigenImageType::Pointer m_MaskingEigenImage; + EigenValueArrayType m_OneEigenPixel; + EigenValueArrayType m_ZeroEigenPixel; + EigenValueArrayType m_LargeEigenPixel; + ParameterArrayType m_Parameters; + typename EigenImageType::RegionType m_Region; + typename SpatialObjectType::Pointer m_SpatialObject; +}; +} // namespace + +// Define the templates we would like to test +typedef ::testing::Types TestingLabelTypes; +TYPED_TEST_CASE(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) +{ + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_DOUBLE_EQ(1.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImageImplementation) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[1], 1e-6); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosImageJournalArticle) +{ + this->m_Filter->SetInput(this->m_ZerosEigenImage); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_ZeroEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.5, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.5, this->m_Parameters[1], 1e-6); + EXPECT_DOUBLE_EQ(0.0, this->m_Parameters[2]); +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageImplementation) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.70710678118654757, this->m_Parameters[1], 1e-6); + EXPECT_NEAR(2.12132034356, this->m_Parameters[2], 1e-6); // sqrt(2) * 0.5 * 3 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImageJournalArticle) +{ + this->m_Filter->SetInput(this->m_OnesEigenImage); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + typedef itk::FixedArray EigenValueArrayType; + typedef typename itk::Image ImageType; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + + input.GoToBegin(); + while (!input.IsAtEnd()) + { + ASSERT_TRUE(this->m_OneEigenPixel == input.Get()); + ++input; + } + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_NEAR(0.5, this->m_Parameters[0], 1e-6); + EXPECT_NEAR(0.5, this->m_Parameters[1], 1e-6); + EXPECT_NEAR(0.75, this->m_Parameters[2], 1e-6); // 0.25 * 3 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectImplementation) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.70710678118654757, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.70710678118654757, this->m_Parameters[1]); + EXPECT_NEAR(212.132034356, this->m_Parameters[2], 1e-6); // sqrt(2) * 0.5 * 300 +} + +TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectJournalArticle) +{ + this->m_Filter->SetInput(this->m_MaskingEigenImage); + this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetParameterSetToJournalArticle(); + EXPECT_NO_THROW(this->m_Filter->Update()); + EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); + + this->m_Parameters = this->m_Filter->GetParameters(); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[0]); + EXPECT_DOUBLE_EQ(0.5, this->m_Parameters[1]); + EXPECT_NEAR(75.0, this->m_Parameters[2], 1e-6); // 0.25 * 300 +} From e8f796ae9b56048f21e20fe4257176b03cc90a44 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 29 Oct 2018 16:12:40 -0600 Subject: [PATCH 092/150] STYLE: Prefer C++11 type alias over typedef. Prefer C++11 type alias over `typedef` for the reasons stated here: http://review.source.kitware.com/#/c/23103/ --- .../itkDescoteauxEigenToMeasureImageFilter.h | 46 +++++++------- ...xEigenToMeasureParameterEstimationFilter.h | 48 +++++++-------- .../include/itkEigenToMeasureImageFilter.h | 45 +++++++------- ...kEigenToMeasureParameterEstimationFilter.h | 45 +++++++------- .../include/itkHessianGaussianImageFilter.h | 45 +++++++------- .../itkKrcahEigenToMeasureImageFilter.h | 50 ++++++++-------- ...hEigenToMeasureParameterEstimationFilter.h | 48 +++++++-------- ...kMultiScaleHessianEnhancementImageFilter.h | 54 ++++++++--------- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 38 ++++++------ ...asureParameterEstimationFilterUnitTest.cxx | 38 ++++++------ .../itkHessianGaussianImageFilterUnitTest.cxx | 10 ++-- ...asureParameterEstimationFilterUnitTest.cxx | 44 +++++++------- ...aximumAbsoluteValueImageFilterUnitTest.cxx | 10 ++-- ...cementImageFilterStaticMethodsUnitTest.cxx | 60 +++++++++---------- 14 files changed, 289 insertions(+), 292 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index 95d05d92d91..f2d36bc22c5 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -54,33 +54,35 @@ class DescoteauxEigenToMeasureImageFilter : public EigenToMeasureImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); + /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureImageFilter Self; - typedef EigenToMeasureImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = DescoteauxEigenToMeasureImageFilter; + using Superclass = EigenToMeasureImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Input typedefs */ - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - typedef typename Superclass::InputImagePointer InputImagePointer; - typedef typename Superclass::InputImageConstPointer InputImageConstPointer; - typedef typename Superclass::InputImageRegionType InputImageRegionType; + using InputImageType = typename Superclass::InputImageType; + using InputImagePixelType = typename Superclass::InputImagePixelType; + using InputImagePointer = typename Superclass::InputImagePointer; + using InputImageConstPointer = typename Superclass::InputImageConstPointer; + using InputImageRegionType = typename Superclass::InputImageRegionType; /** Output typedefs */ - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename Superclass::OutputImagePointer OutputImagePointer; - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + using OutputImageType = typename Superclass::OutputImageType; + using OutputImagePointer = typename Superclass::OutputImagePointer; + using OutputImageRegionType = typename Superclass::OutputImageRegionType; + using OutputImagePixelType = typename Superclass::OutputImagePixelType; /** Parameter typedefs */ - typedef typename Superclass::RealType RealType; - typedef typename Superclass::ParameterArrayType ParameterArrayType; - typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + using RealType = typename Superclass::RealType; + using ParameterArrayType = typename Superclass::ParameterArrayType; + using ParameterDecoratedType = typename Superclass::ParameterDecoratedType; /** Input SpatialObject typedefs. */ - typedef typename Superclass::SpatialObjectType SpatialObjectType; - typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + using SpatialObjectType = typename Superclass::SpatialObjectType; + using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -90,7 +92,7 @@ class DescoteauxEigenToMeasureImageFilter /** Explicitely state the eigenvalues are ordered by magnitude for this filter */ typename Superclass::EigenValueOrderType - GetEigenValueOrder() const ITK_OVERRIDE + GetEigenValueOrder() const override { return Superclass::OrderByMagnitude; } @@ -125,14 +127,12 @@ class DescoteauxEigenToMeasureImageFilter /** Multi-thread version GenerateData. */ void - DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); - /* Member variables */ RealType m_EnhanceType; }; // end class diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index ed0555a8119..6ad7e1426f0 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -54,33 +54,35 @@ class DescoteauxEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); + /** Standard Self typedef */ - typedef DescoteauxEigenToMeasureParameterEstimationFilter Self; - typedef EigenToMeasureParameterEstimationFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = DescoteauxEigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Input typedefs */ - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::InputImagePointer InputImagePointer; - typedef typename Superclass::InputImageConstPointer InputImageConstPointer; - typedef typename Superclass::InputImageRegionType InputImageRegionType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - typedef typename Superclass::PixelValueType PixelValueType; + using InputImageType = typename Superclass::InputImageType; + using InputImagePointer = typename Superclass::InputImagePointer; + using InputImageConstPointer = typename Superclass::InputImageConstPointer; + using InputImageRegionType = typename Superclass::InputImageRegionType; + using InputImagePixelType = typename Superclass::InputImagePixelType; + using PixelValueType = typename Superclass::PixelValueType; /** Output typedefs */ - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + using OutputImageType = typename Superclass::OutputImageType; + using OutputImageRegionType = typename Superclass::OutputImageRegionType; + using OutputImagePixelType = typename Superclass::OutputImagePixelType; /** Input SpatialObject typedefs. */ - typedef typename Superclass::SpatialObjectType SpatialObjectType; - typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + using SpatialObjectType = typename Superclass::SpatialObjectType; + using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; /** Parameter typedefs */ - typedef typename Superclass::RealType RealType; - typedef typename Superclass::ParameterArrayType ParameterArrayType; - typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + using RealType = typename Superclass::RealType; + using ParameterArrayType = typename Superclass::ParameterArrayType; + using ParameterDecoratedType = typename Superclass::ParameterDecoratedType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -104,25 +106,23 @@ class DescoteauxEigenToMeasureParameterEstimationFilter /** Initialize some accumulators before the threads run. */ void - BeforeThreadedGenerateData() ITK_OVERRIDE; + BeforeThreadedGenerateData() override; /** Do final mean and variance computation from data accumulated in threads. */ void - AfterThreadedGenerateData() ITK_OVERRIDE; + AfterThreadedGenerateData() override; /** Multi-thread version GenerateData. */ void - DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; inline RealType CalculateFrobeniusNorm(const InputImagePixelType & pixel) const; void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); - /* Member variables */ RealType m_FrobeniusNormWeight; RealType m_MaxFrobeniusNorm; diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h index f6508d7cd6c..d30877cc635 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -42,39 +42,41 @@ template { public: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); + /** Standard Self typedef */ - typedef EigenToMeasureImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = EigenToMeasureImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Run-time type information (and related methods). */ itkTypeMacro(EigenToMeasureImageFilter, ImageToImageFilter); /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; - typedef typename InputImagePixelType::ValueType PixelValueType; + using InputImageType = TInputImage; + using InputImagePointer = typename InputImageType::Pointer; + using InputImageConstPointer = typename InputImageType::ConstPointer; + using InputImageRegionType = typename InputImageType::RegionType; + using InputImagePixelType = typename InputImageType::PixelType; + using PixelValueType = typename InputImagePixelType::ValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::Pointer OutputImagePointer; - typedef typename OutputImageType::RegionType OutputImageRegionType; - typedef typename OutputImageType::PixelType OutputImagePixelType; + using OutputImageType = TOutputImage; + using OutputImagePointer = typename OutputImageType::Pointer; + using OutputImageRegionType = typename OutputImageType::RegionType; + using OutputImagePixelType = typename OutputImageType::PixelType; /** Input SpatialObject typedefs. */ - typedef TInputSpatialObject SpatialObjectType; - typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + using SpatialObjectType = TInputSpatialObject; + using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; /** Parameter typedefs. */ - typedef typename NumericTraits::RealType RealType; - typedef RealType ParameterType; - typedef Array ParameterArrayType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; + using RealType = typename NumericTraits::RealType; + using ParameterType = RealType; + using ParameterArrayType = Array; + using ParameterDecoratedType = SimpleDataObjectDecorator; /** Process object */ itkSetGetDecoratedInputMacro(Parameters, ParameterArrayType); @@ -101,9 +103,6 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< protected: EigenToMeasureImageFilter() {}; virtual ~EigenToMeasureImageFilter() {} - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureImageFilter); }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index 019a139f5a2..cf7fe88cadd 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -52,37 +52,39 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter : public StreamingImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); + /** Standard Self typedef */ - typedef EigenToMeasureParameterEstimationFilter Self; - typedef StreamingImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = EigenToMeasureParameterEstimationFilter; + using Superclass = StreamingImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Run-time type information (and related methods). */ itkTypeMacro(EigenToMeasureParameterEstimationFilter, StreamingImageFilter); /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; - typedef typename InputImagePixelType::ValueType PixelValueType; + using InputImageType = TInputImage; + using InputImagePointer = typename InputImageType::Pointer; + using InputImageConstPointer = typename InputImageType::ConstPointer; + using InputImageRegionType = typename InputImageType::RegionType; + using InputImagePixelType = typename InputImageType::PixelType; + using PixelValueType = typename InputImagePixelType::ValueType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ - typedef InputImageType OutputImageType; - typedef InputImageRegionType OutputImageRegionType; + using OutputImageType = TInputImage; + using OutputImageRegionType = typename OutputImageType::RegionType; /** Input SpatialObject typedefs. */ - typedef TInputSpatialObject SpatialObjectType; - typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + using SpatialObjectType = TInputSpatialObject; + using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; /** Parameter typedefs. */ - typedef typename NumericTraits::RealType RealType; - typedef RealType ParameterType; - typedef Array ParameterArrayType; - typedef SimpleDataObjectDecorator ParameterDecoratedType; + using RealType = typename NumericTraits::RealType; + using ParameterType = RealType; + using ParameterArrayType = Array; + using ParameterDecoratedType = SimpleDataObjectDecorator; /** Decorators for parameters so they can be passed as a process object */ ParameterDecoratedType * @@ -107,7 +109,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter * in UpdateOutputData() since it must update a little, execute a little, * update some more, execute some more, etc. */ void - UpdateOutputData(DataObject * output) ITK_OVERRIDE; + UpdateOutputData(DataObject * output) override; /** Static function used as a "callback" by the MultiThreader. The threading * library will call this routine for each thread, which will delegate the @@ -125,10 +127,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter virtual ~EigenToMeasureParameterEstimationFilter() {} void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); + PrintSelf(std::ostream & os, Indent indent) const override; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h index fb105a8b4f5..985a07112bd 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h @@ -54,16 +54,18 @@ template { public: + ITK_DISALLOW_COPY_AND_ASSIGN(HessianGaussianImageFilter); + /** Standard Self typedef */ - typedef HessianGaussianImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = HessianGaussianImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Pixel Type of the input image */ - typedef TInputImage InputImageType; - typedef typename TInputImage::PixelType PixelType; - typedef typename NumericTraits::RealType RealType; + using InputImageType = TInputImage; + using PixelType = typename TInputImage::PixelType; + using RealType = typename NumericTraits::RealType; /** Image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); @@ -71,30 +73,29 @@ class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter /** Define the image type for internal computations RealType is usually 'double' in NumericTraits. Here we prefer float in order to save memory. */ - typedef float InternalRealType; - typedef Image RealImageType; + using InternalRealType = float; + using RealImageType = Image; /** Output Image Nth Element Adaptor * This adaptor allows to use conventional scalar * smoothing filters to compute each one of the * components of the gradient image pixels. */ - typedef NthElementImageAdaptor OutputImageAdaptorType; - - typedef typename OutputImageAdaptorType::Pointer OutputImageAdaptorPointer; + using OutputImageAdaptorType = NthElementImageAdaptor; + using OutputImageAdaptorPointer = typename OutputImageAdaptorType::Pointer; /** Derivative filter type */ - typedef DiscreteGaussianDerivativeImageFilter DerivativeFilterType; + using DerivativeFilterType = DiscreteGaussianDerivativeImageFilter; /** Pointer to a gaussian filter. */ - typedef typename DerivativeFilterType::Pointer DerivativeFilterPointer; + using DerivativeFilterPointer = typename DerivativeFilterType::Pointer; /** Pointer to the Output Image */ - typedef typename TOutputImage::Pointer OutputImagePointer; + using OutputImagePointer = typename TOutputImage::Pointer; /** Type of the output Image */ - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::PixelType OutputPixelType; - typedef typename PixelTraits::ValueType OutputComponentType; + using OutputImageType = TOutputImage; + using OutputPixelType = typename OutputImageType::PixelType; + using OutputComponentType = typename PixelTraits::ValueType; /** Run-time type information (and related methods). */ itkTypeMacro(HessianGaussianImageFilter, ImageToImageFilter); @@ -124,7 +125,7 @@ class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter * \sa DiscreteGaussianDerivativeImageFilter::GenerateInputRequestedRegion() */ // TODO virtual void - GenerateInputRequestedRegion() throw (InvalidRequestedRegionError)ITK_OVERRIDE; + GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) override; #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ @@ -137,15 +138,13 @@ class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter HessianGaussianImageFilter(); virtual ~HessianGaussianImageFilter() {} void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; /** Generate Data */ void - GenerateData(void) ITK_OVERRIDE; + GenerateData(void) override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(HessianGaussianImageFilter); - /** Internal filters **/ DerivativeFilterPointer m_DerivativeFilter; OutputImageAdaptorPointer m_ImageAdaptor; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h index 563fe0c235e..b0c9d37d8ac 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h @@ -51,7 +51,7 @@ class KrcahEigenToMeasureFunctor { public: /* Basic type definitions */ - typedef typename NumericTraits::RealType RealType; + using RealType = typename NumericTraits::RealType; KrcahEigenToMeasureFunctor() : m_Direction(-1.0) @@ -168,36 +168,38 @@ class KrcahEigenToMeasureFunctor template class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter { + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureImageFilter); + /** Standard Self typedef */ - typedef KrcahEigenToMeasureImageFilter Self; - typedef EigenToMeasureImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = KrcahEigenToMeasureImageFilter; + using Superclass = EigenToMeasureImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Input typedefs */ - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - typedef typename Superclass::InputImagePointer InputImagePointer; - typedef typename Superclass::InputImageConstPointer InputImageConstPointer; - typedef typename Superclass::InputImageRegionType InputImageRegionType; + using InputImageType = typename Superclass::InputImageType; + using InputImagePixelType = typename Superclass::InputImagePixelType; + using InputImagePointer = typename Superclass::InputImagePointer; + using InputImageConstPointer = typename Superclass::InputImageConstPointer; + using InputImageRegionType = typename Superclass::InputImageRegionType; /** Output typedefs */ - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename Superclass::OutputImagePointer OutputImagePointer; - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + using OutputImageType = typename Superclass::OutputImageType; + using OutputImagePointer = typename Superclass::OutputImagePointer; + using OutputImageRegionType = typename Superclass::OutputImageRegionType; + using OutputImagePixelType = typename Superclass::OutputImagePixelType; /** Parameter typedefs */ - typedef typename Superclass::RealType RealType; - typedef typename Superclass::ParameterArrayType ParameterArrayType; - typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + using RealType = typename Superclass::RealType; + using ParameterArrayType = typename Superclass::ParameterArrayType; + using ParameterDecoratedType = typename Superclass::ParameterDecoratedType; /** Input SpatialObject typedefs. */ - typedef typename Superclass::SpatialObjectType SpatialObjectType; - typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + using SpatialObjectType = typename Superclass::SpatialObjectType; + using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; /** Functor typedefs. */ - typedef typename Functor::KrcahEigenToMeasureFunctor FunctorType; + using FunctorType = typename Functor::KrcahEigenToMeasureFunctor; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -207,7 +209,7 @@ class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter { public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); + /** Standard Self typedef */ - typedef KrcahEigenToMeasureParameterEstimationFilter Self; - typedef EigenToMeasureParameterEstimationFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; + using Self = KrcahEigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; /** Input typedefs */ - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::InputImagePointer InputImagePointer; - typedef typename Superclass::InputImageConstPointer InputImageConstPointer; - typedef typename Superclass::InputImageRegionType InputImageRegionType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - typedef typename Superclass::PixelValueType PixelValueType; + using InputImageType = typename Superclass::InputImageType; + using InputImagePointer = typename Superclass::InputImagePointer; + using InputImageConstPointer = typename Superclass::InputImageConstPointer; + using InputImageRegionType = typename Superclass::InputImageRegionType; + using InputImagePixelType = typename Superclass::InputImagePixelType; + using PixelValueType = typename Superclass::PixelValueType; /** Output typedefs */ - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; + using OutputImageType = typename Superclass::OutputImageType; + using OutputImageRegionType = typename Superclass::OutputImageRegionType; + using OutputImagePixelType = typename Superclass::OutputImagePixelType; /** Input SpatialObject typedefs. */ - typedef typename Superclass::SpatialObjectType SpatialObjectType; - typedef typename Superclass::SpatialObjectConstPointer SpatialObjectConstPointer; + using SpatialObjectType = typename Superclass::SpatialObjectType; + using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; /** Parameter typedefs */ - typedef typename Superclass::RealType RealType; - typedef typename Superclass::ParameterArrayType ParameterArrayType; - typedef typename Superclass::ParameterDecoratedType ParameterDecoratedType; + using RealType = typename Superclass::RealType; + using ParameterArrayType = typename Superclass::ParameterArrayType; + using ParameterDecoratedType = typename Superclass::ParameterDecoratedType; /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -146,15 +148,15 @@ class KrcahEigenToMeasureParameterEstimationFilter /** Initialize some accumulators before the threads run. */ void - BeforeThreadedGenerateData() ITK_OVERRIDE; + BeforeThreadedGenerateData() override; /** Do final mean and variance computation from data accumulated in threads. */ void - AfterThreadedGenerateData() ITK_OVERRIDE; + AfterThreadedGenerateData() override; /** Multi-thread version GenerateData. */ void - DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) ITK_OVERRIDE; + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; /** Calculation of \f$ T \f$ changes depending on the implementation */ inline RealType @@ -163,11 +165,9 @@ class KrcahEigenToMeasureParameterEstimationFilter CalculateTraceAccordingToJournalArticle(InputImagePixelType pixel); void - PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + PrintSelf(std::ostream & os, Indent indent) const override; private: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); - /* Member variables */ KrcahImplementationType m_ParameterSet; CompensatedSummation m_ThreadCount; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 717305433da..0f51107eaaf 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -80,55 +80,55 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image itkTypeMacro(MultiScaleHessianEnhancementImageFilter, ImageToImageFilter); /** Input Image typedefs. */ - typedef TInputImage InputImageType; - typedef typename InputImageType::Pointer InputImagePointer; - typedef typename InputImageType::ConstPointer InputImageConstPointer; - typedef typename InputImageType::RegionType InputImageRegionType; - typedef typename InputImageType::PixelType InputImagePixelType; + using InputImageType = TInputImage; + using InputImagePointer = typename InputImageType::Pointer; + using InputImageConstPointer = typename InputImageType::ConstPointer; + using InputImageRegionType = typename InputImageType::RegionType; + using InputImagePixelType = typename InputImageType::PixelType; itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::Pointer OutputImagePointer; - typedef typename OutputImageType::ConstPointer OutputImageConstPointer; - typedef typename OutputImageType::RegionType OutputImageRegionType; - typedef typename OutputImageType::PixelType OutputImagePixelType; + using OutputImageType = TOutputImage; + using OutputImagePointer = typename OutputImageType::Pointer; + using OutputImageConstPointer = typename OutputImageType::ConstPointer; + using OutputImageRegionType = typename OutputImageType::RegionType; + using OutputImagePixelType = typename OutputImageType::PixelType; /** Mask related typedefs. */ - typedef ImageMaskSpatialObject SpatialObjectType; - typedef typename SpatialObjectType::ConstPointer SpatialObjectConstPointer; + using SpatialObjectType = ImageMaskSpatialObject; + using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; /** Methods to set/get the mask image */ itkSetInputMacro(ImageMask, SpatialObjectType); itkGetInputMacro(ImageMask, SpatialObjectType); /** Hessian related typedefs. */ - // typedef HessianRecursiveGaussianImageFilter< TInputImage > HessianFilterType; - typedef HessianGaussianImageFilter HessianFilterType; - typedef typename HessianFilterType::OutputImageType HessianImageType; - typedef typename HessianImageType::PixelType HessianPixelType; - typedef typename HessianFilterType::InternalRealType InternalRealType; + // using HessianFilterType = HessianRecursiveGaussianImageFilter< TInputImage >; + using HessianFilterType = HessianGaussianImageFilter; + using HessianImageType = typename HessianFilterType::OutputImageType; + using HessianPixelType = typename HessianImageType::PixelType; + using InternalRealType = typename HessianFilterType::InternalRealType; /** Eigenvalue analysis related type alias. The ITK python wrapping usually wraps floating types * and not double types. For this reason, the eigenvalues are of type float. */ - typedef typename NumericTraits::RealType RealType; - typedef typename NumericTraits::FloatType FloatType; - typedef Vector EigenValueArrayType; - typedef Image EigenValueImageType; - typedef SymmetricEigenAnalysisImageFilter EigenAnalysisFilterType; + using RealType = typename NumericTraits::RealType; + using FloatType = typename NumericTraits::FloatType; + using EigenValueArrayType = Vector; + using EigenValueImageType = Image; + using EigenAnalysisFilterType = SymmetricEigenAnalysisImageFilter; /** Maximum over scale related type alias. */ using MaximumAbsoluteValueFilterType = MaximumAbsoluteValueImageFilter; /** Eigenvalue image to measure image related typedefs */ - typedef EigenToMeasureImageFilter EigenToMeasureImageFilterType; - typedef EigenToMeasureParameterEstimationFilter - EigenToMeasureParameterEstimationFilterType; + using EigenToMeasureImageFilterType = EigenToMeasureImageFilter; + using EigenToMeasureParameterEstimationFilterType = + EigenToMeasureParameterEstimationFilter; /** Need some types to determine how to order the eigenvalues */ - typedef typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType InternalEigenValueOrderType; - typedef typename EigenToMeasureImageFilterType::EigenValueOrderType ExternalEigenValueOrderType; + using InternalEigenValueOrderType = typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType; + using ExternalEigenValueOrderType = typename EigenToMeasureImageFilterType::EigenValueOrderType; /** Set/Get the EigenToMeasureImageFilter. */ itkSetObjectMacro(EigenToMeasureImageFilter, EigenToMeasureImageFilterType); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx index b64a9026f93..829c0777333 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -29,18 +29,18 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test { public: /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::Image OutputPixelType; - typedef float EigenPixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenImageType; - typedef itk::ImageMaskSpatialObject SpatialObjectType; - typedef itk::Image MaskImageType; - typedef typename itk::DescoteauxEigenToMeasureImageFilter - FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterArrayType ParameterArrayType; + static const unsigned int DIMENSION = 3; + using PixelType = T; + using OutputPixelType = itk::Image; + using EigenPixelType = float; + using EigenValueArrayType = itk::FixedArray; + using EigenImageType = itk::Image; + using SpatialObjectType = itk::ImageMaskSpatialObject; + using MaskImageType = itk::Image; + using FilterType = + typename itk::DescoteauxEigenToMeasureImageFilter; + using FilterPointerType = typename FilterType::Pointer; + using ParameterArrayType = typename FilterType::ParameterArrayType; itkDescoteauxEigenToMeasureImageFilterUnitTest() { @@ -165,7 +165,7 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +using TestingLabelTypes = ::testing::Types; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, InitialParameters) @@ -187,7 +187,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestZerosImage) EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); @@ -208,7 +208,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelBri EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); @@ -230,7 +230,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestRealEigenPixelDar EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); @@ -251,7 +251,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); @@ -273,7 +273,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestDarkRealEigenPixe EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); @@ -295,7 +295,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef typename itk::Image ImageType; + using ImageType = typename itk::Image; itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); itk::ContinuousIndex point; diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx index 82477c99be6..89a2d50a162 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -29,15 +29,15 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te { public: /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenImageType; - typedef itk::ImageMaskSpatialObject SpatialObjectType; - typedef itk::Image MaskImageType; - typedef typename itk::DescoteauxEigenToMeasureParameterEstimationFilter FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterArrayType ParameterArrayType; + static const unsigned int DIMENSION = 3; + using PixelType = T; + using EigenValueArrayType = itk::FixedArray; + using EigenImageType = itk::Image; + using SpatialObjectType = itk::ImageMaskSpatialObject; + using MaskImageType = itk::Image; + using FilterType = typename itk::DescoteauxEigenToMeasureParameterEstimationFilter; + using FilterPointerType = typename FilterType::Pointer; + using ParameterArrayType = typename FilterType::ParameterArrayType; itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() { @@ -145,7 +145,7 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +using TestingLabelTypes = ::testing::Types; TYPED_TEST_CASE(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) @@ -164,9 +164,9 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestZer EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) @@ -187,9 +187,9 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOne EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) @@ -211,9 +211,9 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOne EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) diff --git a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx index 4563e8203d4..69d0bb99642 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkHessianGaussianImageFilterUnitTest.cxx @@ -21,11 +21,11 @@ TEST(itkHessianGaussianImageFilterTest, ExerciseBasicMethods) { - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::HessianGaussianImageFilter HessianGaussianImageFilterType; - HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); + const unsigned int Dimension = 2; + using PixelType = int; + using ImageType = itk::Image; + using HessianGaussianImageFilterType = itk::HessianGaussianImageFilter; + HessianGaussianImageFilterType::Pointer hess_filter = HessianGaussianImageFilterType::New(); /* Exercise basic set/get methods */ EXPECT_EQ(1.0, hess_filter->GetSigma()) << "Initial value of Sigma should be 1"; diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx index 4313686abf9..36c197732e1 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -29,15 +29,15 @@ class itkKrcahEigenToMeasureParameterEstimationFilterUnitTest : public ::testing { public: /* Useful typedefs */ - static const unsigned int DIMENSION = 3; - typedef T PixelType; - typedef itk::FixedArray EigenValueArrayType; - typedef itk::Image EigenImageType; - typedef itk::ImageMaskSpatialObject SpatialObjectType; - typedef itk::Image MaskImageType; - typedef typename itk::KrcahEigenToMeasureParameterEstimationFilter FilterType; - typedef typename FilterType::Pointer FilterPointerType; - typedef typename FilterType::ParameterArrayType ParameterArrayType; + static const unsigned int DIMENSION = 3; + using PixelType = T; + using EigenValueArrayType = itk::FixedArray; + using EigenImageType = itk::Image; + using SpatialObjectType = itk::ImageMaskSpatialObject; + using MaskImageType = itk::Image; + using FilterType = typename itk::KrcahEigenToMeasureParameterEstimationFilter; + using FilterPointerType = typename FilterType::Pointer; + using ParameterArrayType = typename FilterType::ParameterArrayType; itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() { @@ -145,7 +145,7 @@ class itkKrcahEigenToMeasureParameterEstimationFilterUnitTest : public ::testing } // namespace // Define the templates we would like to test -typedef ::testing::Types TestingLabelTypes; +using TestingLabelTypes = ::testing::Types; TYPED_TEST_CASE(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestingLabelTypes); TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, InitialParameters) @@ -162,9 +162,9 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosIma EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) @@ -186,9 +186,9 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestZerosIma EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) @@ -209,9 +209,9 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImag EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) @@ -233,9 +233,9 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImag EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); - typedef itk::FixedArray EigenValueArrayType; - typedef typename itk::Image ImageType; - itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); + using EigenValueArrayType = itk::FixedArray; + using ImageType = typename itk::Image; + itk::ImageRegionIteratorWithIndex input(this->m_Filter->GetOutput(), this->m_Region); input.GoToBegin(); while (!input.IsAtEnd()) diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx index 2fbe1239327..09f6e994136 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx @@ -22,11 +22,11 @@ TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) { - const unsigned int Dimension = 2; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MaximumAbsoluteValueImageFilter MaximumAbsoluteValueImageFilterType; - MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); + const unsigned int Dimension = 2; + using PixelType = int; + using ImageType = itk::Image; + using MaximumAbsoluteValueImageFilterType = itk::MaximumAbsoluteValueImageFilter; + MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); /** Create an image and run a basic test */ ImageType::RegionType region; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx index 206d1f91761..34f5fde9547 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest.cxx @@ -22,11 +22,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithSizeZero) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; ArrayType sigmaArray; EXPECT_ANY_THROW(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); @@ -35,11 +35,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSi TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSigmaArrayWithMinEqualMax) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Test that we get one when min equals max */ ArrayType expectedOneSigmaArray; @@ -56,11 +56,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateSi TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArray) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Expected array */ ArrayType expectedArray; @@ -83,11 +83,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEq TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEquispacedSigmaArrayWithFlip) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Expected array */ ArrayType expectedArray; @@ -110,11 +110,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateEq TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArray) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Expected array */ ArrayType expectedArray; @@ -137,11 +137,11 @@ TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLo TEST(itkMultiScaleHessianEnhancementImageFilterStaticMethodsUnitTest, GenerateLogarithmicSigmaArrayWithFlip) { - const unsigned int Dimension = 3; - typedef int PixelType; - typedef itk::Image ImageType; - typedef itk::MultiScaleHessianEnhancementImageFilter MultiScaleHessianEnhancementImageFilterType; - typedef MultiScaleHessianEnhancementImageFilterType::SigmaArrayType ArrayType; + const unsigned int Dimension = 3; + using PixelType = int; + using ImageType = itk::Image; + using MultiScaleHessianEnhancementImageFilterType = itk::MultiScaleHessianEnhancementImageFilter; + using ArrayType = MultiScaleHessianEnhancementImageFilterType::SigmaArrayType; /* Expected array */ ArrayType expectedArray; From 92f4698694b9975987077c055434d95652cac571 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Mon, 29 Oct 2018 16:14:17 -0600 Subject: [PATCH 093/150] STYLE: Use "typename" for template parameters --- .../BoneEnhancement/include/itkHessianGaussianImageFilter.hxx | 2 +- .../BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index 7decae47804..b8338b4fc6a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -91,7 +91,7 @@ HessianGaussianImageFilter::GetNormalizeAcrossScale() return m_DerivativeFilter->GetNormalizeAcrossScale(); } -template +template void HessianGaussianImageFilter::GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) { diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h index b0c9d37d8ac..9e1d345c997 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h @@ -46,7 +46,7 @@ namespace Functor * \author: Thomas Fitze * \ingroup BoneEnhancement */ -template +template class KrcahEigenToMeasureFunctor { public: From 53873f006bfb6abcdba094bbbfd3d56c30d07a2f Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 31 Oct 2018 14:57:15 -0600 Subject: [PATCH 094/150] BUG: Fix Krcah implementation Did some basic Krcah implementation fixes. - Copied the KrcahPreprocessingImageToImageFilter - Reimplement computeKrcahBoneEnhancement example - Fix typing on DescoteauxEigenToMeasureImageFilter and KrcahEigenToMeasureImageFilter --- .../itkDescoteauxEigenToMeasureImageFilter.h | 2 +- ...itkDescoteauxEigenToMeasureImageFilter.hxx | 7 +- .../itkKrcahEigenToMeasureImageFilter.h | 141 ++--------------- .../itkKrcahEigenToMeasureImageFilter.hxx | 50 +++++- .../itkKrcahPreprocessingImageToImageFilter.h | 145 ++++++++++++++++++ ...tkKrcahPreprocessingImageToImageFilter.hxx | 117 ++++++++++++++ 6 files changed, 322 insertions(+), 140 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h create mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index f2d36bc22c5..6a0542082b5 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -123,7 +123,7 @@ class DescoteauxEigenToMeasureImageFilter virtual ~DescoteauxEigenToMeasureImageFilter() {} inline OutputImagePixelType - ProcessPixel(const InputImagePixelType & pixel, RealType alpha, RealType beta, RealType c); + ProcessPixel(const InputImagePixelType & pixel, const RealType & alpha, const RealType & beta, const RealType & c); /** Multi-thread version GenerateData. */ void diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index 686422d4480..6d37be1986f 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -22,7 +22,6 @@ #include "itkDescoteauxEigenToMeasureImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" -#include "itkProgressReporter.h" namespace itk { @@ -85,9 +84,9 @@ template ::OutputImagePixelType DescoteauxEigenToMeasureImageFilter::ProcessPixel( const InputImagePixelType & pixel, - RealType alpha, - RealType beta, - RealType c) + const RealType & alpha, + const RealType & beta, + const RealType & c) { double sheetness = 0.0; double a1 = static_cast(pixel[0]); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h index 9e1d345c997..79c47752259 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h @@ -24,10 +24,11 @@ namespace itk { -namespace Functor -{ -/** \class KrcahEigenToMeasureFunctor - * \brief Eigenvalue to measure functor as defined by Krcah et al. +/** \class KrcahEigenToMeasureImageFilter + * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. + * + * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method + * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. * * Computes the following equation for eigenvalues in a three * dimensional fixed array: @@ -41,123 +42,6 @@ namespace Functor * * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. * - * \sa KrcahEigenToMeasureImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToMeasureFunctor -{ -public: - /* Basic type definitions */ - using RealType = typename NumericTraits::RealType; - - KrcahEigenToMeasureFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Avoid divisions by zero (or close to zero) */ - if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) - { - return static_cast(sheetness); - } - - /** - * Compute sheet, noise, and tube like measures. Note that the average trace of the - * Hessian matrix is implicitly included in \f$ \gamma \f$ here. - */ - const double Rsheet = l2 / l3; - const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma - const double Rtube = l1 / (l2 * l3); - - /* Multiply together to get sheetness */ - sheetness = (m_Direction * a3 / l3); - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); - sheetness *= vcl_exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetGamma(const RealType gamma) - { - this->m_Gamma = gamma; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetGamma() const - { - return this->m_Gamma; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_Gamma; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class KrcahEigenToMeasureImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. - * - * The mathematics are defined in KrcahEigenToMeasureFunctor - * - * \sa KrcahEigenToMeasureFunctor * \sa KrcahEigenToMeasureParameterEstimationFilter * \sa EigenToMeasureImageFilter * \sa MultiScaleHessianEnhancementImageFilter @@ -168,6 +52,7 @@ class KrcahEigenToMeasureFunctor template class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter { +public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureImageFilter); /** Standard Self typedef */ @@ -198,9 +83,6 @@ class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter; - /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -239,17 +121,22 @@ class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter:: template void -KrcahEigenToMeasureImageFilter::ThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread, - ThreadIdType threadId) +KrcahEigenToMeasureImageFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) { /* Get Inputs */ ParameterArrayType parameters = this->GetParametersInput()->Get(); @@ -62,8 +60,6 @@ KrcahEigenToMeasureImageFilter:: ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); - inputIt.GoToBegin(); outputIt.GoToBegin(); @@ -72,7 +68,7 @@ KrcahEigenToMeasureImageFilter:: inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); if ((!maskPointer) || (maskPointer->IsInside(point))) { - outputIt.Set(m_Functor(inputIt.Get())); + outputIt.Set(ProcessPixel(inputIt.Get(), parameters[0], parameters[1], parameters[2])); } else { @@ -80,10 +76,48 @@ KrcahEigenToMeasureImageFilter:: } ++inputIt; ++outputIt; - progress.CompletedPixel(); // potential exception thrown here } } +template +typename KrcahEigenToMeasureImageFilter::OutputImagePixelType +KrcahEigenToMeasureImageFilter::ProcessPixel( + const InputImagePixelType & pixel, + const RealType & alpha, + const RealType & beta, + const RealType & gamma) +{ + double sheetness = 0.0; + double a1 = static_cast(pixel[0]); + double a2 = static_cast(pixel[1]); + double a3 = static_cast(pixel[2]); + double l1 = Math::abs(a1); + double l2 = Math::abs(a2); + double l3 = Math::abs(a3); + + /* Avoid divisions by zero (or close to zero) */ + if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) + { + return static_cast(sheetness); + } + + /** + * Compute sheet, noise, and tube like measures. Note that the average trace of the + * Hessian matrix is implicitly included in \f$ \gamma \f$ here. + */ + const double Rsheet = l2 / l3; + const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma + const double Rtube = l1 / (l2 * l3); + + /* Multiply together to get sheetness */ + sheetness = (m_EnhanceType * a3 / l3); + sheetness *= vcl_exp(-(Rsheet * Rsheet) / (alpha * alpha)); + sheetness *= vcl_exp(-(Rtube * Rtube) / (beta * beta)); + sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (gamma * gamma))); + + return static_cast(sheetness); +} + template void KrcahEigenToMeasureImageFilter::PrintSelf(std::ostream & os, diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h new file mode 100644 index 00000000000..270dcab0f20 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h @@ -0,0 +1,145 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahPreprocessingImageToImageFilter_h +#define itkKrcahPreprocessingImageToImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkDiscreteGaussianImageFilter.h" +#include "itkSubtractImageFilter.h" +#include "itkMultiplyImageFilter.h" +#include "itkAddImageFilter.h" + +namespace itk +{ +/** \class KrcahPreprocessingImageToImageFilter + * \brief Perform preprocessing as defined by Krcah et al + * + * This filters performs an unsharp filter as defined by Krcah + * et al. The unsharp filter is defined by: + * \f{ + * J = I+k*(I-(I*G)) + * \f} + * + * Where \f$ k \f$ is a scaling constant set to 5 and the Guassian + * filter has smoothing parameter \f$ s = 1 mm \f$. A user can modify + * these defaults using the appropriate setter methods. + * + * Additionally, this filter provides the ReleaseInternalFilterData + * flag. When this flag is set, the internal filters used to compute + * the unsharp filter will release their data after processing. This + * conserves memory at the expense of computation time if ScalingConstant + * or Sigma are changed. This flag is on by default. + * + * \sa KrcahEigenToScalarImageFilter + * + * \author: Thomas Fitze + * \ingroup BoneEnhancement + */ +template +class ITK_TEMPLATE_EXPORT KrcahPreprocessingImageToImageFilter : public ImageToImageFilter +{ +public: + ITK_DISALLOW_COPY_AND_ASSIGN(KrcahPreprocessingImageToImageFilter); + + /** Standard Self type alias */ + using Self = KrcahPreprocessingImageToImageFilter; + using Superclass = ImageToImageFilter; + using Pointer = SmartPointer; + using ConstPointer = SmartPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(KrcahPreprocessingImageToImageFilter, ImageToImageFilter); + + /** Extract some information from the image types. Dimensionality + * of the two images is assumed to be the same. */ + static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension; + + /** Image related type alias. */ + using PixelType = typename TInputImage::PixelType; + using OutputPixelType = typename TOutputImage::PixelType; + using RealType = typename NumericTraits::RealType; + using OutputPixelValueType = typename NumericTraits::ValueType; + using InputImageConstPointer = typename TInputImage::ConstPointer; + + /** Typedefs for internal filters */ + using GaussianFilterType = DiscreteGaussianImageFilter; + using SubstractFilterType = SubtractImageFilter; + using MultiplyFilterType = MultiplyImageFilter; + using AddFilterType = AddImageFilter; + + /** Flag to release data or not */ + itkSetMacro(ReleaseInternalFilterData, bool); + itkGetConstMacro(ReleaseInternalFilterData, bool); + itkBooleanMacro(ReleaseInternalFilterData); + + /** Flag to release data or not */ + itkSetMacro(Sigma, RealType); + itkGetConstMacro(Sigma, RealType); + + /** Flag to release data or not */ + itkSetMacro(ScalingConstant, RealType); + itkGetConstMacro(ScalingConstant, RealType); + +#ifdef ITK_USE_CONCEPT_CHECKING + // Begin concept checking + itkConceptMacro(InputOutputHaveSamePixelDimensionCheck, + (Concept::SameDimension)); + // End concept checking +#endif +protected: + KrcahPreprocessingImageToImageFilter(); + + /** Single threaded since we are connecting data */ + void + GenerateData() override; + + /** DiscreteGaussianImageFilter needs a larger input requested region + * than the output requested region (larger by the size of the + * Gaussian kernel). As such, DiscreteGaussianImageFilter needs to + * provide an implementation for GenerateInputRequestedRegion() in + * order to inform the pipeline execution model. + * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ + virtual void + GenerateInputRequestedRegion() override; + + void + PrintSelf(std::ostream & os, Indent indent) const override; + +private: + /* Internal member variables */ + RealType m_Sigma; + RealType m_ScalingConstant; + bool m_ReleaseInternalFilterData; + + /* Filter member variables */ + typename GaussianFilterType::Pointer m_GaussianFilter; + typename SubstractFilterType::Pointer m_SubtractFilter; + typename MultiplyFilterType::Pointer m_MultiplyFilter; + typename AddFilterType::Pointer m_AddFilter; +}; // end class +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkKrcahPreprocessingImageToImageFilter.hxx" +#endif + +#endif // itkKrcahPreprocessingImageToImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.hxx new file mode 100644 index 00000000000..e4a61d0dc32 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.hxx @@ -0,0 +1,117 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkKrcahPreprocessingImageToImageFilter_hxx +#define itkKrcahPreprocessingImageToImageFilter_hxx + +#include "itkKrcahPreprocessingImageToImageFilter.h" +#include "itkGaussianOperator.h" +#include "itkMath.h" + +namespace itk +{ +template +KrcahPreprocessingImageToImageFilter::KrcahPreprocessingImageToImageFilter() + : m_Sigma(1.0f) + , m_ScalingConstant(10.0f) + , m_ReleaseInternalFilterData(true) +{ + /* Instantiate all filters */ + m_GaussianFilter = GaussianFilterType::New(); + m_SubtractFilter = SubstractFilterType::New(); + m_MultiplyFilter = MultiplyFilterType::New(); + m_AddFilter = AddFilterType::New(); +} + +template +void +KrcahPreprocessingImageToImageFilter::GenerateInputRequestedRegion() +{ + // Gaussian filter needs expanding around kernel. Since this filter is typically used + // with the Kcrah enhancing filter, we just expand everything. + Superclass::GenerateInputRequestedRegion(); + auto * input = const_cast(this->GetInput()); + if (input) + { + input->SetRequestedRegionToLargestPossibleRegion(); + } +} + +template +void +KrcahPreprocessingImageToImageFilter::GenerateData() +{ + /* Get Input */ + InputImageConstPointer input = this->GetInput(); + + /* I*G */ + m_GaussianFilter->SetInput(input); + m_GaussianFilter->SetVariance(Math::squared_magnitude(this->GetSigma())); + + /* I - I*G */ + m_SubtractFilter->SetInput1(input); + m_SubtractFilter->SetInput2(m_GaussianFilter->GetOutput()); + + /* k(I-(I*G)) */ + m_MultiplyFilter->SetInput(m_SubtractFilter->GetOutput()); + m_MultiplyFilter->SetConstant(this->GetScalingConstant()); + + /* I+k*(I-(I*G)) */ + m_AddFilter->SetInput1(input); + m_AddFilter->SetInput2(m_MultiplyFilter->GetOutput()); + + /* Release data if asked */ + if (this->GetReleaseInternalFilterData()) + { + m_GaussianFilter->ReleaseDataFlagOn(); + m_SubtractFilter->ReleaseDataFlagOn(); + m_MultiplyFilter->ReleaseDataFlagOn(); + m_AddFilter->ReleaseDataFlagOn(); + } + + /* Setup progress reporter */ + ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); + progress->SetMiniPipelineFilter(this); + progress->RegisterInternalFilter(m_GaussianFilter, 0.25f); + progress->RegisterInternalFilter(m_SubtractFilter, 0.25f); + progress->RegisterInternalFilter(m_MultiplyFilter, 0.25f); + progress->RegisterInternalFilter(m_AddFilter, 0.25f); + + /* Graft Output */ + m_AddFilter->GraftOutput(this->GetOutput()); + m_AddFilter->Update(); + this->GraftOutput(m_AddFilter->GetOutput()); +} + +template +void +KrcahPreprocessingImageToImageFilter::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "GaussianFilter: " << m_GaussianFilter.GetPointer() << std::endl; + os << indent << "SubtractFilter: " << m_SubtractFilter.GetPointer() << std::endl; + os << indent << "MultiplyFilter: " << m_MultiplyFilter.GetPointer() << std::endl; + os << indent << "AddFilter: " << m_AddFilter.GetPointer() << std::endl; + os << indent << "Sigma: " << GetSigma() << std::endl; + os << indent << "ScalingConstant: " << GetScalingConstant() << std::endl; + os << indent << "ReleaseInternalFilterData: " << GetReleaseInternalFilterData() << std::endl; +} + +} // namespace itk + +#endif // itkKrcahPreprocessingImageToImageFilter_hxx From 902d4d22a0eaf797cc521c2567300d7bd18b4714 Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Wed, 31 Oct 2018 17:51:57 -0600 Subject: [PATCH 095/150] ENH: Remove SpatialObject parameterization A few things were acheived here: - itkEigenToMeasureImageFilter now explicitly handles the DyanmicThreadedGenerateData logic - SpatialObject in the template was removed --- .../itkDescoteauxEigenToMeasureImageFilter.h | 19 +- ...itkDescoteauxEigenToMeasureImageFilter.hxx | 73 ++---- ...xEigenToMeasureParameterEstimationFilter.h | 13 +- ...igenToMeasureParameterEstimationFilter.hxx | 30 ++- .../include/itkEigenToMeasureImageFilter.h | 25 ++- .../include/itkEigenToMeasureImageFilter.hxx | 71 ++++++ ...kEigenToMeasureParameterEstimationFilter.h | 25 +-- ...igenToMeasureParameterEstimationFilter.hxx | 99 ++------- .../itkKrcahEigenToMeasureImageFilter.h | 21 +- .../itkKrcahEigenToMeasureImageFilter.hxx | 69 ++---- ...hEigenToMeasureParameterEstimationFilter.h | 13 +- ...igenToMeasureParameterEstimationFilter.hxx | 36 ++- ...kMultiScaleHessianEnhancementImageFilter.h | 15 +- ...ultiScaleHessianEnhancementImageFilter.hxx | 10 +- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 8 +- ...asureParameterEstimationFilterUnitTest.cxx | 6 +- ...asureParameterEstimationFilterUnitTest.cxx | 8 +- ...cahEigenToScalarFunctorImageFilterTest.cxx | 122 ---------- .../itkKrcahEigenToScalarImageFilterTest.cxx | 95 -------- ...alarParameterEstimationImageFilterTest.cxx | 209 ------------------ 20 files changed, 226 insertions(+), 741 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx delete mode 100644 Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index 6a0542082b5..2550d1014ae 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -49,16 +49,15 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class DescoteauxEigenToMeasureImageFilter - : public EigenToMeasureImageFilter +template +class DescoteauxEigenToMeasureImageFilter : public EigenToMeasureImageFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureImageFilter); /** Standard Self typedef */ using Self = DescoteauxEigenToMeasureImageFilter; - using Superclass = EigenToMeasureImageFilter; + using Superclass = EigenToMeasureImageFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -80,10 +79,6 @@ class DescoteauxEigenToMeasureImageFilter using ParameterArrayType = typename Superclass::ParameterArrayType; using ParameterDecoratedType = typename Superclass::ParameterDecoratedType; - /** Input SpatialObject typedefs. */ - using SpatialObjectType = typename Superclass::SpatialObjectType; - using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; - /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -122,12 +117,12 @@ class DescoteauxEigenToMeasureImageFilter DescoteauxEigenToMeasureImageFilter(); virtual ~DescoteauxEigenToMeasureImageFilter() {} - inline OutputImagePixelType - ProcessPixel(const InputImagePixelType & pixel, const RealType & alpha, const RealType & beta, const RealType & c); + OutputImagePixelType + ProcessPixel(const InputImagePixelType & pixel) override; - /** Multi-thread version GenerateData. */ + /** Check the input has the right number of parameters. */ void - DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; + BeforeThreadedGenerateData() override; void PrintSelf(std::ostream & os, Indent indent) const override; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index 6d37be1986f..621d6db72ba 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -25,69 +25,33 @@ namespace itk { -template -DescoteauxEigenToMeasureImageFilter:: - DescoteauxEigenToMeasureImageFilter() - : Superclass() - , m_EnhanceType(-1.0) +template +DescoteauxEigenToMeasureImageFilter::DescoteauxEigenToMeasureImageFilter() + : m_EnhanceType(-1.0) {} -template +template void -DescoteauxEigenToMeasureImageFilter::DynamicThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread) +DescoteauxEigenToMeasureImageFilter::BeforeThreadedGenerateData() { - /* Get Inputs */ - ParameterArrayType parameters = this->GetParametersInput()->Get(); - InputImageConstPointer inputPtr = this->GetInput(0); - OutputImagePointer outputPtr = this->GetOutput(0); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); - typename InputImageType::PointType point; - - /* Test parameters */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); if (parameters.GetSize() != 3) { itkExceptionMacro(<< "Parameters must have size 3. Given array of size " << parameters.GetSize()); } - - // Define the portion of the input to walk for this thread, using - // the CallCopyOutputRegionToInputRegion method allows for the input - // and output images to be different dimensions - InputImageRegionType inputRegionForThread; - - this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); - - // Define the iterators - ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); - ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - - inputIt.GoToBegin(); - outputIt.GoToBegin(); - - while (!inputIt.IsAtEnd()) - { - inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) - { - outputIt.Set(ProcessPixel(inputIt.Get(), parameters[0], parameters[1], parameters[2])); - } - else - { - outputIt.Set(NumericTraits::Zero); - } - ++inputIt; - ++outputIt; - } } -template -typename DescoteauxEigenToMeasureImageFilter::OutputImagePixelType -DescoteauxEigenToMeasureImageFilter::ProcessPixel( - const InputImagePixelType & pixel, - const RealType & alpha, - const RealType & beta, - const RealType & c) +template +typename DescoteauxEigenToMeasureImageFilter::OutputImagePixelType +DescoteauxEigenToMeasureImageFilter::ProcessPixel(const InputImagePixelType & pixel) { + /* Grab parameters */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); + RealType alpha = parameters[0]; + RealType beta = parameters[1]; + RealType c = parameters[2]; + + /* Grab pixel values */ double sheetness = 0.0; double a1 = static_cast(pixel[0]); double a2 = static_cast(pixel[1]); @@ -122,10 +86,9 @@ DescoteauxEigenToMeasureImageFilter(sheetness); } -template +template void -DescoteauxEigenToMeasureImageFilter::PrintSelf(std::ostream & os, - Indent indent) const +DescoteauxEigenToMeasureImageFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Direction: " << GetEnhanceType() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index 6ad7e1426f0..b57a4d59c52 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -49,16 +49,15 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class DescoteauxEigenToMeasureParameterEstimationFilter - : public EigenToMeasureParameterEstimationFilter +template +class DescoteauxEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); /** Standard Self typedef */ using Self = DescoteauxEigenToMeasureParameterEstimationFilter; - using Superclass = EigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -75,9 +74,9 @@ class DescoteauxEigenToMeasureParameterEstimationFilter using OutputImageRegionType = typename Superclass::OutputImageRegionType; using OutputImagePixelType = typename Superclass::OutputImagePixelType; - /** Input SpatialObject typedefs. */ - using SpatialObjectType = typename Superclass::SpatialObjectType; - using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; + /** Input Mask typedefs. */ + using MaskSpatialObjectType = typename Superclass::MaskSpatialObjectType; + using MaskSpatialObjectTypeConstPointer = typename Superclass::MaskSpatialObjectTypeConstPointer; /** Parameter typedefs */ using RealType = typename Superclass::RealType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index aabbb818bba..ee599603e23 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -25,9 +25,8 @@ namespace itk { -template -DescoteauxEigenToMeasureParameterEstimationFilter:: - DescoteauxEigenToMeasureParameterEstimationFilter() +template +DescoteauxEigenToMeasureParameterEstimationFilter::DescoteauxEigenToMeasureParameterEstimationFilter() : Superclass() , m_FrobeniusNormWeight(0.5) { @@ -40,16 +39,16 @@ DescoteauxEigenToMeasureParameterEstimationFilterGetParametersOutput()->Set(parameters); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { m_MaxFrobeniusNorm = NumericTraits::NonpositiveMin(); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { /* Determine default parameters */ RealType alpha, beta, c; @@ -72,9 +71,9 @@ DescoteauxEigenToMeasureParameterEstimationFilterGetParametersOutput()->Set(parameters); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( +DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ @@ -89,7 +88,7 @@ DescoteauxEigenToMeasureParameterEstimationFilterGetInput(); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); typename InputImageType::PointType point; OutputImageType * outputPtr = this->GetOutput(0); @@ -131,9 +130,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter -typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType -DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( +template +typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType +DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( const InputImagePixelType & pixel) const { /* Forbenius norm is given by the square root of the sum of squares @@ -147,10 +146,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter +template void -DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, - Indent indent) const +DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h index d30877cc635..e6d8ea6bd9f 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.h @@ -20,8 +20,8 @@ #define itkEigenToMeasureImageFilter_h #include "itkImageToImageFilter.h" -#include "itkSpatialObject.h" #include "itkSimpleDataObjectDecorator.h" +#include "itkSpatialObject.h" namespace itk { @@ -38,7 +38,7 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter { public: @@ -68,9 +68,9 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< using OutputImageRegionType = typename OutputImageType::RegionType; using OutputImagePixelType = typename OutputImageType::PixelType; - /** Input SpatialObject typedefs. */ - using SpatialObjectType = TInputSpatialObject; - using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; + /** Input Mask typedefs. */ + using MaskSpatialObjectType = SpatialObject; + using MaskSpatialObjectTypeConstPointer = typename MaskSpatialObjectType::ConstPointer; /** Parameter typedefs. */ using RealType = typename NumericTraits::RealType; @@ -82,8 +82,8 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< itkSetGetDecoratedInputMacro(Parameters, ParameterArrayType); /** Methods to set/get the mask image */ - itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); - itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkSetInputMacro(Mask, MaskSpatialObjectType); + itkGetInputMacro(Mask, MaskSpatialObjectType); /** Template the EigenValueOrderType. Methods that inherit from this class can override this function * to produce a different eigenvalue ordering. Ideally, the enum EigenValueOrderType should come from @@ -103,7 +103,18 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureImageFilter : public ImageToImageFilter< protected: EigenToMeasureImageFilter() {}; virtual ~EigenToMeasureImageFilter() {} + + virtual OutputImagePixelType + ProcessPixel(const InputImagePixelType & pixel) = 0; + + /** Multi-thread version GenerateData. */ + void + DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; }; // end class } // namespace itk +#ifndef ITK_MANUAL_INSTANTIATION +# include "itkEigenToMeasureImageFilter.hxx" +#endif + #endif /* itkEigenToMeasureImageFilter_h */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx new file mode 100644 index 00000000000..4568a504301 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx @@ -0,0 +1,71 @@ +/*========================================================================= + * + * Copyright Insight Software 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 + * + * 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. + * + *=========================================================================*/ + +#ifndef itkEigenToMeasureImageFilter_hxx +#define itkEigenToMeasureImageFilter_hxx + +#include "itkEigenToMeasureImageFilter.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkImageRegionIterator.h" + +namespace itk +{ + +template +void +EigenToMeasureImageFilter::DynamicThreadedGenerateData( + const OutputImageRegionType & outputRegionForThread) +{ + /* Get Inputs */ + InputImageConstPointer inputPtr = this->GetInput(0); + OutputImagePointer outputPtr = this->GetOutput(0); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); + typename InputImageType::PointType point; + + // Define the portion of the input to walk for this thread, using + // the CallCopyOutputRegionToInputRegion method allows for the input + // and output images to be different dimensions + InputImageRegionType inputRegionForThread; + this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); + + // Define the iterators + ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); + ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + + inputIt.GoToBegin(); + outputIt.GoToBegin(); + + while (!inputIt.IsAtEnd()) + { + inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInside(point))) + { + outputIt.Set(ProcessPixel(inputIt.Get())); + } + else + { + outputIt.Set(NumericTraits::Zero); + } + ++inputIt; + ++outputIt; + } +} + +} // namespace itk + +#endif /* itkEigenToMeasureImageFilter_hxx */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index cf7fe88cadd..6a1e05979fa 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -20,8 +20,8 @@ #define itkEigenToMeasureParameterEstimationFilter_h #include "itkStreamingImageFilter.h" -#include "itkSpatialObject.h" #include "itkSimpleDataObjectDecorator.h" +#include "itkSpatialObject.h" namespace itk { @@ -47,7 +47,7 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter : public StreamingImageFilter { @@ -76,9 +76,9 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter using OutputImageType = TInputImage; using OutputImageRegionType = typename OutputImageType::RegionType; - /** Input SpatialObject typedefs. */ - using SpatialObjectType = TInputSpatialObject; - using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; + /** Input Mask typedefs. */ + using MaskSpatialObjectType = SpatialObject; + using MaskSpatialObjectTypeConstPointer = typename MaskSpatialObjectType::ConstPointer; /** Parameter typedefs. */ using RealType = typename NumericTraits::RealType; @@ -100,8 +100,8 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter } /** Methods to set/get the mask image */ - itkSetInputMacro(MaskingSpatialObject, SpatialObjectType); - itkGetInputMacro(MaskingSpatialObject, SpatialObjectType); + itkSetInputMacro(Mask, MaskSpatialObjectType); + itkGetInputMacro(Mask, MaskSpatialObjectType); /** Override UpdateOutputData() from StreamingImageFilter to divide * upstream updates into pieces. This filter does not have a GenerateData() @@ -111,17 +111,6 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter void UpdateOutputData(DataObject * output) override; - /** Static function used as a "callback" by the MultiThreader. The threading - * library will call this routine for each thread, which will delegate the - * control to ThreadedGenerateData(). */ - static ITK_THREAD_RETURN_TYPE - ThreaderCallback(void * arg); - - struct ThreadStruct - { - Pointer Filter; - }; - protected: EigenToMeasureParameterEstimationFilter(); virtual ~EigenToMeasureParameterEstimationFilter() {} diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx index 317219ecbef..f60c8783454 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -29,30 +29,22 @@ namespace itk { -template -EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() +template +EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() { /* Set stream parameters */ this->SetNumberOfStreamDivisions(10); this->SetRegionSplitter(ImageRegionSplitterSlowDimension::New()); - /* We require an input image */ - this->SetNumberOfRequiredInputs(1); - - /* We require an output image and parameters */ - this->SetNumberOfRequiredOutputs(2); - /* Allocate parameterset decorator */ - typename ParameterDecoratedType::Pointer output = ParameterDecoratedType::New(); - ParameterArrayType initialParameters; - output->Set(initialParameters); - this->SetNthOutput(1, output.GetPointer()); + typename ParameterDecoratedType::Pointer output = ParameterDecoratedType::New().GetPointer(); + this->ProcessObject::SetNthOutput(1, output.GetPointer()); + this->GetParametersOutput()->Set(ParameterArrayType()); } -template +template void -EigenToMeasureParameterEstimationFilter::UpdateOutputData( - DataObject * itkNotUsed(output)) +EigenToMeasureParameterEstimationFilter::UpdateOutputData(DataObject * itkNotUsed(output)) { /** Prevent chasing our tail */ if (this->m_Updating) @@ -126,31 +118,9 @@ EigenToMeasureParameterEstimationFilter::Updat inputPtr->PropagateRequestedRegion(); inputPtr->UpdateOutputData(); - // /* Setup a multithreadign process */ - // ThreadStruct str; - // str.Filter = this; - - // // Get the output pointer - // const ImageRegionSplitterBase * splitter = this->GetImageRegionSplitter(); - // const unsigned int validThreads = splitter->GetNumberOfSplits( streamRegion, this->GetNumberOfThreads() ); - - // this->GetMultiThreader()->SetNumberOfThreads( validThreads ); - // this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str); - - // // multithread the execution - // this->GetMultiThreader()->SingleMethodExecute(); - + /* Process this chunk */ this->ThreadedGenerateData(streamRegion, piece); - // copy the result to the proper place in the output. the input - // requested region determined by the RegionSplitter (as opposed - // to what the pipeline might have enlarged it to) is used to - // copy the regions from the input to output - // if (inputPtr != outputPtr) - // { - // ImageAlgorithm::Copy( inputPtr, outputPtr, streamRegion, streamRegion ); - // } - /* Update progress and stream another chunk */ this->UpdateProgress(static_cast(piece) / static_cast(numDivisions)); } @@ -187,60 +157,23 @@ EigenToMeasureParameterEstimationFilter::Updat this->m_Updating = false; } -// Threaded splitter -// template< typename TInputImage, typename TInputSpatialObject > -// ITK_THREAD_RETURN_TYPE -// EigenToMeasureParameterEstimationFilter< TInputImage, TInputSpatialObject > -// ::ThreaderCallback(void *arg) -// { -// ThreadStruct *str; -// ThreadIdType total, threadId, threadCount; - -// threadId = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->ThreadID; -// threadCount = ( (MultiThreader::ThreadInfoStruct *)( arg ) )->NumberOfThreads; - -// str = (ThreadStruct *)( ( (MultiThreader::ThreadInfoStruct *)( arg ) )->UserData ); - -// // execute the actual method with appropriate output region -// // first find out how many pieces extent can be split into. -// typename OutputImageType::RegionType splitRegion; -// total = str->Filter->SplitRequestedRegion(threadId, threadCount, -// splitRegion); -// unsigned int streamNumber = str->Filter->m_CurrentSplit; - -// if ( threadId < total ) -// { -// str->Filter->ThreadedGenerateData(splitRegion, str->Filter->GetNumberOfStreamDivisions()*threadId + -// streamNumber); -// } -// // else -// // { -// // otherwise don't use this thread. Sometimes the threads dont -// // break up very well and it is just as efficient to leave a -// // few threads idle. -// // } - -// return ITK_THREAD_RETURN_VALUE; -// } - -template -typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() { return static_cast(this->ProcessObject::GetOutput(1)); } -template -const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +template +const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() const { return static_cast(this->ProcessObject::GetOutput(1)); } -template +template void -EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, - Indent indent) const +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h index 79c47752259..f1f921f9290 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h @@ -49,15 +49,15 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter +template +class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureImageFilter); /** Standard Self typedef */ using Self = KrcahEigenToMeasureImageFilter; - using Superclass = EigenToMeasureImageFilter; + using Superclass = EigenToMeasureImageFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -79,10 +79,6 @@ class KrcahEigenToMeasureImageFilter : public EigenToMeasureImageFilter -KrcahEigenToMeasureImageFilter::KrcahEigenToMeasureImageFilter() +template +KrcahEigenToMeasureImageFilter::KrcahEigenToMeasureImageFilter() : Superclass() , m_EnhanceType(-1.0f) {} -template +template void -KrcahEigenToMeasureImageFilter::DynamicThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread) +KrcahEigenToMeasureImageFilter::BeforeThreadedGenerateData() { - /* Get Inputs */ - ParameterArrayType parameters = this->GetParametersInput()->Get(); - InputImageConstPointer inputPtr = this->GetInput(0); - OutputImagePointer outputPtr = this->GetOutput(0); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); - typename InputImageType::PointType point; - - /* Set parameters */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); if (parameters.GetSize() != 3) { itkExceptionMacro(<< "Parameters must have size 3. Given array of size " << parameters.GetSize()); } - - // Define the portion of the input to walk for this thread, using - // the CallCopyOutputRegionToInputRegion method allows for the input - // and output images to be different dimensions - InputImageRegionType inputRegionForThread; - - this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); - - // Define the iterators - ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); - ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - - inputIt.GoToBegin(); - outputIt.GoToBegin(); - - while (!inputIt.IsAtEnd()) - { - inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) - { - outputIt.Set(ProcessPixel(inputIt.Get(), parameters[0], parameters[1], parameters[2])); - } - else - { - outputIt.Set(NumericTraits::Zero); - } - ++inputIt; - ++outputIt; - } } -template -typename KrcahEigenToMeasureImageFilter::OutputImagePixelType -KrcahEigenToMeasureImageFilter::ProcessPixel( - const InputImagePixelType & pixel, - const RealType & alpha, - const RealType & beta, - const RealType & gamma) +template +typename KrcahEigenToMeasureImageFilter::OutputImagePixelType +KrcahEigenToMeasureImageFilter::ProcessPixel(const InputImagePixelType & pixel) { + /* Grab parameters */ + ParameterArrayType parameters = this->GetParametersInput()->Get(); + RealType alpha = parameters[0]; + RealType beta = parameters[1]; + RealType gamma = parameters[2]; + + /* Grab pixel values */ double sheetness = 0.0; double a1 = static_cast(pixel[0]); double a2 = static_cast(pixel[1]); @@ -118,10 +84,9 @@ KrcahEigenToMeasureImageFilter:: return static_cast(sheetness); } -template +template void -KrcahEigenToMeasureImageFilter::PrintSelf(std::ostream & os, - Indent indent) const +KrcahEigenToMeasureImageFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Direction: " << GetEnhanceType() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h index 95ed1bcc3b0..400a6c4603b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h @@ -74,16 +74,15 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class KrcahEigenToMeasureParameterEstimationFilter - : public EigenToMeasureParameterEstimationFilter +template +class KrcahEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); /** Standard Self typedef */ using Self = KrcahEigenToMeasureParameterEstimationFilter; - using Superclass = EigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -100,9 +99,9 @@ class KrcahEigenToMeasureParameterEstimationFilter using OutputImageRegionType = typename Superclass::OutputImageRegionType; using OutputImagePixelType = typename Superclass::OutputImagePixelType; - /** Input SpatialObject typedefs. */ - using SpatialObjectType = typename Superclass::SpatialObjectType; - using SpatialObjectConstPointer = typename Superclass::SpatialObjectConstPointer; + /** Input Mask typedefs. */ + using MaskSpatialObjectType = typename Superclass::MaskSpatialObjectType; + using MaskSpatialObjectTypeConstPointer = typename Superclass::MaskSpatialObjectTypeConstPointer; /** Parameter typedefs */ using RealType = typename Superclass::RealType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx index 96b1a04a844..f1b8bc0ad6d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -25,9 +25,8 @@ namespace itk { -template -KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() +template +KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() : m_ParameterSet(UseImplementationParameters) { /* Set parameter size to 3 */ @@ -39,17 +38,17 @@ KrcahEigenToMeasureParameterEstimationFilterGetParametersOutput()->Set(parameters); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { m_ThreadAccumulatedTrace = NumericTraits::ZeroValue(); m_ThreadCount = NumericTraits::ZeroValue(); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { /* Determine default parameters */ RealType alpha, beta, gamma; @@ -92,9 +91,9 @@ KrcahEigenToMeasureParameterEstimationFilter:: this->GetParametersOutput()->Set(parameters); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( +KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ @@ -125,7 +124,7 @@ KrcahEigenToMeasureParameterEstimationFilter:: /* Get input and mask pointer */ InputImageConstPointer inputPointer = this->GetInput(); - SpatialObjectConstPointer maskPointer = this->GetMaskingSpatialObject(); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); typename InputImageType::PointType point; OutputImageType * outputPtr = this->GetOutput(0); @@ -169,9 +168,9 @@ KrcahEigenToMeasureParameterEstimationFilter:: m_ThreadAccumulatedTrace += accum; } -template -typename KrcahEigenToMeasureParameterEstimationFilter::RealType -KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( InputImagePixelType pixel) { /* Sum of the absolute value of the eigenvalues */ @@ -183,9 +182,9 @@ KrcahEigenToMeasureParameterEstimationFilter:: return trace; } -template -typename KrcahEigenToMeasureParameterEstimationFilter::RealType -KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( InputImagePixelType pixel) { /* Sum of the eigenvalues */ @@ -197,10 +196,9 @@ KrcahEigenToMeasureParameterEstimationFilter:: return trace; } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, - Indent indent) const +KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "ParameterSet: " << GetParameterSet() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h index 0f51107eaaf..00ef8f908c2 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.h @@ -24,7 +24,7 @@ #include "itkMaximumAbsoluteValueImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" -#include "itkImageMaskSpatialObject.h" +#include "itkSpatialObject.h" #include "itkEigenToMeasureImageFilter.h" #include "itkEigenToMeasureParameterEstimationFilter.h" @@ -95,12 +95,12 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image using OutputImagePixelType = typename OutputImageType::PixelType; /** Mask related typedefs. */ - using SpatialObjectType = ImageMaskSpatialObject; - using SpatialObjectConstPointer = typename SpatialObjectType::ConstPointer; + using MaskSpatialObjectType = SpatialObject; + using MaskSpatialObjectTypeConstPointer = typename MaskSpatialObjectType::ConstPointer; /** Methods to set/get the mask image */ - itkSetInputMacro(ImageMask, SpatialObjectType); - itkGetInputMacro(ImageMask, SpatialObjectType); + itkSetInputMacro(ImageMask, MaskSpatialObjectType); + itkGetInputMacro(ImageMask, MaskSpatialObjectType); /** Hessian related typedefs. */ // using HessianFilterType = HessianRecursiveGaussianImageFilter< TInputImage >; @@ -122,9 +122,8 @@ class ITK_TEMPLATE_EXPORT MultiScaleHessianEnhancementImageFilter : public Image using MaximumAbsoluteValueFilterType = MaximumAbsoluteValueImageFilter; /** Eigenvalue image to measure image related typedefs */ - using EigenToMeasureImageFilterType = EigenToMeasureImageFilter; - using EigenToMeasureParameterEstimationFilterType = - EigenToMeasureParameterEstimationFilter; + using EigenToMeasureImageFilterType = EigenToMeasureImageFilter; + using EigenToMeasureParameterEstimationFilterType = EigenToMeasureParameterEstimationFilter; /** Need some types to determine how to order the eigenvalues */ using InternalEigenValueOrderType = typename EigenAnalysisFilterType::FunctorType::EigenValueOrderType; diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 7077fc9845d..cd51342578e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -132,11 +132,11 @@ MultiScaleHessianEnhancementImageFilter::GenerateData m_EigenToMeasureImageFilter->SetParametersInput(m_EigenToMeasureParameterEstimationFilter->GetParametersOutput()); /* Set the mask */ - SpatialObjectConstPointer mask = this->GetImageMask(); + MaskSpatialObjectTypeConstPointer mask = this->GetImageMask(); if (mask) { - m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); - m_EigenToMeasureParameterEstimationFilter->SetMaskingSpatialObject(mask); + m_EigenToMeasureParameterEstimationFilter->SetMask(mask); + m_EigenToMeasureParameterEstimationFilter->SetMask(mask); } /* After executing we want to release data to save memory */ @@ -237,7 +237,7 @@ MultiScaleHessianEnhancementImageFilter::GetOutputReg region = inputPtr->GetLargestPossibleRegion(); /* Grab the mask pointer */ - SpatialObjectConstPointer mask = this->GetImageMask(); + MaskSpatialObjectTypeConstPointer mask = this->GetImageMask(); if (!mask) { // No mask was set so we need to estimate parameters across the whole image @@ -245,7 +245,7 @@ MultiScaleHessianEnhancementImageFilter::GetOutputReg } /* Crop the region */ - typename SpatialObjectType::RegionType maskRegion = mask->GetAxisAlignedBoundingBoxRegion(); + typename MaskSpatialObjectType::RegionType maskRegion = mask->GetAxisAlignedBoundingBoxRegion(); region.Crop(maskRegion); return region; diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx index 829c0777333..058b967b805 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureImageFilterUnitTest.cxx @@ -35,12 +35,11 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test using EigenPixelType = float; using EigenValueArrayType = itk::FixedArray; using EigenImageType = itk::Image; - using SpatialObjectType = itk::ImageMaskSpatialObject; using MaskImageType = itk::Image; - using FilterType = - typename itk::DescoteauxEigenToMeasureImageFilter; + using FilterType = typename itk::DescoteauxEigenToMeasureImageFilter; using FilterPointerType = typename FilterType::Pointer; using ParameterArrayType = typename FilterType::ParameterArrayType; + using SpatialObjectType = itk::ImageMaskSpatialObject; itkDescoteauxEigenToMeasureImageFilterUnitTest() { @@ -132,7 +131,6 @@ class itkDescoteauxEigenToMeasureImageFilterUnitTest : public ::testing::Test ++maskIt; } - /* Create Spatial Object */ m_SpatialObject = SpatialObjectType::New(); m_SpatialObject->SetImage(m_MaskImage); } @@ -291,7 +289,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureImageFilterUnitTest, TestWithSpatialObject this->m_Parameters[2] = 0.25; this->m_Filter->SetParameters(this->m_Parameters); this->m_Filter->SetInput(this->m_NonZeroEigenImage); - this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetMask(this->m_SpatialObject); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx index 89a2d50a162..e8c314dd239 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -33,11 +33,11 @@ class itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest : public ::te using PixelType = T; using EigenValueArrayType = itk::FixedArray; using EigenImageType = itk::Image; - using SpatialObjectType = itk::ImageMaskSpatialObject; using MaskImageType = itk::Image; - using FilterType = typename itk::DescoteauxEigenToMeasureParameterEstimationFilter; + using FilterType = typename itk::DescoteauxEigenToMeasureParameterEstimationFilter; using FilterPointerType = typename FilterType::Pointer; using ParameterArrayType = typename FilterType::ParameterArrayType; + using SpatialObjectType = itk::ImageMaskSpatialObject; itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest() { @@ -231,7 +231,7 @@ TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestOne TYPED_TEST(itkDescoteauxEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObject) { this->m_Filter->SetInput(this->m_MaskingEigenImage); - this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetMask(this->m_SpatialObject); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx index 36c197732e1..81b655df0d4 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToMeasureParameterEstimationFilterUnitTest.cxx @@ -33,11 +33,11 @@ class itkKrcahEigenToMeasureParameterEstimationFilterUnitTest : public ::testing using PixelType = T; using EigenValueArrayType = itk::FixedArray; using EigenImageType = itk::Image; - using SpatialObjectType = itk::ImageMaskSpatialObject; using MaskImageType = itk::Image; - using FilterType = typename itk::KrcahEigenToMeasureParameterEstimationFilter; + using FilterType = typename itk::KrcahEigenToMeasureParameterEstimationFilter; using FilterPointerType = typename FilterType::Pointer; using ParameterArrayType = typename FilterType::ParameterArrayType; + using SpatialObjectType = itk::ImageMaskSpatialObject; itkKrcahEigenToMeasureParameterEstimationFilterUnitTest() { @@ -253,7 +253,7 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestOnesImag TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectImplementation) { this->m_Filter->SetInput(this->m_MaskingEigenImage); - this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetMask(this->m_SpatialObject); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); @@ -266,7 +266,7 @@ TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpat TYPED_TEST(itkKrcahEigenToMeasureParameterEstimationFilterUnitTest, TestWithSpatialObjectJournalArticle) { this->m_Filter->SetInput(this->m_MaskingEigenImage); - this->m_Filter->SetMaskingSpatialObject(this->m_SpatialObject); + this->m_Filter->SetMask(this->m_SpatialObject); this->m_Filter->SetParameterSetToJournalArticle(); EXPECT_NO_THROW(this->m_Filter->Update()); EXPECT_TRUE(this->m_Filter->GetOutput()->GetBufferedRegion() == this->m_Region); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx deleted file mode 100644 index ebc364280de..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx +++ /dev/null @@ -1,122 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarFunctorImageFilter.h" -#include "itkUnaryFunctorImageFilter.h" -#include "itkTestingMacros.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkMath.h" - -int -itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) -{ - /* type alias, instantiate filter */ - constexpr unsigned int Dimension = 3; - using ImagePixelType = double; - using ImageType = itk::Image; - - using EigenValueType = double; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using FilterType = itk::KrcahEigenToScalarFunctorImageFilter; - FilterType::Pointer krcahFilter = FilterType::New(); - - /* Basic tests. Need to set parameters first. */ - krcahFilter->SetAlpha(0.5); - krcahFilter->SetBeta(0.5); - krcahFilter->SetGamma(0.25); - EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /* Exercise basic set/get methods */ - krcahFilter->SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, krcahFilter->GetAlpha()); - krcahFilter->SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, krcahFilter->GetBeta()); - krcahFilter->SetGamma(0.25); - TEST_SET_GET_VALUE(0.25, krcahFilter->GetGamma()); - // Default should be -1 - TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); - krcahFilter->SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, krcahFilter->GetEnhanceType()); - krcahFilter->SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, 0); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - krcahFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); - - itk::ImageRegionIteratorWithIndex input(krcahFilter->GetOutput(), region); - - input.GoToBegin(); - while (!input.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); - ++input; - } - - /* Create some test data which is computable */ - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, -1); - } - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - krcahFilter->SetInput(image2); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); - - itk::ImageRegionIteratorWithIndex input2(krcahFilter->GetOutput(), region); - - input2.GoToBegin(); - while (!input2.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.000335462627903, 6, 0.000001)); - ++input2; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx deleted file mode 100644 index b3f3da41c80..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx +++ /dev/null @@ -1,95 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) -{ - constexpr unsigned int Dimension = 3; - using MaskPixelType = unsigned int; - using MaskType = itk::Image; - - using OutputPixelType = double; - using OutputType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using KrcahEigenToScalarImageFilterType = - itk::KrcahEigenToScalarImageFilter; - - KrcahEigenToScalarImageFilterType::Pointer krcahFilter = KrcahEigenToScalarImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); - - /* Test defaults */ - TEST_EXPECT_EQUAL(krcahFilter->GetEigenValueOrder(), KrcahEigenToScalarImageFilterType::Superclass::OrderByMagnitude); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, -1); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - /* Run with no exceptions */ - krcahFilter->SetParameterSetToImplementation(); - krcahFilter->SetEnhanceBrightObjects(); - krcahFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); - - /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); - - itk::ImageRegionIteratorWithIndex it(krcahFilter->GetOutput(), region); - - it.GoToBegin(); - while (!it.IsAtEnd()) - { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.0158368867121, 6, 0.000001)); - ++it; - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx deleted file mode 100644 index 5786a96aca8..00000000000 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ /dev/null @@ -1,209 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkTestingMacros.h" -#include "itkMath.h" -#include "itkImageRegionIteratorWithIndex.h" - -int -itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) -{ - constexpr unsigned int Dimension = 3; - using MaskPixelType = unsigned int; - using MaskType = itk::Image; - - using EigenValueType = float; - using EigenValueArrayType = itk::FixedArray; - using EigenValueImageType = itk::Image; - - using KrcahEigenToScalarParameterEstimationImageFilterType = - itk::KrcahEigenToScalarParameterEstimationImageFilter; - - KrcahEigenToScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = - KrcahEigenToScalarParameterEstimationImageFilterType::New(); - - EXERCISE_BASIC_OBJECT_METHODS( - krcahParameterEstimator, KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /* Test defaults */ - TEST_EXPECT_EQUAL(krcahParameterEstimator->GetParameterSet(), - KrcahEigenToScalarParameterEstimationImageFilterType::UseImplementationParameters); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGammaOutput()->Get(), 0.5, 6, 0.000001)); - - /* Create some test data which is computable */ - EigenValueArrayType simpleEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - simpleEigenPixel.SetElement(i, -1); - } - - EigenValueImageType::RegionType region; - EigenValueImageType::IndexType start; - start[0] = 0; - start[1] = 0; - start[2] = 0; - - EigenValueImageType::SizeType size; - size[0] = 10; - size[1] = 10; - size[2] = 10; - - region.SetSize(size); - region.SetIndex(start); - - EigenValueImageType::Pointer image = EigenValueImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(simpleEigenPixel); - - EigenValueImageType::Pointer image2 = EigenValueImageType::New(); - image2->SetRegions(region); - image2->Allocate(); - image2->FillBuffer(simpleEigenPixel); - - EigenValueImageType::IndexType maskStart; - maskStart[0] = 2; - maskStart[1] = 2; - maskStart[2] = 2; - - EigenValueImageType::SizeType maskSize; - maskSize[0] = 8; - maskSize[1] = 8; - maskSize[2] = 8; - - MaskPixelType backgroundValue = 1; - MaskPixelType foregroundValue = 2; - MaskType::Pointer mask = MaskType::New(); - mask->SetRegions(region); - mask->Allocate(); - mask->FillBuffer(backgroundValue); - - EigenValueArrayType newEigenPixel; - for (unsigned int i = 0; i < Dimension; ++i) - { - newEigenPixel.SetElement(i, 3); - } - - EigenValueImageType::RegionType maskRegion; - maskRegion.SetSize(maskSize); - maskRegion.SetIndex(maskStart); - - itk::ImageRegionIteratorWithIndex input2It(image2, maskRegion); - itk::ImageRegionIteratorWithIndex maskIt(mask, maskRegion); - - input2It.GoToBegin(); - maskIt.GoToBegin(); - while (!input2It.IsAtEnd()) - { - input2It.Set(newEigenPixel); - maskIt.Set(foregroundValue); - ++input2It; - ++maskIt; - } - - /* Test an empty pixel value */ - krcahParameterEstimator->SetInput(image); - krcahParameterEstimator->SetParameterSetToImplementation(); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); - - krcahParameterEstimator->SetParameterSetToJournalArticle(); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 0.25, 6, 0.000001)); - - /* Test with a mask */ - krcahParameterEstimator->SetParameterSetToImplementation(); - krcahParameterEstimator->SetInput(image2); - krcahParameterEstimator->SetMaskImage(mask); - krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 3 * 0.5, 6, 0.000001)); - - krcahParameterEstimator->SetParameterSetToImplementation(); - krcahParameterEstimator->SetBackgroundValue(foregroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); - - krcahParameterEstimator->SetParameterSetToJournalArticle(); - krcahParameterEstimator->SetInput(image2); - krcahParameterEstimator->SetMaskImage(mask); - krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.25, 6, 0.000001)); - - krcahParameterEstimator->SetParameterSetToJournalArticle(); - krcahParameterEstimator->SetBackgroundValue(foregroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_EQUAL(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); - - MaskType::Pointer mask2 = MaskType::New(); - mask2->SetRegions(maskRegion); - mask2->Allocate(); - mask2->FillBuffer(foregroundValue); - - krcahParameterEstimator->SetInput(image); - krcahParameterEstimator->SetParameterSetToImplementation(); - krcahParameterEstimator->SetMaskImage(mask2); - krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( - itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); - - krcahParameterEstimator->SetInput(image); - krcahParameterEstimator->SetParameterSetToJournalArticle(); - krcahParameterEstimator->SetMaskImage(mask2); - krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); - - return EXIT_SUCCESS; -} From b282ebafdffff8c100fcbd815c4abad4ab2393ca Mon Sep 17 00:00:00 2001 From: Bryce Besler Date: Fri, 2 Nov 2018 13:43:34 -0600 Subject: [PATCH 096/150] BUG: Follow templating of itkStreamableImageFilter for wrapping --- ...xEigenToMeasureParameterEstimationFilter.h | 7 ++-- ...igenToMeasureParameterEstimationFilter.hxx | 28 ++++++++-------- ...kEigenToMeasureParameterEstimationFilter.h | 8 ++--- ...igenToMeasureParameterEstimationFilter.hxx | 24 +++++++------- ...hEigenToMeasureParameterEstimationFilter.h | 7 ++-- ...igenToMeasureParameterEstimationFilter.hxx | 33 ++++++++++--------- 6 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index b57a4d59c52..b3f217140fe 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -49,15 +49,16 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class DescoteauxEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter +template +class DescoteauxEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToMeasureParameterEstimationFilter); /** Standard Self typedef */ using Self = DescoteauxEigenToMeasureParameterEstimationFilter; - using Superclass = EigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index ee599603e23..9f1caf58455 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -25,8 +25,9 @@ namespace itk { -template -DescoteauxEigenToMeasureParameterEstimationFilter::DescoteauxEigenToMeasureParameterEstimationFilter() +template +DescoteauxEigenToMeasureParameterEstimationFilter::DescoteauxEigenToMeasureParameterEstimationFilter() : Superclass() , m_FrobeniusNormWeight(0.5) { @@ -39,16 +40,16 @@ DescoteauxEigenToMeasureParameterEstimationFilter::DescoteauxEigenT this->GetParametersOutput()->Set(parameters); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +DescoteauxEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { m_MaxFrobeniusNorm = NumericTraits::NonpositiveMin(); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { /* Determine default parameters */ RealType alpha, beta, c; @@ -71,9 +72,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter::AfterThreadedGen this->GetParametersOutput()->Set(parameters); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( +DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ @@ -130,9 +131,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter::DynamicThreadedG m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); } -template -typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType -DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( +template +typename DescoteauxEigenToMeasureParameterEstimationFilter::RealType +DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeniusNorm( const InputImagePixelType & pixel) const { /* Forbenius norm is given by the square root of the sum of squares @@ -146,9 +147,10 @@ DescoteauxEigenToMeasureParameterEstimationFilter::CalculateFrobeni return sqrt(norm); } -template +template void -DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const +DescoteauxEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index 6a1e05979fa..268bd2ca51d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -47,16 +47,16 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template +template class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter - : public StreamingImageFilter + : public StreamingImageFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(EigenToMeasureParameterEstimationFilter); /** Standard Self typedef */ using Self = EigenToMeasureParameterEstimationFilter; - using Superclass = StreamingImageFilter; + using Superclass = StreamingImageFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; @@ -73,7 +73,7 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter itkStaticConstMacro(ImageDimension, unsigned int, TInputImage::ImageDimension); /** Output image typedefs. */ - using OutputImageType = TInputImage; + using OutputImageType = TOutputImage; using OutputImageRegionType = typename OutputImageType::RegionType; /** Input Mask typedefs. */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx index f60c8783454..77a1b2a0a79 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.hxx @@ -29,8 +29,8 @@ namespace itk { -template -EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() +template +EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEstimationFilter() { /* Set stream parameters */ this->SetNumberOfStreamDivisions(10); @@ -42,9 +42,9 @@ EigenToMeasureParameterEstimationFilter::EigenToMeasureParameterEst this->GetParametersOutput()->Set(ParameterArrayType()); } -template +template void -EigenToMeasureParameterEstimationFilter::UpdateOutputData(DataObject * itkNotUsed(output)) +EigenToMeasureParameterEstimationFilter::UpdateOutputData(DataObject * itkNotUsed(output)) { /** Prevent chasing our tail */ if (this->m_Updating) @@ -157,23 +157,23 @@ EigenToMeasureParameterEstimationFilter::UpdateOutputData(DataObjec this->m_Updating = false; } -template -typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() +template +typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() { return static_cast(this->ProcessObject::GetOutput(1)); } -template -const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * -EigenToMeasureParameterEstimationFilter::GetParametersOutput() const +template +const typename EigenToMeasureParameterEstimationFilter::ParameterDecoratedType * +EigenToMeasureParameterEstimationFilter::GetParametersOutput() const { return static_cast(this->ProcessObject::GetOutput(1)); } -template +template void -EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const +EigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h index 400a6c4603b..a3a396d0274 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h @@ -74,15 +74,16 @@ namespace itk * \author: Bryce Besler * \ingroup BoneEnhancement */ -template -class KrcahEigenToMeasureParameterEstimationFilter : public EigenToMeasureParameterEstimationFilter +template +class KrcahEigenToMeasureParameterEstimationFilter + : public EigenToMeasureParameterEstimationFilter { public: ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToMeasureParameterEstimationFilter); /** Standard Self typedef */ using Self = KrcahEigenToMeasureParameterEstimationFilter; - using Superclass = EigenToMeasureParameterEstimationFilter; + using Superclass = EigenToMeasureParameterEstimationFilter; using Pointer = SmartPointer; using ConstPointer = SmartPointer; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx index f1b8bc0ad6d..544fa4c1e98 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -25,8 +25,8 @@ namespace itk { -template -KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() +template +KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasureParameterEstimationFilter() : m_ParameterSet(UseImplementationParameters) { /* Set parameter size to 3 */ @@ -38,17 +38,17 @@ KrcahEigenToMeasureParameterEstimationFilter::KrcahEigenToMeasurePa this->GetParametersOutput()->Set(parameters); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() +KrcahEigenToMeasureParameterEstimationFilter::BeforeThreadedGenerateData() { m_ThreadAccumulatedTrace = NumericTraits::ZeroValue(); m_ThreadCount = NumericTraits::ZeroValue(); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() +KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerateData() { /* Determine default parameters */ RealType alpha, beta, gamma; @@ -91,9 +91,9 @@ KrcahEigenToMeasureParameterEstimationFilter::AfterThreadedGenerate this->GetParametersOutput()->Set(parameters); } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( +KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenerateData( const OutputImageRegionType & outputRegionForThread) { /* If size is zero, return */ @@ -168,9 +168,9 @@ KrcahEigenToMeasureParameterEstimationFilter::DynamicThreadedGenera m_ThreadAccumulatedTrace += accum; } -template -typename KrcahEigenToMeasureParameterEstimationFilter::RealType -KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToImplementation( InputImagePixelType pixel) { /* Sum of the absolute value of the eigenvalues */ @@ -182,9 +182,9 @@ KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordi return trace; } -template -typename KrcahEigenToMeasureParameterEstimationFilter::RealType -KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( +template +typename KrcahEigenToMeasureParameterEstimationFilter::RealType +KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordingToJournalArticle( InputImagePixelType pixel) { /* Sum of the eigenvalues */ @@ -196,9 +196,10 @@ KrcahEigenToMeasureParameterEstimationFilter::CalculateTraceAccordi return trace; } -template +template void -KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, Indent indent) const +KrcahEigenToMeasureParameterEstimationFilter::PrintSelf(std::ostream & os, + Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "ParameterSet: " << GetParameterSet() << std::endl; From 339c70b818ce3461c2ff452503a35bd5aea19a06 Mon Sep 17 00:00:00 2001 From: Pablo Hernandez-Cerdan Date: Mon, 19 Nov 2018 14:06:43 -0500 Subject: [PATCH 097/150] COMP: Use directly std::exp instead of the wrapper vcl_exp Also remove deprecated throw signature in GenerateInputRequestedRegion --- .../include/itkDescoteauxEigenToScalarFunctorImageFilter.h | 6 +++--- .../include/itkKrcahEigenToScalarFunctorImageFilter.h | 6 +++--- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.h | 2 +- ...itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index de7f7217caf..190f035be17 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -92,9 +92,9 @@ class DescoteauxEigenToScalarFunctor /* Multiply together to get sheetness */ sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); + sheetness *= std::exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); + sheetness *= (1.0 - std::exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); + sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); return static_cast(sheetness); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 6caebe21057..893059c3775 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -86,9 +86,9 @@ class KrcahEigenToScalarFunctor /* Multiply together to get sheetness */ sheetness = (m_Direction * a3 / l3); - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); - sheetness *= vcl_exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); + sheetness *= std::exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); + sheetness *= std::exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); + sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); return static_cast(sheetness); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index 963a6171574..a1e2ceb0e06 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -106,7 +106,7 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter * order to inform the pipeline execution model. * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ virtual void - GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); + GenerateInputRequestedRegion(); #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx index 51487470594..eddf59a3679 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx @@ -44,8 +44,7 @@ KrcahEigenToScalarPreprocessingImageToImageFilter void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() throw( - InvalidRequestedRegionError) +KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() { // This implementation is copied from itkDiscreteGaussianImageFilter From 8e19dc2283bb6c3befeb9bfc01793ffb11e4da2a Mon Sep 17 00:00:00 2001 From: Pablo Hernandez-Cerdan Date: Mon, 19 Nov 2018 22:08:43 -0500 Subject: [PATCH 098/150] BUG: Disable DynamicMultiThreading in EigenToScalarParameterEstimation Error: ``` itk::ERROR: KrcahEigenToScalarParameterEstimationImageFilter(0x5583dd2a87c0): Subclass should override this method!!! If old behavior is desired invoke this->DynamicMultiThreadingOff(); before Update() is called. The best place is in class constructor. ``` --- .../itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx | 1 + .../itkKrcahEigenToScalarParameterEstimationImageFilter.hxx | 1 + 2 files changed, 2 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx index d835345a393..bc0a98daf2f 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx @@ -44,6 +44,7 @@ DescoteauxEigenToScalarParameterEstimationImageFilter:: output->Set(0.5); this->ProcessObject::SetNthOutput(i, output.GetPointer()); } + this->DynamicMultiThreadingOff(); } template diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index 85a90c1b2a3..fb6412c581e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -45,6 +45,7 @@ KrcahEigenToScalarParameterEstimationImageFilterSet(0.5); this->ProcessObject::SetNthOutput(i, output.GetPointer()); } + this->DynamicMultiThreadingOff(); } template From 99ed66391431c4cd4e2378b920fb08453bd7a401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 11:19:23 -0400 Subject: [PATCH 099/150] COMP: add ITK_ prefix to testing macros --- ...escoteauxEigenToScalarFunctorImageTest.cxx | 22 ++--- .../itkDescoteauxEigenToScalarFunctorTest.cxx | 30 +++---- ...DescoteauxEigenToScalarImageFilterTest.cxx | 16 ++-- ...alarParameterEstimationImageFilterTest.cxx | 61 ++++++++------ ...cahEigenToScalarFunctorImageFilterTest.cxx | 22 ++--- .../test/itkKrcahEigenToScalarFunctorTest.cxx | 40 ++++----- .../itkKrcahEigenToScalarImageFilterTest.cxx | 15 ++-- ...alarParameterEstimationImageFilterTest.cxx | 84 +++++++++---------- ...larPreprocessingImageToImageFilterTest.cxx | 8 +- ...itkMaximumAbsoluteValueImageFilterTest.cxx | 6 +- ...nhancementImageFilterStaticMethodsTest.cxx | 27 +++--- 11 files changed, 170 insertions(+), 161 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx index 344acd4a248..ca897e4a188 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorImageTest.cxx @@ -41,21 +41,21 @@ itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) descoFilter->SetAlpha(0.5); descoFilter->SetBeta(0.5); descoFilter->SetC(0.25); - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /* Exercise basic set/get methods */ descoFilter->SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetAlpha()); + ITK_TEST_SET_GET_VALUE(0.5, descoFilter->GetAlpha()); descoFilter->SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, descoFilter->GetBeta()); + ITK_TEST_SET_GET_VALUE(0.5, descoFilter->GetBeta()); descoFilter->SetC(0.25); - TEST_SET_GET_VALUE(0.25, descoFilter->GetC()); + ITK_TEST_SET_GET_VALUE(0.25, descoFilter->GetC()); // Default should be 1 - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); descoFilter->SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, descoFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(1.0, descoFilter->GetEnhanceType()); descoFilter->SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, descoFilter->GetEnhanceType()); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -84,14 +84,14 @@ itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) image->FillBuffer(simpleEigenPixel); descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); itk::ImageRegionIteratorWithIndex input(descoFilter->GetOutput(), region); input.GoToBegin(); while (!input.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); ++input; } @@ -106,14 +106,14 @@ itkDescoteauxEigenToScalarFunctorImageTest(int argc, char * argv[]) image2->FillBuffer(simpleEigenPixel); descoFilter->SetInput(image2); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); itk::ImageRegionIteratorWithIndex input2(descoFilter->GetOutput(), region); input2.GoToBegin(); while (!input2.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.0913983433747, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.0913983433747, 6, 0.000001)); ++input2; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx index 44fc42de65e..4693001d135 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx @@ -36,17 +36,17 @@ itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) /* Exercise basic set/get methods */ functor.SetAlpha(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetAlpha()); + ITK_TEST_SET_GET_VALUE(0.25, functor.GetAlpha()); functor.SetBeta(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetBeta()); + ITK_TEST_SET_GET_VALUE(0.25, functor.GetBeta()); functor.SetC(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetC()); + ITK_TEST_SET_GET_VALUE(0.25, functor.GetC()); // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); /* Test a few calculations */ EigenValueArrayType mEigenValueArray; @@ -59,63 +59,63 @@ itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* Return zero on positive l3 with bright sheets */ mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = 1; functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* Return zero on positive l3 with dark sheets */ mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = -1; functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* 0, 0, -1; bright sheets */ mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = -1; functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); /* 0, 0, 1; dark sheets */ mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = 1; functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.999329187279, 6, 0.000001)); /* 1, 1, -1; bright sheets */ mEigenValueArray[0] = 1; mEigenValueArray[1] = 1; mEigenValueArray[2] = -1; functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* 1, 1, 1; dark sheets */ mEigenValueArray[0] = 1; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* 0.25, 1, -1; bright sheets */ mEigenValueArray[0] = 0.25; mEigenValueArray[1] = 1; mEigenValueArray[2] = -1; functor.SetEnhanceBrightObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); /* 0.25, 1, 1; dark sheets */ mEigenValueArray[0] = 0.25; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; functor.SetEnhanceDarkObjects(); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0913983433747, 6, 0.000001)); return EXIT_SUCCESS; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx index b5e4221ee2c..837365a02ab 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarImageFilterTest.cxx @@ -40,11 +40,11 @@ itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) DescoteauxEigenToScalarImageFilterType::Pointer descoFilter = DescoteauxEigenToScalarImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(descoFilter, DescoteauxEigenToScalarImageFilter, EigenToScalarImageFilter); /* Test defaults */ - TEST_EXPECT_EQUAL(descoFilter->GetEigenValueOrder(), - DescoteauxEigenToScalarImageFilterType::Superclass::OrderByMagnitude); + ITK_TEST_EXPECT_EQUAL(descoFilter->GetEigenValueOrder(), + DescoteauxEigenToScalarImageFilterType::Superclass::OrderByMagnitude); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -74,19 +74,19 @@ itkDescoteauxEigenToScalarImageFilterTest(int argc, char * argv[]) /* Run with no exceptions */ descoFilter->SetEnhanceBrightObjects(); descoFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(descoFilter->Update()); /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetC(), 2.41091269 * 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoFilter->GetC(), 2.41091269 * 0.5, 6, 0.000001)); itk::ImageRegionIteratorWithIndex it(descoFilter->GetOutput(), region); it.GoToBegin(); while (!it.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.364376944099, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.364376944099, 6, 0.000001)); ++it; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx index 97a3679c76a..229dc7ce142 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarParameterEstimationImageFilterTest.cxx @@ -38,17 +38,19 @@ itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) DescoteauxEigenToScalarParameterEstimationImageFilterType::Pointer descoteauxParameterEstimator = DescoteauxEigenToScalarParameterEstimationImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS( + ITK_EXERCISE_BASIC_OBJECT_METHODS( descoteauxParameterEstimator, DescoteauxEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); /* Test defaults */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetCOutput()->Get(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetCOutput()->Get(), 0.5, 6, 0.000001)); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -123,35 +125,39 @@ itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) /* Test an empty pixel value */ descoteauxParameterEstimator->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); /* Test an empty pixel value */ descoteauxParameterEstimator->SetFrobeniusNormWeight(0.25); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.25, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.25, 6, 0.000001)); /* Test with a mask */ descoteauxParameterEstimator->SetInput(image2); descoteauxParameterEstimator->SetMaskImage(mask); descoteauxParameterEstimator->SetBackgroundValue(foregroundValue); descoteauxParameterEstimator->SetFrobeniusNormWeight(0.5); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); descoteauxParameterEstimator->SetInput(image2); descoteauxParameterEstimator->SetMaskImage(mask); descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 3 * 0.5, 6, 0.000001)); MaskType::Pointer mask2 = MaskType::New(); mask2->SetRegions(maskRegion); @@ -161,10 +167,11 @@ itkDescoteauxEigenToScalarParameterEstimationImageFilterTest(int, char *[]) descoteauxParameterEstimator->SetInput(image); descoteauxParameterEstimator->SetMaskImage(mask2); descoteauxParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(descoteauxParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE( + itk::Math::FloatAlmostEqual(descoteauxParameterEstimator->GetC(), sqrt(3) * 1 * 0.5, 6, 0.000001)); return EXIT_SUCCESS; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx index ebc364280de..f27b5275c68 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorImageFilterTest.cxx @@ -41,21 +41,21 @@ itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) krcahFilter->SetAlpha(0.5); krcahFilter->SetBeta(0.5); krcahFilter->SetGamma(0.25); - EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); /* Exercise basic set/get methods */ krcahFilter->SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, krcahFilter->GetAlpha()); + ITK_TEST_SET_GET_VALUE(0.5, krcahFilter->GetAlpha()); krcahFilter->SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, krcahFilter->GetBeta()); + ITK_TEST_SET_GET_VALUE(0.5, krcahFilter->GetBeta()); krcahFilter->SetGamma(0.25); - TEST_SET_GET_VALUE(0.25, krcahFilter->GetGamma()); + ITK_TEST_SET_GET_VALUE(0.25, krcahFilter->GetGamma()); // Default should be -1 - TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); krcahFilter->SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, krcahFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(1.0, krcahFilter->GetEnhanceType()); krcahFilter->SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, krcahFilter->GetEnhanceType()); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -84,14 +84,14 @@ itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) image->FillBuffer(simpleEigenPixel); krcahFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); itk::ImageRegionIteratorWithIndex input(krcahFilter->GetOutput(), region); input.GoToBegin(); while (!input.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input.Get(), 0.0, 6, 0.000001)); ++input; } @@ -107,14 +107,14 @@ itkKrcahEigenToScalarFunctorImageFilterTest(int argc, char * argv[]) image2->FillBuffer(simpleEigenPixel); krcahFilter->SetInput(image2); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); itk::ImageRegionIteratorWithIndex input2(krcahFilter->GetOutput(), region); input2.GoToBegin(); while (!input2.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.000335462627903, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(input2.Get(), 0.000335462627903, 6, 0.000001)); ++input2; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx index 38d282791d9..164c5bc13fb 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx @@ -36,17 +36,17 @@ itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) /* Exercise basic set/get methods */ functor.SetAlpha(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetAlpha()); + ITK_TEST_SET_GET_VALUE(0.5, functor.GetAlpha()); functor.SetBeta(0.5); - TEST_SET_GET_VALUE(0.5, functor.GetBeta()); + ITK_TEST_SET_GET_VALUE(0.5, functor.GetBeta()); functor.SetGamma(0.25); - TEST_SET_GET_VALUE(0.25, functor.GetGamma()); + ITK_TEST_SET_GET_VALUE(0.25, functor.GetGamma()); // Default should be -1 - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); functor.SetEnhanceDarkObjects(); - TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(1.0, functor.GetEnhanceType()); functor.SetEnhanceBrightObjects(); - TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); + ITK_TEST_SET_GET_VALUE(-1.0, functor.GetEnhanceType()); /* Test a few calculations */ EigenValueArrayType mEigenValueArray; @@ -59,97 +59,97 @@ itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = 0; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* lambda_2 zeros returns zero */ mEigenValueArray[0] = 0; mEigenValueArray[1] = 0; mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0, 6, 0.000001)); /* lambda_1 zero */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.0183156368276, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.0183156368276, 6, 0.000001)); /* lambda_1 zero; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0183156368276, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.0183156368276, 6, 0.000001)); /* one, one, one */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = 1; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); /* one, one, one; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = 1; mEigenValueArray[1] = 1; mEigenValueArray[2] = 1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); /* one, one, one negative */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = -1; mEigenValueArray[1] = -1; mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.000335462627903, 6, 0.000001)); /* one, one, one negative; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = -1; mEigenValueArray[1] = -1; mEigenValueArray[2] = -1; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.000335462627903, 6, 0.000001)); /* -1, -2, 3 */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = -1; mEigenValueArray[1] = -2; mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.15123975969, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -0.15123975969, 6, 0.000001)); /* -1, -2, 3; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = -1; mEigenValueArray[1] = -2; mEigenValueArray[2] = 3; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.15123975969, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 0.15123975969, 6, 0.000001)); /* Perfect Joint */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = 1000; mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); /* Perfect Joint; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = 1000; mEigenValueArray[2] = 100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); /* Perfect Bone */ functor.SetEnhanceBrightObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = -1000; mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), 1.0, 6, 0.000001)); /* Perfect Bone; dark sheets */ functor.SetEnhanceDarkObjects(); mEigenValueArray[0] = 0; mEigenValueArray[1] = -1000; mEigenValueArray[2] = -100000000; - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(functor(mEigenValueArray), -1.0, 6, 0.000001)); return EXIT_SUCCESS; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx index b3f3da41c80..fff3b85a82d 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarImageFilterTest.cxx @@ -40,10 +40,11 @@ itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) KrcahEigenToScalarImageFilterType::Pointer krcahFilter = KrcahEigenToScalarImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(krcahFilter, KrcahEigenToScalarImageFilter, EigenToScalarImageFilter); /* Test defaults */ - TEST_EXPECT_EQUAL(krcahFilter->GetEigenValueOrder(), KrcahEigenToScalarImageFilterType::Superclass::OrderByMagnitude); + ITK_TEST_EXPECT_EQUAL(krcahFilter->GetEigenValueOrder(), + KrcahEigenToScalarImageFilterType::Superclass::OrderByMagnitude); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -75,19 +76,19 @@ itkKrcahEigenToScalarImageFilterTest(int argc, char * argv[]) krcahFilter->SetParameterSetToImplementation(); krcahFilter->SetEnhanceBrightObjects(); krcahFilter->SetInput(image); - TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahFilter->Update()); /* Make sure process for setting parameters works */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahFilter->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); itk::ImageRegionIteratorWithIndex it(krcahFilter->GetOutput(), region); it.GoToBegin(); while (!it.IsAtEnd()) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.0158368867121, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(it.Get(), 0.0158368867121, 6, 0.000001)); ++it; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx index 5786a96aca8..f9d96a59145 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarParameterEstimationImageFilterTest.cxx @@ -38,18 +38,18 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) KrcahEigenToScalarParameterEstimationImageFilterType::Pointer krcahParameterEstimator = KrcahEigenToScalarParameterEstimationImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS( + ITK_EXERCISE_BASIC_OBJECT_METHODS( krcahParameterEstimator, KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); /* Test defaults */ - TEST_EXPECT_EQUAL(krcahParameterEstimator->GetParameterSet(), - KrcahEigenToScalarParameterEstimationImageFilterType::UseImplementationParameters); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGammaOutput()->Get(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_EQUAL(krcahParameterEstimator->GetParameterSet(), + KrcahEigenToScalarParameterEstimationImageFilterType::UseImplementationParameters); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlphaOutput()->Get(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBetaOutput()->Get(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGammaOutput()->Get(), 0.5, 6, 0.000001)); /* Create some test data which is computable */ EigenValueArrayType simpleEigenPixel; @@ -125,59 +125,59 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) /* Test an empty pixel value */ krcahParameterEstimator->SetInput(image); krcahParameterEstimator->SetParameterSetToImplementation(); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 0.25, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 0.25, 6, 0.000001)); /* Test with a mask */ krcahParameterEstimator->SetParameterSetToImplementation(); krcahParameterEstimator->SetInput(image2); krcahParameterEstimator->SetMaskImage(mask); krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 3 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToImplementation(); krcahParameterEstimator->SetBackgroundValue(foregroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); krcahParameterEstimator->SetInput(image2); krcahParameterEstimator->SetMaskImage(mask); krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.25, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), 3 * 3 * 0.25, 6, 0.000001)); krcahParameterEstimator->SetParameterSetToJournalArticle(); krcahParameterEstimator->SetBackgroundValue(foregroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_EQUAL(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_EQUAL(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); MaskType::Pointer mask2 = MaskType::New(); mask2->SetRegions(maskRegion); @@ -188,22 +188,22 @@ itkKrcahEigenToScalarParameterEstimationImageFilterTest(int, char *[]) krcahParameterEstimator->SetParameterSetToImplementation(); krcahParameterEstimator->SetMaskImage(mask2); krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE( + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), itk::Math::sqrt2 * 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), itk::Math::sqrt2 * 3 * 1 * 0.5, 6, 0.000001)); krcahParameterEstimator->SetInput(image); krcahParameterEstimator->SetParameterSetToJournalArticle(); krcahParameterEstimator->SetMaskImage(mask2); krcahParameterEstimator->SetBackgroundValue(backgroundValue); - TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); + ITK_TRY_EXPECT_NO_EXCEPTION(krcahParameterEstimator->Update()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetAlpha(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetBeta(), 0.5, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(krcahParameterEstimator->GetGamma(), -3 * 1 * 0.25, 6, 0.000001)); return EXIT_SUCCESS; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx index e16178cab7a..df82f9b0117 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarPreprocessingImageToImageFilterTest.cxx @@ -30,12 +30,12 @@ itkKrcahEigenToScalarPreprocessingImageToImageFilterTest(int, char *[]) FilterType::Pointer filter = FilterType::New(); /* Basic test */ - EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(filter, KrcahEigenToScalarPreprocessingImageToImageFilter, ImageToImageFilter); /* Default parameters */ - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetScalingConstant(), 10.0, 6, 0.000001)); - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetSigma(), 1.0, 6, 0.000001)); - TEST_EXPECT_TRUE(filter->GetReleaseInternalFilterData()); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetScalingConstant(), 10.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual(filter->GetSigma(), 1.0, 6, 0.000001)); + ITK_TEST_EXPECT_TRUE(filter->GetReleaseInternalFilterData()); /* TODO: Regression test */ diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx index c42e1ba1b98..a8426c6781f 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterTest.cxx @@ -29,7 +29,7 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) using MaximumAbsoluteValueImageFilterType = itk::MaximumAbsoluteValueImageFilter; MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); - EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); + ITK_EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); /** Create an image and run a basic test */ ImageType::RegionType region; @@ -87,11 +87,11 @@ itkMaximumAbsoluteValueImageFilterTest(int, char *[]) { if ((i % 2) == 0) { - TEST_EXPECT_EQUAL(ot.Get(), -2); + ITK_TEST_EXPECT_EQUAL(ot.Get(), -2); } else { - TEST_EXPECT_EQUAL(ot.Get(), 2); + ITK_TEST_EXPECT_EQUAL(ot.Get(), 2); } ++ot; } diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index c4c0914e2e0..a78894f1b8c 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -34,10 +34,11 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) ArrayType sigmaArray; bool exceptionCaught = false; - TRY_EXPECT_EXCEPTION(sigmaArray = - MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); + ITK_TRY_EXPECT_EXCEPTION(sigmaArray = + MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); - TRY_EXPECT_EXCEPTION(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); + ITK_TRY_EXPECT_EXCEPTION(sigmaArray = + MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 5, 0)); /* Test that we get one when min equals max */ ArrayType expectedOneSigmaArray; @@ -46,9 +47,9 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) /* Test the two cases of min equals max with a large number of values */ sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); + ITK_TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 1, 100); - TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); + ITK_TEST_EXPECT_EQUAL(expectedOneSigmaArray, sigmaArray); /* Test the Logarithmic method */ ArrayType expectedLogarithmicArray; @@ -61,19 +62,19 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) ArrayType logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(1, 5, 5); /* Here we need to do some floating point comparisons */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) + ITK_TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) { - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); } logarithmicArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 1, 5); /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) + ITK_TEST_EXPECT_EQUAL(expectedLogarithmicArray.GetSize(), logarithmicArray.GetSize()) for (ArrayType::SizeValueType i = 0; i < expectedLogarithmicArray.GetSize(); ++i) { - TEST_EXPECT_TRUE( + ITK_TEST_EXPECT_TRUE( itk::Math::FloatAlmostEqual(expectedLogarithmicArray.GetElement(i), logarithmicArray.GetElement(i), 6, 0.000001)); } @@ -89,19 +90,19 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) ArrayType equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(1, 5, 5); /* Here we need to do some floating point comparisons. These are exact, but we should still do a floating point * comparison to be sure */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) + ITK_TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); } equidistanceArray = MultiScaleHessianEnhancementImageFilterType::GenerateEquispacedSigmaArray(5, 1, 5); /* Should be the same if we flip min and max */ - TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) + ITK_TEST_EXPECT_EQUAL(expectedEquidistanceArray.GetSize(), equidistanceArray.GetSize()) for (ArrayType::SizeValueType i = 0; i < expectedEquidistanceArray.GetSize(); ++i) { - TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( + ITK_TEST_EXPECT_TRUE(itk::Math::FloatAlmostEqual( expectedEquidistanceArray.GetElement(i), equidistanceArray.GetElement(i), 6, 0.000001)); } From 25fc0bbc9eda65096a8b09c25df894e4955548fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 11:24:56 -0400 Subject: [PATCH 100/150] COMP: Do not include itkExceptionObject.h directly --- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index 1268a198f31..acc40d3f88e 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -21,7 +21,6 @@ #include "itkMultiScaleHessianEnhancementImageFilter.h" #include "itkMath.h" #include "itkProgressAccumulator.h" -#include "itkExceptionObject.h" namespace itk { From 616b4910a2b1244608bc081f6dac40ea35751dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 11:30:41 -0400 Subject: [PATCH 101/150] COMP: fully qualify enumeration names --- .../include/itkMultiScaleHessianEnhancementImageFilter.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx index acc40d3f88e..d8dfeb9e7e3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkMultiScaleHessianEnhancementImageFilter.hxx @@ -249,11 +249,11 @@ MultiScaleHessianEnhancementImageFilter::ConvertType( switch (order) { case EigenToScalarImageFilterType::OrderByValue: - return EigenAnalysisFilterType::FunctorType::OrderByValue; + return EigenAnalysisFilterType::FunctorType::EigenValueOrderType::OrderByValue; case EigenToScalarImageFilterType::OrderByMagnitude: - return EigenAnalysisFilterType::FunctorType::OrderByMagnitude; + return EigenAnalysisFilterType::FunctorType::EigenValueOrderType::OrderByMagnitude; case EigenToScalarImageFilterType::DoNotOrder: - return EigenAnalysisFilterType::FunctorType::DoNotOrder; + return EigenAnalysisFilterType::FunctorType::EigenValueOrderType::DoNotOrder; default: itkExceptionMacro(<< "Trying to convert bad order " << order); } From 3693635def41531166a03332a43c79ee0b46a0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 11:32:08 -0400 Subject: [PATCH 102/150] COMP: rename GetNumberOfThreads into GetNumberOfWorkUnits --- ...kDescoteauxEigenToScalarParameterEstimationImageFilter.hxx | 4 ++-- .../itkKrcahEigenToScalarParameterEstimationImageFilter.hxx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx index bc0a98daf2f..1b326b44b51 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx @@ -87,7 +87,7 @@ template void DescoteauxEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); /* Resize threads */ m_MaxFrobeniusNorm.SetSize(numberOfThreads); @@ -98,7 +98,7 @@ template void DescoteauxEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); /* Determine default parameters */ RealType alpha, beta, c; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index fb6412c581e..9b63c70b3c3 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -88,7 +88,7 @@ template void KrcahEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); /* Resize threads */ m_AccumulatedAverageTrace.SetSize(numberOfThreads); @@ -102,7 +102,7 @@ template void KrcahEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() { - ThreadIdType numberOfThreads = this->GetNumberOfThreads(); + ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); /* Determine default parameters */ RealType alpha, beta, gamma; From 40cb7b1acb55fdbef8413203d3e28b5ca348fe0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 14:08:27 -0400 Subject: [PATCH 103/150] COMP: fix warnings -Winconsistent-missing-override e.g. warning: 'PrintSelf' overrides a member function but is not marked 'override' [-Winconsistent-missing-override] --- .../include/itkDescoteauxEigenToScalarFunctorImageFilter.h | 2 +- .../include/itkKrcahEigenToScalarFunctorImageFilter.h | 2 +- .../itkKrcahEigenToScalarPreprocessingImageToImageFilter.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h index 190f035be17..b2916ac6c8d 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h @@ -245,7 +245,7 @@ class DescoteauxEigenToScalarFunctorImageFilter private: void - PrintSelf(std::ostream & os, Indent indent) const + PrintSelf(std::ostream & os, Indent indent) const override { Superclass::PrintSelf(os, indent); os << indent << "Alpha: " << GetAlpha() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h index 893059c3775..ebbf77e36fd 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h @@ -236,7 +236,7 @@ class KrcahEigenToScalarFunctorImageFilter private: void - PrintSelf(std::ostream & os, Indent indent) const + PrintSelf(std::ostream & os, Indent indent) const override { Superclass::PrintSelf(os, indent); os << indent << "Alpha: " << GetAlpha() << std::endl; diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h index a1e2ceb0e06..ee10ca0a87b 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.h @@ -105,8 +105,8 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarPreprocessingImageToImageFilter * provide an implementation for GenerateInputRequestedRegion() in * order to inform the pipeline execution model. * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - virtual void - GenerateInputRequestedRegion(); + void + GenerateInputRequestedRegion() override; #ifdef ITK_USE_CONCEPT_CHECKING // Begin concept checking From 7da2bdc99a43023e50cb1e70f2ef7c2f474cb9eb Mon Sep 17 00:00:00 2001 From: Dzenan Zukic Date: Tue, 15 Oct 2019 14:41:49 -0400 Subject: [PATCH 104/150] COMP: fix GCC -Wall warnings --- .../itkKrcahEigenToScalarParameterEstimationImageFilter.h | 8 ++++---- ...tkKrcahEigenToScalarParameterEstimationImageFilter.hxx | 4 ---- .../test/itkDescoteauxEigenToScalarFunctorTest.cxx | 4 ++++ .../test/itkKrcahEigenToScalarFunctorTest.cxx | 4 ++++ ...caleHessianEnhancementImageFilterStaticMethodsTest.cxx | 1 - 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h index 79361d0e07d..452b4056f0a 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h @@ -221,14 +221,14 @@ class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter private: /* Parameters */ - KrcahImplementationType m_ParameterSet; + KrcahImplementationType m_ParameterSet{ UseImplementationParameters }; /* Inputs */ - MaskPixelType m_BackgroundValue; + MaskPixelType m_BackgroundValue{ NumericTraits::Zero }; /* Arrays for threads */ - Array m_AccumulatedAverageTrace; - Array m_NumVoxels; + Array m_AccumulatedAverageTrace{ 1 }; + Array m_NumVoxels{ 1 }; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx index 9b63c70b3c3..bf6bf2d4af4 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx @@ -29,10 +29,6 @@ namespace itk template KrcahEigenToScalarParameterEstimationImageFilter::KrcahEigenToScalarParameterEstimationImageFilter() - : m_ParameterSet(UseImplementationParameters) - , m_BackgroundValue(NumericTraits::Zero) - , m_NumVoxels(1) - , m_AccumulatedAverageTrace(1) { /* We require an input, optional mask */ this->SetNumberOfRequiredInputs(1); diff --git a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx index 4693001d135..a893f2d2535 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkDescoteauxEigenToScalarFunctorTest.cxx @@ -26,10 +26,14 @@ itkDescoteauxEigenToScalarFunctorTest(int argc, char * argv[]) constexpr unsigned int Dimension = 3; using ImagePixelType = double; using ImageType = itk::Image; + typename ImageType::Pointer image = ImageType::New(); + ITK_EXERCISE_BASIC_OBJECT_METHODS(image, Image, ImageBase); using EigenValueType = float; using EigenValueArrayType = itk::FixedArray; using EigenValueImageType = itk::Image; + typename EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + ITK_EXERCISE_BASIC_OBJECT_METHODS(image2, Image, ImageBase); using FunctorType = itk::Functor::DescoteauxEigenToScalarFunctor; FunctorType functor = FunctorType(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx index 164c5bc13fb..3e9018a9e7c 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkKrcahEigenToScalarFunctorTest.cxx @@ -26,10 +26,14 @@ itkKrcahEigenToScalarFunctorTest(int argc, char * argv[]) constexpr unsigned int Dimension = 3; using ImagePixelType = double; using ImageType = itk::Image; + typename ImageType::Pointer image = ImageType::New(); + ITK_EXERCISE_BASIC_OBJECT_METHODS(image, Image, ImageBase); using EigenValueType = float; using EigenValueArrayType = itk::FixedArray; using EigenValueImageType = itk::Image; + typename EigenValueImageType::Pointer image2 = EigenValueImageType::New(); + ITK_EXERCISE_BASIC_OBJECT_METHODS(image2, Image, ImageBase); using FunctorType = itk::Functor::KrcahEigenToScalarFunctor; FunctorType functor = FunctorType(); diff --git a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx index a78894f1b8c..7a1efe3fe8b 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest.cxx @@ -32,7 +32,6 @@ itkMultiScaleHessianEnhancementImageFilterStaticMethodsTest(int, char *[]) /* Test the two cases of step size zero */ ArrayType sigmaArray; - bool exceptionCaught = false; ITK_TRY_EXPECT_EXCEPTION(sigmaArray = MultiScaleHessianEnhancementImageFilterType::GenerateLogarithmicSigmaArray(5, 5, 0)); From 4d27bdc80d122f4b353875a19efd4b6ef025d69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 15 Oct 2019 16:13:52 -0400 Subject: [PATCH 105/150] ENH: update version numbers --- Modules/Filtering/BoneEnhancement/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Modules/Filtering/BoneEnhancement/CMakeLists.txt b/Modules/Filtering/BoneEnhancement/CMakeLists.txt index be6e51e0f5e..46013479776 100644 --- a/Modules/Filtering/BoneEnhancement/CMakeLists.txt +++ b/Modules/Filtering/BoneEnhancement/CMakeLists.txt @@ -1,3 +1,9 @@ project(BoneEnhancement) -itk_module_impl() +if(NOT ITK_SOURCE_DIR) + find_package(ITK 5.0 REQUIRED) + list(APPEND CMAKE_MODULE_PATH ${ITK_CMAKE_DIR}) + include(ITKModuleExternal) +else() + itk_module_impl() +endif() From 6aa7e367d62948f732a2efb0ebf90faa457f9106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 19 Nov 2019 10:33:38 -0500 Subject: [PATCH 106/150] COMP: make it compile after the big merge --- ...itkDescoteauxEigenToMeasureImageFilter.hxx | 6 +- ...xEigenToMeasureParameterEstimationFilter.h | 4 +- ...igenToMeasureParameterEstimationFilter.hxx | 5 +- .../include/itkEigenToMeasureImageFilter.hxx | 2 +- .../include/itkHessianGaussianImageFilter.h | 4 +- .../include/itkHessianGaussianImageFilter.hxx | 4 +- .../itkKrcahEigenToMeasureImageFilter.hxx | 6 +- ...hEigenToMeasureParameterEstimationFilter.h | 4 +- ...igenToMeasureParameterEstimationFilter.hxx | 5 +- ...oScalarPreprocessingImageToImageFilter.hxx | 192 ------------------ .../itkKrcahPreprocessingImageToImageFilter.h | 9 - ...aximumAbsoluteValueImageFilterUnitTest.cxx | 12 +- ...kDescoteauxEigenToMeasureImageFilter.wrap} | 2 +- ...wrap => itkEigenToMeasureImageFilter.wrap} | 2 +- ...=> itkKrcahEigenToMeasureImageFilter.wrap} | 4 +- ...KrcahPreprocessingImageToImageFilter.wrap} | 2 +- 16 files changed, 32 insertions(+), 231 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx rename Modules/Filtering/BoneEnhancement/wrapping/{itkDescoteauxEigenToScalarImageFilter.wrap => itkDescoteauxEigenToMeasureImageFilter.wrap} (88%) rename Modules/Filtering/BoneEnhancement/wrapping/{itkEigenToScalarImageFilter.wrap => itkEigenToMeasureImageFilter.wrap} (88%) rename Modules/Filtering/BoneEnhancement/wrapping/{itkKrcahEigenToScalarImageFilter.wrap => itkKrcahEigenToMeasureImageFilter.wrap} (84%) rename Modules/Filtering/BoneEnhancement/wrapping/{itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap => itkKrcahPreprocessingImageToImageFilter.wrap} (50%) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx index 621d6db72ba..de9302022a1 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.hxx @@ -79,9 +79,9 @@ DescoteauxEigenToMeasureImageFilter::ProcessPixel(con /* Multiply together to get sheetness */ sheetness = 1.0; - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (2 * alpha * alpha)); - sheetness *= (1.0 - vcl_exp(-(Rblob * Rblob) / (2 * beta * beta))); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (2 * c * c))); + sheetness *= std::exp(-(Rsheet * Rsheet) / (2 * alpha * alpha)); + sheetness *= (1.0 - std::exp(-(Rblob * Rblob) / (2 * beta * beta))); + sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (2 * c * c))); return static_cast(sheetness); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h index b3f217140fe..db45a6c2eeb 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.h @@ -21,7 +21,7 @@ #include "itkMath.h" #include "itkEigenToMeasureParameterEstimationFilter.h" -#include "itkSimpleFastMutexLock.h" +#include namespace itk { @@ -127,7 +127,7 @@ class DescoteauxEigenToMeasureParameterEstimationFilter RealType m_FrobeniusNormWeight; RealType m_MaxFrobeniusNorm; - SimpleFastMutexLock m_Mutex; + std::mutex m_Mutex; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index 9f1caf58455..49cea7708e9 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -20,7 +20,6 @@ #define itkDescoteauxEigenToMeasureParameterEstimationFilter_hxx #include "itkDescoteauxEigenToMeasureParameterEstimationFilter.h" -#include "itkMutexLockHolder.h" namespace itk { @@ -112,7 +111,7 @@ DescoteauxEigenToMeasureParameterEstimationFilter::Dy { // Process point inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) { /* Compute max norm */ max = std::max(max, this->CalculateFrobeniusNorm(inputIt.Get())); @@ -127,7 +126,7 @@ DescoteauxEigenToMeasureParameterEstimationFilter::Dy } /* Block and store */ - MutexLockHolder mutexHolder(m_Mutex); + std::lock_guard mutexHolder(m_Mutex); m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx index 4568a504301..4eba55f4bba 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx @@ -53,7 +53,7 @@ EigenToMeasureImageFilter::DynamicThreadedGenerateDat while (!inputIt.IsAtEnd()) { inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) { outputIt.Set(ProcessPixel(inputIt.Get())); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h index 985a07112bd..7c30e7b8900 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.h @@ -124,8 +124,8 @@ class ITK_TEMPLATE_EXPORT HessianGaussianImageFilter : public ImageToImageFilter * Gaussian filter. * \sa DiscreteGaussianDerivativeImageFilter::GenerateInputRequestedRegion() */ // TODO - virtual void - GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) override; + void + GenerateInputRequestedRegion() override; #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ diff --git a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx index b8338b4fc6a..c4a7919d430 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkHessianGaussianImageFilter.hxx @@ -93,7 +93,7 @@ HessianGaussianImageFilter::GetNormalizeAcrossScale() template void -HessianGaussianImageFilter::GenerateInputRequestedRegion() throw(InvalidRequestedRegionError) +HessianGaussianImageFilter::GenerateInputRequestedRegion() { // call the superclass' implementation of this method. this should // copy the output requested region to the input requested region @@ -228,8 +228,6 @@ HessianGaussianImageFilter::GenerateData(void) typename RealImageType::Pointer derivativeImage; derivativeImage = m_DerivativeFilter->GetOutput(); - progress->ResetFilterProgressAndKeepAccumulatedProgress(); - // Copy the results to the corresponding component // on the output image of vectors m_ImageAdaptor->SelectNthElement(element++); diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.hxx index 67c6692c217..cb79cbb8984 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.hxx @@ -77,9 +77,9 @@ KrcahEigenToMeasureImageFilter::ProcessPixel(const In /* Multiply together to get sheetness */ sheetness = (m_EnhanceType * a3 / l3); - sheetness *= vcl_exp(-(Rsheet * Rsheet) / (alpha * alpha)); - sheetness *= vcl_exp(-(Rtube * Rtube) / (beta * beta)); - sheetness *= (1.0 - vcl_exp(-(Rnoise * Rnoise) / (gamma * gamma))); + sheetness *= std::exp(-(Rsheet * Rsheet) / (alpha * alpha)); + sheetness *= std::exp(-(Rtube * Rtube) / (beta * beta)); + sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (gamma * gamma))); return static_cast(sheetness); } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h index a3a396d0274..ca9a2b1c114 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.h @@ -21,7 +21,7 @@ #include "itkMath.h" #include "itkEigenToMeasureParameterEstimationFilter.h" -#include "itkSimpleFastMutexLock.h" +#include #include "itkCompensatedSummation.h" namespace itk @@ -173,7 +173,7 @@ class KrcahEigenToMeasureParameterEstimationFilter CompensatedSummation m_ThreadCount; CompensatedSummation m_ThreadAccumulatedTrace; - SimpleFastMutexLock m_Mutex; + std::mutex m_Mutex; }; // end class } // namespace itk diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx index 544fa4c1e98..be7fdbbf897 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -20,7 +20,6 @@ #define itkKrcahEigenToMeasureParameterEstimationFilter_hxx #include "itkKrcahEigenToMeasureParameterEstimationFilter.h" -#include "itkMutexLockHolder.h" namespace itk { @@ -147,7 +146,7 @@ KrcahEigenToMeasureParameterEstimationFilter::Dynamic { // Process point inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInside(point))) + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) { /* Compute trace */ count++; @@ -163,7 +162,7 @@ KrcahEigenToMeasureParameterEstimationFilter::Dynamic } /* Block and store */ - MutexLockHolder mutexHolder(m_Mutex); + std::lock_guard mutexHolder(m_Mutex); m_ThreadCount += count; m_ThreadAccumulatedTrace += accum; } diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx deleted file mode 100644 index eddf59a3679..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarPreprocessingImageToImageFilter.hxx +++ /dev/null @@ -1,192 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx -#define itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx - -#include "itkKrcahEigenToScalarPreprocessingImageToImageFilter.h" -#include "itkGaussianOperator.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarPreprocessingImageToImageFilter::KrcahEigenToScalarPreprocessingImageToImageFilter() - : m_Sigma(1.0f) - , m_ScalingConstant(10.0f) - , m_ReleaseInternalFilterData(true) -{ - /* Only need the input image */ - this->SetNumberOfRequiredInputs(1); - - /* Instantiate all filters */ - m_GaussianFilter = GaussianFilterType::New(); - m_SubtractFilter = SubstractFilterType::New(); - m_MultiplyFilter = MultiplyFilterType::New(); - m_AddFilter = AddFilterType::New(); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateInputRequestedRegion() -{ - // This implementation is copied from itkDiscreteGaussianImageFilter - - // call the superclass' implementation of this method. this should - // copy the output requested region to the input requested region - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the input and output - typename Superclass::InputImagePointer inputPtr = const_cast(this->GetInput()); - - if (!inputPtr) - { - return; - } - - // Build an operator so that we can determine the kernel size - GaussianOperator oper; - - typename TInputImage::SizeType radius; - - for (unsigned int i = 0; i < TInputImage::ImageDimension; i++) - { - // Determine the size of the operator in this dimension. Note that the - // Gaussian is built as a 1D operator in each of the specified directions. - oper.SetDirection(i); - if (m_GaussianFilter->GetUseImageSpacing() == true) - { - if (this->GetInput()->GetSpacing()[i] == 0.0) - { - itkExceptionMacro(<< "Pixel spacing cannot be zero"); - } - else - { - // convert the variance from physical units to pixels - double s = this->GetInput()->GetSpacing()[i]; - s = s * s; - oper.SetVariance(m_GaussianFilter->GetVariance()[i] / s); - } - } - else - { - oper.SetVariance(m_GaussianFilter->GetVariance()[i]); - } - oper.SetMaximumError(m_GaussianFilter->GetMaximumError()[i]); - oper.SetMaximumKernelWidth(m_GaussianFilter->GetMaximumKernelWidth()); - oper.CreateDirectional(); - - radius[i] = oper.GetRadius(i); - } - - // get a copy of the input requested region (should equal the output - // requested region) - typename TInputImage::RegionType inputRequestedRegion; - inputRequestedRegion = inputPtr->GetRequestedRegion(); - - // pad the input requested region by the operator radius - inputRequestedRegion.PadByRadius(radius); - - // crop the input requested region at the input's largest possible region - if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) - { - inputPtr->SetRequestedRegion(inputRequestedRegion); - return; - } - else - { - // Couldn't crop the region (requested region is outside the largest - // possible region). Throw an exception. - - // store what we tried to request (prior to trying to crop) - inputPtr->SetRequestedRegion(inputRequestedRegion); - - // build an exception - InvalidRequestedRegionError e(__FILE__, __LINE__); - e.SetLocation(ITK_LOCATION); - e.SetDescription("Requested region is (at least partially) outside the largest possible region."); - e.SetDataObject(inputPtr); - throw e; - } -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::GenerateData() -{ - /* Get Input */ - typename TInputImage::Pointer input = TInputImage::New(); - input->Graft(const_cast(this->GetInput())); - - /* I*G */ - m_GaussianFilter->SetInput(input); - m_GaussianFilter->SetVariance(Math::squared_magnitude(this->GetSigma())); - - /* I - I*G */ - m_SubtractFilter->SetInput1(input); - m_SubtractFilter->SetInput2(m_GaussianFilter->GetOutput()); - - /* k(I-(I*G)) */ - m_MultiplyFilter->SetInput(m_SubtractFilter->GetOutput()); - m_MultiplyFilter->SetConstant(this->GetScalingConstant()); - - /* I+k*(I-(I*G)) */ - m_AddFilter->SetInput1(input); - m_AddFilter->SetInput2(m_MultiplyFilter->GetOutput()); - - /* Release data if asked */ - if (this->GetReleaseInternalFilterData()) - { - m_GaussianFilter->ReleaseDataFlagOn(); - m_SubtractFilter->ReleaseDataFlagOn(); - m_MultiplyFilter->ReleaseDataFlagOn(); - m_AddFilter->ReleaseDataFlagOn(); - } - - /* Setup progress reporter */ - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - progress->RegisterInternalFilter(m_GaussianFilter, 0.25); - progress->RegisterInternalFilter(m_SubtractFilter, 0.25); - progress->RegisterInternalFilter(m_MultiplyFilter, 0.25); - progress->RegisterInternalFilter(m_AddFilter, 0.25); - - /* Graft Output */ - m_AddFilter->Update(); - this->GraftOutput(m_AddFilter->GetOutput()); -} - -template -void -KrcahEigenToScalarPreprocessingImageToImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "GaussianFilter: " << m_GaussianFilter.GetPointer() << std::endl; - os << indent << "SubtractFilter: " << m_SubtractFilter.GetPointer() << std::endl; - os << indent << "MultiplyFilter: " << m_MultiplyFilter.GetPointer() << std::endl; - os << indent << "AddFilter: " << m_AddFilter.GetPointer() << std::endl; - os << indent << "Sigma: " << GetSigma() << std::endl; - os << indent << "ScalingConstant: " << GetScalingConstant() << std::endl; - os << indent << "ReleaseInternalFilterData: " << GetReleaseInternalFilterData() << std::endl; -} - -} // namespace itk - -#endif // itkKrcahEigenToScalarPreprocessingImageToImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h index 284bc2215a6..8f55da09576 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahPreprocessingImageToImageFilter.h @@ -121,15 +121,6 @@ class ITK_TEMPLATE_EXPORT KrcahPreprocessingImageToImageFilter : public ImageToI void GenerateData() override; - /** DiscreteGaussianImageFilter needs a larger input requested region - * than the output requested region (larger by the size of the - * Gaussian kernel). As such, DiscreteGaussianImageFilter needs to - * provide an implementation for GenerateInputRequestedRegion() in - * order to inform the pipeline execution model. - * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - virtual void - GenerateInputRequestedRegion() override; - void PrintSelf(std::ostream & os, Indent indent) const override; diff --git a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx index be64d5a50da..2cf8577d9f0 100644 --- a/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx +++ b/Modules/Filtering/BoneEnhancement/test/itkMaximumAbsoluteValueImageFilterUnitTest.cxx @@ -19,6 +19,7 @@ #include "itkMaximumAbsoluteValueImageFilter.h" #include "gtest/gtest.h" #include "itkImageRegionIterator.h" +#include "itkTestingMacros.h" TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) { @@ -28,7 +29,12 @@ TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) using MaximumAbsoluteValueImageFilterType = itk::MaximumAbsoluteValueImageFilter; MaximumAbsoluteValueImageFilterType::Pointer maxAbsFilter = MaximumAbsoluteValueImageFilterType::New(); - ITK_EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); + // if not wrapped in a lambda, produces error C2562: 'void' function returning a value + int basicMethods = [=]() -> int { + ITK_EXERCISE_BASIC_OBJECT_METHODS(maxAbsFilter, MaximumAbsoluteValueImageFilter, BinaryFunctorImageFilter); + return EXIT_SUCCESS; + }(); + ASSERT_EQ(basicMethods, EXIT_SUCCESS); /** Create an image and run a basic test */ ImageType::RegionType region; @@ -88,11 +94,11 @@ TEST(itkMaximumAbsoluteValueImageFilterUnitTest, TakesAbsMaxOfSimpleImages) { if ((i % 2) == 0) { - ITK_TEST_EXPECT_EQUAL(ot.Get(), -2); + ASSERT_EQ(ot.Get(), -2); } else { - ITK_TEST_EXPECT_EQUAL(ot.Get(), 2); + ASSERT_EQ(ot.Get(), 2); } ++ot; } diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap similarity index 88% rename from Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap rename to Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap index d5ce1a5acc1..b994883110b 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap @@ -1,4 +1,4 @@ -itk_wrap_class("itk::DescoteauxEigenToScalarImageFilter" POINTER) +itk_wrap_class("itk::DescoteauxEigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap similarity index 88% rename from Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap rename to Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap index 4f4a7ee5eb9..593cf5c2fb6 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap @@ -1,4 +1,4 @@ -itk_wrap_class("itk::EigenToScalarImageFilter" POINTER) +itk_wrap_class("itk::EigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) # Only defined for vectors of dimension 3 and images of dimension 3 diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap similarity index 84% rename from Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap rename to Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap index 273175aba3b..e02992fcb16 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap @@ -1,4 +1,4 @@ -itk_wrap_class("itk::KrcahEigenToScalarParameterEstimationImageFilter" POINTER) +itk_wrap_class("itk::KrcahEigenToMeasureParameterEstimationFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) # Only defined for vectors of dimension 3 and images of dimension 3 @@ -7,7 +7,7 @@ foreach(t1 ${WRAP_ITK_VECTOR_REAL}) endforeach() itk_end_wrap_class() -itk_wrap_class("itk::KrcahEigenToScalarImageFilter" POINTER) +itk_wrap_class("itk::KrcahEigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) foreach(t3 ${WRAP_ITK_SCALAR}) diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahPreprocessingImageToImageFilter.wrap similarity index 50% rename from Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap rename to Modules/Filtering/BoneEnhancement/wrapping/itkKrcahPreprocessingImageToImageFilter.wrap index 588cba91429..0d5f8b56357 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToScalarPreprocessingImageToImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahPreprocessingImageToImageFilter.wrap @@ -1,3 +1,3 @@ -itk_wrap_class("itk::KrcahEigenToScalarPreprocessingImageToImageFilter" POINTER_WITH_SUPERCLASS) +itk_wrap_class("itk::KrcahPreprocessingImageToImageFilter" POINTER_WITH_SUPERCLASS) itk_wrap_image_filter_combinations("${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}") itk_end_wrap_class() From a2287f4e57a6de4607126364996d3060e023d2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 19 Nov 2019 14:22:33 -0500 Subject: [PATCH 107/150] BUG: fix Python wrapping --- ...itkDescoteauxEigenToMeasureImageFilter.wrap | 11 +++-------- ...igenToMeasureParameterEstimationFilter.wrap | 5 +++++ .../wrapping/itkEigenToMeasureImageFilter.wrap | 9 ++++++--- .../itkKrcahEigenToMeasureImageFilter.wrap | 18 ++---------------- ...igenToMeasureParameterEstimationFilter.wrap | 5 +++++ 5 files changed, 21 insertions(+), 27 deletions(-) create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureParameterEstimationFilter.wrap create mode 100644 Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureParameterEstimationFilter.wrap diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap index b994883110b..9b1bbb21e01 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureImageFilter.wrap @@ -1,13 +1,8 @@ itk_wrap_class("itk::DescoteauxEigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() + foreach(t3 ${WRAP_ITK_REAL}) + # Only defined for vectors of dimension 3 and images of dimension 3 + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t3}3}") endforeach() endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureParameterEstimationFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureParameterEstimationFilter.wrap new file mode 100644 index 00000000000..31ec8ee9b31 --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkDescoteauxEigenToMeasureParameterEstimationFilter.wrap @@ -0,0 +1,5 @@ +itk_wrap_class("itk::DescoteauxEigenToMeasureParameterEstimationFilter" POINTER) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t1}33}" "${ITKT_I${t1}33}, ${ITKT_I${t1}33}") +endforeach() +itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap index 593cf5c2fb6..5dc7a570570 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkEigenToMeasureImageFilter.wrap @@ -1,3 +1,9 @@ +itk_wrap_class("itk::EigenToMeasureParameterEstimationFilter" POINTER) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t1}33}" "${ITKT_I${t1}33}, ${ITKT_I${t1}33}") +endforeach() +itk_end_wrap_class() + itk_wrap_class("itk::EigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) foreach(t2 ${WRAP_ITK_REAL}) @@ -5,7 +11,4 @@ foreach(t1 ${WRAP_ITK_VECTOR_REAL}) itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}") endforeach() endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap index e02992fcb16..83b7975f4aa 100644 --- a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureImageFilter.wrap @@ -1,22 +1,8 @@ -itk_wrap_class("itk::KrcahEigenToMeasureParameterEstimationFilter" POINTER) +itk_wrap_class("itk::KrcahEigenToMeasureImageFilter" POINTER) foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) + foreach(t3 ${WRAP_ITK_REAL}) # Only defined for vectors of dimension 3 and images of dimension 3 itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t3}3}") endforeach() endforeach() itk_end_wrap_class() - -itk_wrap_class("itk::KrcahEigenToMeasureImageFilter" POINTER) -foreach(t1 ${WRAP_ITK_VECTOR_REAL}) - foreach(t2 ${WRAP_ITK_REAL}) - foreach(t3 ${WRAP_ITK_SCALAR}) - # Only defined for vectors of dimension 3 and images of dimension 3 - itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t2}3}${ITKM_I${t3}3}" "${ITKT_I${t1}33}, ${ITKT_I${t2}3}, ${ITKT_I${t3}3}") - endforeach() - endforeach() -endforeach() - -# Currently, this doesn't work -#itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR_REAL}" "${WRAP_ITK_SCALAR}" "${WRAP_ITK_SCALAR}" 3) -itk_end_wrap_class() diff --git a/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureParameterEstimationFilter.wrap b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureParameterEstimationFilter.wrap new file mode 100644 index 00000000000..db338c808ab --- /dev/null +++ b/Modules/Filtering/BoneEnhancement/wrapping/itkKrcahEigenToMeasureParameterEstimationFilter.wrap @@ -0,0 +1,5 @@ +itk_wrap_class("itk::KrcahEigenToMeasureParameterEstimationFilter" POINTER) +foreach(t1 ${WRAP_ITK_VECTOR_REAL}) + itk_wrap_template("${ITKM_I${t1}33}${ITKM_I${t1}33}" "${ITKT_I${t1}33}, ${ITKT_I${t1}33}") +endforeach() +itk_end_wrap_class() From caa40651f05f99315cd4bf90e233b50277c270ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Fri, 22 Nov 2019 17:57:21 -0500 Subject: [PATCH 108/150] COMP: support running with legacy removed --- .../include/itkEigenToMeasureParameterEstimationFilter.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h index 268bd2ca51d..f5be4e187ef 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureParameterEstimationFilter.h @@ -111,6 +111,13 @@ class ITK_TEMPLATE_EXPORT EigenToMeasureParameterEstimationFilter void UpdateOutputData(DataObject * output) override; + /** Delegates work to DynamicThreadedGenerateData. */ + void + ThreadedGenerateData(const InputImageRegionType & region, ThreadIdType) override + { + this->DynamicThreadedGenerateData(region); + } + protected: EigenToMeasureParameterEstimationFilter(); virtual ~EigenToMeasureParameterEstimationFilter() {} From 0df83c82de0850f88f2e8ba79aeaf15b6c28d3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 26 Nov 2019 10:28:57 -0500 Subject: [PATCH 109/150] ENH: removing unused files These files were left over from refactoring. --- ...escoteauxEigenToScalarFunctorImageFilter.h | 259 --------------- ...ToScalarParameterEstimationImageFilter.hxx | 267 --------------- .../itkKrcahEigenToScalarFunctorImageFilter.h | 250 -------------- ...enToScalarParameterEstimationImageFilter.h | 239 -------------- ...ToScalarParameterEstimationImageFilter.hxx | 306 ------------------ 5 files changed, 1321 deletions(-) delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h delete mode 100644 Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h deleted file mode 100644 index b2916ac6c8d..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,259 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarFunctorImageFilter_h -#define itkDescoteauxEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class DescoteauxEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Descoteaux et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ - * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ - * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) - * \f} - * - * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. - * - * The parameter selection is done by DescoteauxEigentoScalarParameterEstimationImageFilter - * where the parameter \f$ c \f$ is scaled by the maximum of the Frobenius norm. - * - * \sa DescoteauxEigentoScalarParameterEstimationImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - using RealType = typename NumericTraits::RealType; - - DescoteauxEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Deal with l3 > 0 */ - if (m_Direction * a3 < 0) - { - return static_cast(0.0); - } - - /* Avoid divisions by zero (or close to zero) */ - if (l3 < Math::eps) - { - return static_cast(0.0); - } - - /* Compute measures */ - const double Rsheet = l2 / l3; - const double Rblob = Math::abs(2 * l3 - l2 - l1) / l3; - const double Rnoise = sqrt(l1 * l1 + l2 * l2 + l3 * l3); - - /* Multiply together to get sheetness */ - sheetness = 1.0; - sheetness *= std::exp(-(Rsheet * Rsheet) / (2 * m_Alpha * m_Alpha)); - sheetness *= (1.0 - std::exp(-(Rblob * Rblob) / (2 * m_Beta * m_Beta))); - sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (2 * m_C * m_C))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetC(const RealType c) - { - this->m_C = c; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetC() const - { - return this->m_C; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_C; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class DescoteauxEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Descoteaux et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Descoteaux et al. The parameters of the filter should be set using - * DescoteauxEigentoScalarParameterEstimationImageFilter. - * - * See functor DescoteauxEigenToScalarFunctor for mathematics. - * - * \sa DescoteauxEigenToScalarFunctor - * \sa DescoteauxEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class DescoteauxEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor> -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(DescoteauxEigenToScalarFunctorImageFilter); - - /** Standard Self type alias */ - using Self = DescoteauxEigenToScalarFunctorImageFilter; - using Superclass = UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::DescoteauxEigenToScalarFunctor>; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Useful type alias for numerics */ - typedef - typename Functor::DescoteauxEigenToScalarFunctor - DescoteauxFunctorType; - typedef typename DescoteauxFunctorType::RealType RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(DescoteauxEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - using InputParameterDecoratorType = SimpleDataObjectDecorator; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(C, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() override - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetC(this->GetCInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - DescoteauxEigenToScalarFunctorImageFilter() {} - virtual ~DescoteauxEigenToScalarFunctorImageFilter() {} - -private: - void - PrintSelf(std::ostream & os, Indent indent) const override - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "C: " << GetC() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkDescoteauxEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index 1b326b44b51..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,267 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx -#define itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkDescoteauxEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -DescoteauxEigenToScalarParameterEstimationImageFilter:: - DescoteauxEigenToScalarParameterEstimationImageFilter() - : m_FrobeniusNormWeight(0.5f) - , m_BackgroundValue(NumericTraits::Zero) - , m_MaxFrobeniusNorm(1) -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } - this->DynamicMultiThreadingOff(); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); - - /* Resize threads */ - m_MaxFrobeniusNorm.SetSize(numberOfThreads); - m_MaxFrobeniusNorm.Fill(NumericTraits::ZeroValue()); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); - - /* Determine default parameters */ - RealType alpha, beta, c; - alpha = 0.5f; - beta = 0.5f; - c = m_FrobeniusNormWeight; - - /* Accumulate over threads */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - if (m_MaxFrobeniusNorm[i] > maxFrobeniusNorm) - { - maxFrobeniusNorm = m_MaxFrobeniusNorm[i]; - } - } - - /* Scale c */ - if (maxFrobeniusNorm > 0) - { - c = c * maxFrobeniusNorm; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetCOutput()->Set(c); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Count starts zero */ - RealType maxFrobeniusNorm = NumericTraits::ZeroValue(); - RealType thisFrobeniusNorm; - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - /* Compute max norm */ - thisFrobeniusNorm = this->CalculateFrobeniusNorm(inputIt.Get()); - if (thisFrobeniusNorm > maxFrobeniusNorm) - { - maxFrobeniusNorm = thisFrobeniusNorm; - } - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_MaxFrobeniusNorm[threadId] = maxFrobeniusNorm; -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealType -DescoteauxEigenToScalarParameterEstimationImageFilter::CalculateFrobeniusNorm( - InputPixelType pixel) -{ - /* Forbenius norm is given by the square root of the sum of squares - * of the eigenvalues for real, symmetric matricies - */ - RealType norm = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - norm += pixel[i] * pixel[i]; - } - return sqrt(norm); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename DescoteauxEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -DescoteauxEigenToScalarParameterEstimationImageFilter::GetCOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -DescoteauxEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << this->GetAlpha() << std::endl; - os << indent << "Beta: " << this->GetBeta() << std::endl; - os << indent << "C: " << this->GetC() << std::endl; - os << indent << "BackgroundValue: " << GetBackgroundValue() << std::endl; - os << indent << "FrobeniusNormWeight: " << GetFrobeniusNormWeight() << std::endl; -} - -} // namespace itk - -#endif // itkDescoteauxEigenToScalarParameterEstimationImageFilter_hxx diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h deleted file mode 100644 index ebbf77e36fd..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarFunctorImageFilter.h +++ /dev/null @@ -1,250 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarFunctorImageFilter_h -#define itkKrcahEigenToScalarFunctorImageFilter_h - -#include "itkUnaryFunctorImageFilter.h" -#include "itkNumericTraits.h" -#include "itkMath.h" -#include "itkSimpleDataObjectDecorator.h" - -namespace itk -{ -namespace Functor -{ -/** \class KrcahEigenToScalarFunctor - * \brief Eigenvalue to scalar functor as defined by Krcah et al. - * - * Computes the following equation for eigenvalues in a three - * dimensional fixed array: - * \f{eqnarray*}{ - * R_{sheet} &=& \frac{|\lambda_2|}{\lambda_3|} \\ - * R_{tube} &=& \frac{\lambda_1|}{|\lambda_2| \cdot \lambda_3|} \\ - * R_{noise} &=& \lambda_1| + |\lambda_2| + \lambda_3| \\ - * s &=& sign(\lambda_3) \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \exp\left(- \frac{R_{tube}^2}{\beta^2} - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) - * \f} - * - * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. - * - * \sa KrcahEigentoScalarParameterEstimationImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctor -{ -public: - /* Basic type definitions */ - using RealType = typename NumericTraits::RealType; - - KrcahEigenToScalarFunctor() - : m_Direction(-1.0) - {} - - inline TOutputPixel - operator()(const TInputPixel & A) - { - double sheetness = 0.0; - double a1 = static_cast(A[0]); - double a2 = static_cast(A[1]); - double a3 = static_cast(A[2]); - double l1 = Math::abs(a1); - double l2 = Math::abs(a2); - double l3 = Math::abs(a3); - - /* Avoid divisions by zero (or close to zero) */ - if (static_cast(l3) < Math::eps || static_cast(l2) < Math::eps) - { - return static_cast(sheetness); - } - - /** - * Compute sheet, noise, and tube like measures. Note that the average trace of the - * Hessian matrix is implicitly included in \f$ \gamma \f$ here. - */ - const double Rsheet = l2 / l3; - const double Rnoise = (l1 + l2 + l3); // T implicite in m_Gamma - const double Rtube = l1 / (l2 * l3); - - /* Multiply together to get sheetness */ - sheetness = (m_Direction * a3 / l3); - sheetness *= std::exp(-(Rsheet * Rsheet) / (m_Alpha * m_Alpha)); - sheetness *= std::exp(-(Rtube * Rtube) / (m_Beta * m_Beta)); - sheetness *= (1.0 - std::exp(-(Rnoise * Rnoise) / (m_Gamma * m_Gamma))); - - return static_cast(sheetness); - } - - /** Macro definition for set/get of parameters */ - virtual void - SetAlpha(const RealType alpha) - { - this->m_Alpha = alpha; - } - virtual void - SetBeta(const RealType beta) - { - this->m_Beta = beta; - } - virtual void - SetGamma(const RealType gamma) - { - this->m_Gamma = gamma; - } - RealType - GetAlpha() const - { - return this->m_Alpha; - } - RealType - GetBeta() const - { - return this->m_Beta; - } - RealType - GetGamma() const - { - return this->m_Gamma; - } - - /** Set/get the type to enhance */ - void - SetEnhanceBrightObjects() - { - m_Direction = -1.0; - } - void - SetEnhanceDarkObjects() - { - m_Direction = 1.0; - } - RealType - GetEnhanceType() const - { - return m_Direction; - } - -private: - /* Private member variables */ - RealType m_Alpha; - RealType m_Beta; - RealType m_Gamma; - RealType m_Direction; -}; // end class -} // namespace Functor - -/** \class KrcahEigenToScalarFunctorImageFilter - * \brief Convert eigenvalues into a measure of sheetness according to the method of Krcah et al. - * - * Converts a 3D fixed array of eigenvalues into a measure of sheetness according to the method - * of Krcah et al. The parameters of the filter should be set using KrcahEigentoScalarParameterEstimationImageFilter. - * - * See functor for mathematics. - * - * \sa KrcahEigenToScalarFunctor - * \sa KrcahEigenToScalarImageFilter - * - * \author: Thomas Fitze - * \ingroup BoneEnhancement - */ -template -class KrcahEigenToScalarFunctorImageFilter - : public UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor> -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarFunctorImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarFunctorImageFilter; - using Superclass = UnaryFunctorImageFilter< - TInputImage, - TOutputImage, - Functor::KrcahEigenToScalarFunctor>; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Useful type alias for numerics */ - using KrcahFunctorType = - typename Functor::KrcahEigenToScalarFunctor; - using RealType = typename KrcahFunctorType::RealType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Runtime information support. */ - itkTypeMacro(KrcahEigenToScalarFunctorImageFilter, UnaryFunctorImageFilter); - - /** Define decorator types */ - using InputParameterDecoratorType = SimpleDataObjectDecorator; - - /** Process object */ - itkSetGetDecoratedInputMacro(Alpha, RealType); - itkSetGetDecoratedInputMacro(Beta, RealType); - itkSetGetDecoratedInputMacro(Gamma, RealType); - - /** Need to access the input parameters at execution time */ - void - BeforeThreadedGenerateData() override - { - /* Set functor parameters after a call to Update() to make sure the input parameters resolve */ - this->GetFunctor().SetAlpha(this->GetAlphaInput()->Get()); - this->GetFunctor().SetBeta(this->GetBetaInput()->Get()); - this->GetFunctor().SetGamma(this->GetGammaInput()->Get()); - } - - /** setter/getter methods for setting type of object to enhance */ - void - SetEnhanceBrightObjects() - { - this->GetFunctor().SetEnhanceBrightObjects(); - } - void - SetEnhanceDarkObjects() - { - this->GetFunctor().SetEnhanceDarkObjects(); - } - RealType - GetEnhanceType() const - { - return this->GetFunctor().GetEnhanceType(); - } - -protected: - KrcahEigenToScalarFunctorImageFilter() {} - virtual ~KrcahEigenToScalarFunctorImageFilter() {} - -private: - void - PrintSelf(std::ostream & os, Indent indent) const override - { - Superclass::PrintSelf(os, indent); - os << indent << "Alpha: " << GetAlpha() << std::endl; - os << indent << "Beta: " << GetBeta() << std::endl; - os << indent << "Gamma: " << GetGamma() << std::endl; - os << indent << "EnhanceType: " << GetEnhanceType() << std::endl; - } -}; // end class -} // namespace itk - -#endif // itkKrcahEigenToScalarFunctorImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h deleted file mode 100644 index 452b4056f0a..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.h +++ /dev/null @@ -1,239 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_h -#define itkKrcahEigenToScalarParameterEstimationImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkNumericTraits.h" -#include "itkSimpleDataObjectDecorator.h" -#include "itkArray.h" - -namespace itk -{ -/** \class KrcahEigenToScalarParameterEstimationImageFilter - * \brief Automatic parameter estimation for the Krcah method - * - * This class takes an image of eigenvalues and estimates the parameters for the Krcah - * bone enhanced filter. According to the original paper, - * \f{eqnarray*}{ - * \alpha &=& 0.5 \\ - * \beta &=& 0.5 \\ - * \gamma &=& 0.25 - * \f} - * However, this does not include scaling \f$ R_noise \f$ by the trace of the matrix. - * The trace of the matrix can be computed directly from the eigenvalues as the sum - * of the eigenvalues. - * - * In this implementation, the average of the trace is moved into the constant - * \f$ \gamma \f$. This is done to seperate parameter estimation from the unary - * functor. The modification is very simple. If the average of the trace is - * denoted \f$ T \f$ the new parameter becomes: - * \f{ - * \gamma &=& 0.25 \cdot T - * \f} - * - * However, the code was implemented different than described in the original - * paper. In the implementation, \f$ R_noise \f$ is scaled by the sum - * of the absolute value of the eigenvalues NOT the sum of the eigenvalues. - * Furthermore, all parameters were scaled by a factor of 2 in the implementation - * and \f$ \gamma \f$ was set to 0.5 of the average sum of absolute value of the - * eigenvalues. To account for these discrepancies, the flag KrcahImplementationType - * can be set which enables the implementation parameters: - * \f{eqnarray*}{ - * \alpha &=& \sqrt{2} \cdot 0.5 \\ - * \beta &=& \sqrt{2} \cdot 0.5 \\ - * \gamma &=& \sqrt{2} \cdot 0.5 \cdot T - * \f} - * Default is to use parameters from the implementation, not the paper. - * - * Finally, a mask can be provided. Metal or non-standard objects in the field - * of view may throw off the parameter estimation. In those cases, a mask can - * be provided so those voxels are not factored into the calculation of \f$ T \f$. - * - * If the input image and mask have different regions over which they - * are defined, parameters are estimated only in the intersection of - * the two image regions. However, the mask region must be a proper sub - * subset (contained) in the image region. - * - * \sa KrcahEigenToScalarImageFilter - * - * \author: Bryce Besler - * \ingroup BoneEnhancement - */ -template -class ITK_TEMPLATE_EXPORT KrcahEigenToScalarParameterEstimationImageFilter - : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_ASSIGN(KrcahEigenToScalarParameterEstimationImageFilter); - - /** Standard Self type alias */ - using Self = KrcahEigenToScalarParameterEstimationImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(KrcahEigenToScalarParameterEstimationImageFilter, ImageToImageFilter); - - /** Image related type alias. */ - using InputImagePointer = typename TInputImage::Pointer; - using InputImageConstPointer = typename TInputImage::ConstPointer; - using InputRegionType = typename TInputImage::RegionType; - using InputSizeType = typename TInputImage::SizeType; - using InputIndexType = typename TInputImage::IndexType; - using InputPixelType = typename TInputImage::PixelType; - using InputPixelValueType = typename InputPixelType::ValueType; - - /** Output region definitions */ - using OutputRegionType = InputRegionType; - - /** Mask related type alias. */ - using MaskImagePointer = typename TMaskImage::Pointer; - using MaskImageConstPointer = typename TMaskImage::ConstPointer; - using MaskPixelType = typename TMaskImage::PixelType; - using MaskRegionType = typename TMaskImage::RegionType; - - /** Methods to set/get the mask image */ - itkSetInputMacro(MaskImage, TMaskImage); - itkGetInputMacro(MaskImage, TMaskImage); - - /** Iterator types */ - itkSetMacro(BackgroundValue, MaskPixelType); - itkGetConstMacro(BackgroundValue, MaskPixelType); - - typedef enum - { - UseImplementationParameters = 1, - UseJournalParameters - } KrcahImplementationType; - itkSetMacro(ParameterSet, KrcahImplementationType); - itkGetConstMacro(ParameterSet, KrcahImplementationType); - - /* Set parameter set */ - void - SetParameterSetToImplementation() - { - this->SetParameterSet(UseImplementationParameters); - } - - void - SetParameterSetToJournalArticle() - { - this->SetParameterSet(UseJournalParameters); - } - - /** Parameters */ - using RealType = typename NumericTraits::RealType; - using RealTypeDecoratedType = SimpleDataObjectDecorator; - - /** Decorators for parameters so they can be passed as a process object */ - RealTypeDecoratedType * - GetAlphaOutput(); - const RealTypeDecoratedType * - GetAlphaOutput() const; - RealTypeDecoratedType * - GetBetaOutput(); - const RealTypeDecoratedType * - GetBetaOutput() const; - RealTypeDecoratedType * - GetGammaOutput(); - const RealTypeDecoratedType * - GetGammaOutput() const; - - /** Standard getters for the output parameters */ - RealType - GetAlpha() const - { - return this->GetAlphaOutput()->Get(); - } - RealType - GetBeta() const - { - return this->GetBetaOutput()->Get(); - } - RealType - GetGamma() const - { - return this->GetGammaOutput()->Get(); - } - -#ifdef ITK_USE_CONCEPT_CHECKING - // Begin concept checking - itkConceptMacro(InputHaveDimension3Check, (Concept::SameDimension)); - // End concept checking -#endif -protected: - KrcahEigenToScalarParameterEstimationImageFilter(); - virtual ~KrcahEigenToScalarParameterEstimationImageFilter() {} - - /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ - void - AllocateOutputs() override; - - /** Initialize some accumulators before the threads run. */ - void - BeforeThreadedGenerateData() override; - - /** Do final mean and variance computation from data accumulated in threads. */ - void - AfterThreadedGenerateData() override; - - /** Multi-thread version GenerateData. */ - void - ThreadedGenerateData(const OutputRegionType & outputRegionForThread, ThreadIdType threadId) override; - - /** Override since the filter needs all the data for the algorithm */ - void - GenerateInputRequestedRegion() override; - - /** Override since the filter produces all of its output */ - void - EnlargeOutputRequestedRegion(DataObject * data) override; - - void - PrintSelf(std::ostream & os, Indent indent) const override; - - /** Calculation of \f$ T \f$ changes depending on the implementation */ - inline RealType - CalculateTraceAccordingToImplementation(InputPixelType pixel); - inline RealType - CalculateTraceAccordingToJournalArticle(InputPixelType pixel); - -private: - /* Parameters */ - KrcahImplementationType m_ParameterSet{ UseImplementationParameters }; - - /* Inputs */ - MaskPixelType m_BackgroundValue{ NumericTraits::Zero }; - - /* Arrays for threads */ - Array m_AccumulatedAverageTrace{ 1 }; - Array m_NumVoxels{ 1 }; -}; // end class -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkKrcahEigenToScalarParameterEstimationImageFilter.hxx" -#endif - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_h diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx deleted file mode 100644 index bf6bf2d4af4..00000000000 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToScalarParameterEstimationImageFilter.hxx +++ /dev/null @@ -1,306 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software 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 - * - * 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. - * - *=========================================================================*/ - -#ifndef itkKrcahEigenToScalarParameterEstimationImageFilter_hxx -#define itkKrcahEigenToScalarParameterEstimationImageFilter_hxx - -#include "itkKrcahEigenToScalarParameterEstimationImageFilter.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkProgressReporter.h" -#include "itkMath.h" - -namespace itk -{ -template -KrcahEigenToScalarParameterEstimationImageFilter::KrcahEigenToScalarParameterEstimationImageFilter() -{ - /* We require an input, optional mask */ - this->SetNumberOfRequiredInputs(1); - this->SetNumberOfRequiredOutputs(4); - - /* Allocate all decorators */ - for (int i = 1; i < 4; ++i) - { - typename RealTypeDecoratedType::Pointer output = RealTypeDecoratedType::New(); - output->Set(0.5); - this->ProcessObject::SetNthOutput(i, output.GetPointer()); - } - this->DynamicMultiThreadingOff(); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AllocateOutputs() -{ - /* Pass the input through as the output */ - InputImagePointer image = const_cast(this->GetInput()); - this->GraftOutput(image); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - if (this->GetInput()) - { - InputImagePointer image = const_cast(this->GetInput()); - image->SetRequestedRegionToLargestPossibleRegion(); - } - if (this->GetMaskImage()) - { - MaskImagePointer mask = const_cast(this->GetMaskImage()); - mask->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::EnlargeOutputRequestedRegion( - DataObject * data) -{ - Superclass::EnlargeOutputRequestedRegion(data); - data->SetRequestedRegionToLargestPossibleRegion(); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::BeforeThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); - - /* Resize threads */ - m_AccumulatedAverageTrace.SetSize(numberOfThreads); - m_NumVoxels.SetSize(numberOfThreads); - - m_AccumulatedAverageTrace.Fill(NumericTraits::ZeroValue()); - m_NumVoxels.Fill(NumericTraits::ZeroValue()); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::AfterThreadedGenerateData() -{ - ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits(); - - /* Determine default parameters */ - RealType alpha, beta, gamma; - switch (m_ParameterSet) - { - case UseImplementationParameters: - alpha = Math::sqrt2 * 0.5f; - beta = Math::sqrt2 * 0.5f; - gamma = Math::sqrt2 * 0.5f; - break; - case UseJournalParameters: - alpha = 0.5f; - beta = 0.5f; - gamma = 0.25f; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Accumulate over threads */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - for (unsigned int i = 0; i < numberOfThreads; ++i) - { - numVoxels += m_NumVoxels[i]; - accumulatedAverageTrace += m_AccumulatedAverageTrace[i]; - } - - /* Do derived measure */ - if (numVoxels > 0) - { - RealType averageTrace = (RealType)accumulatedAverageTrace / (RealType)numVoxels; - gamma = gamma * averageTrace; - } - - /* Assign outputs parameters */ - this->GetAlphaOutput()->Set(alpha); - this->GetBetaOutput()->Set(beta); - this->GetGammaOutput()->Set(gamma); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::ThreadedGenerateData( - const OutputRegionType & outputRegionForThread, - ThreadIdType threadId) -{ - /* Determine which function to call */ - RealType (Self::*traceFunction)(InputPixelType); - switch (m_ParameterSet) - { - case UseImplementationParameters: - traceFunction = &Self::CalculateTraceAccordingToImplementation; - break; - case UseJournalParameters: - traceFunction = &Self::CalculateTraceAccordingToJournalArticle; - break; - default: - itkExceptionMacro(<< "Have bad parameterset enumeration " << m_ParameterSet); - break; - } - - /* Count starts zero */ - SizeValueType numVoxels = NumericTraits::ZeroValue(); - RealType accumulatedAverageTrace = NumericTraits::ZeroValue(); - - /* Get input pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - - /* Get mask pointer */ - MaskImageConstPointer maskPointer = this->GetMaskImage(); - - /* If we have a mask pointer we need to crop outputRegionForThread to the mask region */ - InputRegionType croppedRegion = outputRegionForThread; - if (maskPointer) - { - croppedRegion.Crop(maskPointer->GetLargestPossibleRegion()); - /* No check for one region being inside the other. Superclass::GenerateInputRequestedRegion() - * takes care of the case of the mask region being outside the image region. It's actually - * impossible to determine if the mask region is valid inside ThreadedGenerateData because - * outputRegionForThread is a sub region of the output region. - */ - } - - /* If size is zero, return */ - const SizeValueType size0 = croppedRegion.GetSize(0); - if (size0 == 0) - { - return; - } - - /* Setup progress reporter */ - ProgressReporter progress(this, threadId, croppedRegion.GetNumberOfPixels()); - - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, croppedRegion); - - /* Iterate and count */ - inputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - if ((!maskPointer) || (maskPointer->GetPixel(inputIt.GetIndex()) != m_BackgroundValue)) - { - numVoxels++; - - /* Compute trace */ - accumulatedAverageTrace += (this->*traceFunction)(inputIt.Get()); - } - ++inputIt; - progress.CompletedPixel(); - } - - /* Store this thread */ - m_AccumulatedAverageTrace[threadId] = accumulatedAverageTrace; - m_NumVoxels[threadId] = numVoxels; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToImplementation( - InputPixelType pixel) -{ - /* Sum of the absolute value of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += Math::abs(pixel[i]); - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealType -KrcahEigenToScalarParameterEstimationImageFilter::CalculateTraceAccordingToJournalArticle( - InputPixelType pixel) -{ - /* Sum of the eigenvalues */ - RealType trace = 0; - for (unsigned int i = 0; i < pixel.Length; ++i) - { - trace += pixel[i]; - } - return trace; -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetAlphaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(1)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetBetaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(2)); -} - -template -typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -const typename KrcahEigenToScalarParameterEstimationImageFilter::RealTypeDecoratedType * -KrcahEigenToScalarParameterEstimationImageFilter::GetGammaOutput() const -{ - return static_cast(this->ProcessObject::GetOutput(3)); -} - -template -void -KrcahEigenToScalarParameterEstimationImageFilter::PrintSelf(std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "m_Alpha: " << this->GetAlpha() << std::endl; - os << indent << "m_Beta: " << this->GetBeta() << std::endl; - os << indent << "m_Gamma: " << this->GetGamma() << std::endl; - os << indent << "m_BackgroundValue: " << m_BackgroundValue << std::endl; - os << indent << "m_ParameterSet: " << m_ParameterSet << std::endl; -} - -} // end namespace itk - -#endif // itkKrcahEigenToScalarParameterEstimationImageFilter_hxx From 91ff1cfbc865a119f0863754cfd4f97fd6b40e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 26 Nov 2019 09:45:29 -0500 Subject: [PATCH 110/150] ENH: parallelizing EigenToMeasureParameterEstimation filters --- ...igenToMeasureParameterEstimationFilter.hxx | 75 +++++++++-------- ...igenToMeasureParameterEstimationFilter.hxx | 80 ++++++++++--------- 2 files changed, 84 insertions(+), 71 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx index 49cea7708e9..ca265038d20 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureParameterEstimationFilter.hxx @@ -83,13 +83,9 @@ DescoteauxEigenToMeasureParameterEstimationFilter::Dy return; } - /* Keep track of the current max */ - RealType max = NumericTraits::NonpositiveMin(); - /* Get input and mask pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); - typename InputImageType::PointType point; + InputImageConstPointer inputPointer = this->GetInput(); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); OutputImageType * outputPtr = this->GetOutput(0); @@ -100,34 +96,45 @@ DescoteauxEigenToMeasureParameterEstimationFilter::Dy this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); - ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - - /* Iterate and count */ - inputIt.GoToBegin(); - outputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - // Process point - inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) - { - /* Compute max norm */ - max = std::max(max, this->CalculateFrobeniusNorm(inputIt.Get())); - } - - // Set - outputIt.Set(static_cast(inputIt.Get())); - - // Increment - ++inputIt; - ++outputIt; - } - - /* Block and store */ - std::lock_guard mutexHolder(m_Mutex); - m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); + MultiThreaderBase::Pointer mt = this->GetMultiThreader(); + + mt->ParallelizeImageRegion( + outputRegionForThread, + [inputPointer, maskPointer, outputPtr, this](const OutputImageRegionType region) { + /* Keep track of the current max */ + RealType max = NumericTraits::NonpositiveMin(); + + typename InputImageType::PointType point; + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); + ImageRegionIterator outputIt(outputPtr, region); + + /* Iterate and count */ + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) + { + /* Compute max norm */ + max = std::max(max, this->CalculateFrobeniusNorm(inputIt.Get())); + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + + /* Block and store */ + std::lock_guard mutexHolder(m_Mutex); + m_MaxFrobeniusNorm = std::max(m_MaxFrobeniusNorm, max); + }, + nullptr); } template diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx index be7fdbbf897..46e00be4241 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureParameterEstimationFilter.hxx @@ -117,14 +117,9 @@ KrcahEigenToMeasureParameterEstimationFilter::Dynamic break; } - /* Keep track of the current max */ - RealType accum = NumericTraits::ZeroValue(); - RealType count = NumericTraits::ZeroValue(); - /* Get input and mask pointer */ - InputImageConstPointer inputPointer = this->GetInput(); - MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); - typename InputImageType::PointType point; + InputImageConstPointer inputPointer = this->GetInput(); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); OutputImageType * outputPtr = this->GetOutput(0); @@ -135,36 +130,47 @@ KrcahEigenToMeasureParameterEstimationFilter::Dynamic this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); - /* Setup iterator */ - ImageRegionConstIteratorWithIndex inputIt(inputPointer, inputRegionForThread); - ImageRegionIterator outputIt(outputPtr, outputRegionForThread); - - /* Iterate and count */ - inputIt.GoToBegin(); - outputIt.GoToBegin(); - while (!inputIt.IsAtEnd()) - { - // Process point - inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) - { - /* Compute trace */ - count++; - accum += (this->*traceFunction)(inputIt.Get()); - } - - // Set - outputIt.Set(static_cast(inputIt.Get())); - - // Increment - ++inputIt; - ++outputIt; - } - - /* Block and store */ - std::lock_guard mutexHolder(m_Mutex); - m_ThreadCount += count; - m_ThreadAccumulatedTrace += accum; + MultiThreaderBase::Pointer mt = this->GetMultiThreader(); + + mt->ParallelizeImageRegion( + outputRegionForThread, + [inputPointer, maskPointer, outputPtr, this, traceFunction](const OutputImageRegionType region) { + /* Keep track of the current accumulation */ + RealType accum = NumericTraits::ZeroValue(); + RealType count = NumericTraits::ZeroValue(); + + typename InputImageType::PointType point; + + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPointer, region); + ImageRegionIterator outputIt(outputPtr, region); + + /* Iterate and count */ + while (!inputIt.IsAtEnd()) + { + // Process point + inputPointer->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) + { + /* Compute trace */ + count++; + accum += (this->*traceFunction)(inputIt.Get()); + } + + // Set + outputIt.Set(static_cast(inputIt.Get())); + + // Increment + ++inputIt; + ++outputIt; + } + + /* Block and store */ + std::lock_guard mutexHolder(m_Mutex); + m_ThreadCount += count; + m_ThreadAccumulatedTrace += accum; + }, + nullptr); } template From 65b654f0b85c916581559cd31d743a41d06dc6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Tue, 26 Nov 2019 09:58:11 -0500 Subject: [PATCH 111/150] ENH: parallelize EigenToMeasure filter --- .../include/itkEigenToMeasureImageFilter.hxx | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx index 4eba55f4bba..f498592ce08 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx +++ b/Modules/Filtering/BoneEnhancement/include/itkEigenToMeasureImageFilter.hxx @@ -32,10 +32,9 @@ EigenToMeasureImageFilter::DynamicThreadedGenerateDat const OutputImageRegionType & outputRegionForThread) { /* Get Inputs */ - InputImageConstPointer inputPtr = this->GetInput(0); - OutputImagePointer outputPtr = this->GetOutput(0); - MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); - typename InputImageType::PointType point; + InputImageConstPointer inputPtr = this->GetInput(0); + OutputImagePointer outputPtr = this->GetOutput(0); + MaskSpatialObjectTypeConstPointer maskPointer = this->GetMask(); // Define the portion of the input to walk for this thread, using // the CallCopyOutputRegionToInputRegion method allows for the input @@ -43,27 +42,34 @@ EigenToMeasureImageFilter::DynamicThreadedGenerateDat InputImageRegionType inputRegionForThread; this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); - // Define the iterators - ImageRegionConstIteratorWithIndex inputIt(inputPtr, inputRegionForThread); - ImageRegionIterator outputIt(outputPtr, outputRegionForThread); + MultiThreaderBase::Pointer mt = this->GetMultiThreader(); - inputIt.GoToBegin(); - outputIt.GoToBegin(); + mt->ParallelizeImageRegion( + outputRegionForThread, + [inputPtr, maskPointer, outputPtr, this](const OutputImageRegionType region) { + typename InputImageType::PointType point; - while (!inputIt.IsAtEnd()) - { - inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); - if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) - { - outputIt.Set(ProcessPixel(inputIt.Get())); - } - else - { - outputIt.Set(NumericTraits::Zero); - } - ++inputIt; - ++outputIt; - } + /* Setup iterator */ + ImageRegionConstIteratorWithIndex inputIt(inputPtr, region); + ImageRegionIterator outputIt(outputPtr, region); + + while (!inputIt.IsAtEnd()) + { + inputPtr->TransformIndexToPhysicalPoint(inputIt.GetIndex(), point); + if ((!maskPointer) || (maskPointer->IsInsideInObjectSpace(point))) + { + outputIt.Set(this->ProcessPixel(inputIt.Get())); + } + else + { + outputIt.Set(NumericTraits::Zero); + } + + ++inputIt; + ++outputIt; + } + }, + nullptr); } } // namespace itk From 2c72ac5bb5ff2b1f2142551de708f0f5ab9aeb34 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 19 Feb 2020 14:51:37 -0600 Subject: [PATCH 112/150] ENH: Add .gitattributes to allow running ITK clang-formatting scripts ``` git filter-branch -f \ --tree-filter "~/ITK/Utilities/Maintenance/clang-format.bash --clang-format ~/Dashboard/src/ITK-clang11/clang-format-Linux --tracked" \ master.. ``` --- .../include/itkDescoteauxEigenToMeasureImageFilter.h | 3 +-- .../include/itkKrcahEigenToMeasureImageFilter.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index 2550d1014ae..c987cf59371 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -37,8 +37,7 @@ namespace itk * R_{blob} &=& \frac{|2 |\lambda_3| - |\lambda_2| - |\lambda_1| |}{|\lambda_3|} \\ * R_{noise} &=& \sqrt{|\lambda_1|^2 + |\lambda_2|^2 + \lambda_3|^2} \\ * s &=& \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \left(1 - \exp\left(- \frac{R_{blob}^2}{\beta^2} \right) - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) - * \f} + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{c^2} \right) \right) \f} * * Note that if \f$ \lambda_3 > 0 \f$, \f$ s = 0 \f$. * diff --git a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h index f1f921f9290..61037355492 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkKrcahEigenToMeasureImageFilter.h @@ -37,8 +37,7 @@ namespace itk * R_{tube} &=& \frac{\lambda_1|}{|\lambda_2| \cdot \lambda_3|} \\ * R_{noise} &=& \lambda_1| + |\lambda_2| + \lambda_3| \\ * s &=& sign(\lambda_3) \exp\left(- \frac{R_{sheet}^2}{\alpha^2} \right) \exp\left(- \frac{R_{tube}^2}{\beta^2} - * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) - * \f} + * \right) \left(1 - \exp\left(- \frac{R_{noise}^2}{\gamma^2} \right) \right) \f} * * The scaling by the average trace of the Hessian matrix is implicit in \f$ \gamma \f$. * From cfd7e72963b63816317fcb58a5b6700ce3f20b63 Mon Sep 17 00:00:00 2001 From: Mathew Seng Date: Fri, 13 Dec 2019 12:40:47 -0600 Subject: [PATCH 113/150] ENH: Adding new scoped enumerations Changed SigmaStepMethodEnum to scoped enum class Changed EigenValueOrderType to EigenValueOrderEnum enum class Creation of KrachImplementationEnum --- .../itkDescoteauxEigenToMeasureImageFilter.h | 2 +- .../include/itkEigenToMeasureImageFilter.h | 18 +++++++++++---- .../itkKrcahEigenToMeasureImageFilter.h | 2 +- ...hEigenToMeasureParameterEstimationFilter.h | 23 ++++++++++++++----- ...igenToMeasureParameterEstimationFilter.hxx | 6 ++--- ...kMultiScaleHessianEnhancementImageFilter.h | 13 ++++++++--- ...teauxEigenToMeasureImageFilterUnitTest.cxx | 2 +- 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h index c987cf59371..69e48502b65 100644 --- a/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h +++ b/Modules/Filtering/BoneEnhancement/include/itkDescoteauxEigenToMeasureImageFilter.h @@ -85,7 +85,7 @@ class DescoteauxEigenToMeasureImageFilter : public EigenToMeasureImageFilter