diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 9b3b188..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.16.3 FATAL_ERROR) -project(HigherOrderAccurateGradient) - -if(NOT ITK_SOURCE_DIR) - find_package(ITK REQUIRED) - list(APPEND CMAKE_MODULE_PATH ${ITK_CMAKE_DIR}) - include(ITKModuleExternal) -else() - itk_module_impl() -endif() diff --git a/CTestConfig.cmake b/CTestConfig.cmake deleted file mode 100644 index efccad4..0000000 --- a/CTestConfig.cmake +++ /dev/null @@ -1,7 +0,0 @@ -set(CTEST_PROJECT_NAME "ITK") -set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC") - -set(CTEST_DROP_METHOD "https") -set(CTEST_DROP_SITE "open.cdash.org") -set(CTEST_DROP_LOCATION "/submit.php?project=Insight") -set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac1bf0a --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Migrated to ITK main + +The `HigherOrderAccurateGradient` module has been ingested into the Insight Toolkit (ITK) main repository and is no longer maintained here. + +- **In-tree location:** [`Modules/Filtering/HigherOrderAccurateGradient`](https://github.com/InsightSoftwareConsortium/ITK/tree/main/Modules/Filtering/HigherOrderAccurateGradient) +- **Ingest PR:** [InsightSoftwareConsortium/ITK#6242](https://github.com/InsightSoftwareConsortium/ITK/pull/6242) +- **Merge commit:** [`970bba73bb`](https://github.com/InsightSoftwareConsortium/ITK/commit/970bba73bbd657ba8199d14af807a471da6d759a) + +Future development, bug fixes, and pull requests should target ITK main. This repository's history is preserved for `git blame` and archival reference. + +**Maintainer action:** please mark this repository **Archived** under repo Settings -> Danger Zone after merging this PR. See the [ITK ingestion strategy](https://github.com/InsightSoftwareConsortium/ITK/blob/main/Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md) for context. diff --git a/include/itkHigherOrderAccurateDerivativeImageFilter.h b/include/itkHigherOrderAccurateDerivativeImageFilter.h deleted file mode 100644 index cddcfd1..0000000 --- a/include/itkHigherOrderAccurateDerivativeImageFilter.h +++ /dev/null @@ -1,163 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateDerivativeImageFilter_h -#define itkHigherOrderAccurateDerivativeImageFilter_h - -#include "itkImageToImageFilter.h" - -namespace itk -{ - -/** \class HigherOrderAccurateDerivativeImageFilter - * \brief Computes the higher order accurate directional derivative of an image. - * The directional derivative at each pixel location is computed by convolution - * with a higher order accurate derivative operator of user-specified order. - * - * SetOrder() specifies the order of the derivative. - * - * SetDirection() specifies the direction of the derivative with respect to the - * coordinate axes of the image. - * - * To specify the order of accuracy, use SetOrderOfAccuracy(). The - * approximation will be accurate to two times the OrderOfAccuracy in terms of - * Taylor series terms. - * - * \sa Image - * \sa Neighborhood - * \sa NeighborhoodOperator - * \sa NeighborhoodIterator - * - * \ingroup ImageFeatureExtraction - * \ingroup HigherOrderAccurateGradient - */ -template -class HigherOrderAccurateDerivativeImageFilter : public ImageToImageFilter -{ -public: - ITK_DISALLOW_COPY_AND_MOVE(HigherOrderAccurateDerivativeImageFilter); - - /** Standard class type alias. */ - using Self = HigherOrderAccurateDerivativeImageFilter; - using Superclass = ImageToImageFilter; - using Pointer = SmartPointer; - using ConstPointer = SmartPointer; - - /** Extract some information from the image types. Dimensionality - * of the two images is assumed to be the same. */ - using OutputPixelType = typename TOutputImage::PixelType; - using OutputInternalPixelType = typename TOutputImage::InternalPixelType; - using InputPixelType = typename TInputImage::PixelType; - using InputInternalPixelType = typename TInputImage::InternalPixelType; - - /** 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 type alias support. */ - using InputImageType = TInputImage; - using OutputImageType = TOutputImage; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(HigherOrderAccurateDerivativeImageFilter, ImageToImageFilter); - - /** The output pixel type must be signed. */ -#ifdef ITK_USE_CONCEPT_CHECKING - /** Begin concept checking */ - itkConceptMacro(SignedOutputPixelType, (Concept::Signed)); - /** End concept checking */ -#endif - - /** Standard get/set macros for filter parameters. */ - itkSetMacro(Order, unsigned int); - itkGetConstMacro(Order, unsigned int); - itkSetMacro(OrderOfAccuracy, unsigned int); - itkGetConstMacro(OrderOfAccuracy, unsigned int); - itkSetMacro(Direction, unsigned int); - itkGetConstMacro(Direction, unsigned int); - - /** Use the image spacing information in calculations. Use this option if you - * want derivatives in physical space. Default is UseImageSpacingOn. */ - void - SetUseImageSpacingOn() - { - this->SetUseImageSpacing(true); - } - - /** Ignore the image spacing. Use this option if you want derivatives in - isotropic pixel space. Default is UseImageSpacingOn. */ - void - SetUseImageSpacingOff() - { - this->SetUseImageSpacing(false); - } - - /** Set/Get whether or not the filter will use the spacing of the input - image in its calculations */ - itkSetMacro(UseImageSpacing, bool); - itkGetConstMacro(UseImageSpacing, bool); - -protected: - HigherOrderAccurateDerivativeImageFilter() - - = default; - - ~HigherOrderAccurateDerivativeImageFilter() override = default; - void - PrintSelf(std::ostream & os, Indent indent) const override; - - /** HigherOrderAccurateDerivativeImageFilter needs a larger input requested region than - * the output requested region (larger in the direction of the - * derivative). As such, HigherOrderAccurateDerivativeImageFilter needs to provide an - * implementation for GenerateInputRequestedRegion() in order to - * inform the pipeline execution model. - * - * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - void - GenerateInputRequestedRegion() override; - - /** Standard pipeline method. While this class does not implement a - * ThreadedGenerateData(), its GenerateData() delegates all - * calculations to an NeighborhoodOperatorImageFilter. Since the - * NeighborhoodOperatorImageFilter is multithreaded, this filter is - * multithreaded by default. */ - void - GenerateData() override; - -private: - /** The order of the derivative. */ - unsigned int m_Order{ 1 }; - - /** Order of accuracy. */ - unsigned int m_OrderOfAccuracy{ 2 }; - - /** The direction of the derivative. */ - unsigned int m_Direction{ 0 }; - - bool m_UseImageSpacing{ true }; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkHigherOrderAccurateDerivativeImageFilter.hxx" -#endif - -#endif diff --git a/include/itkHigherOrderAccurateDerivativeImageFilter.hxx b/include/itkHigherOrderAccurateDerivativeImageFilter.hxx deleted file mode 100644 index 987249d..0000000 --- a/include/itkHigherOrderAccurateDerivativeImageFilter.hxx +++ /dev/null @@ -1,161 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateDerivativeImageFilter_hxx -#define itkHigherOrderAccurateDerivativeImageFilter_hxx - -#include "itkNumericTraits.h" -#include "itkNeighborhoodOperatorImageFilter.h" -#include "itkHigherOrderAccurateDerivativeOperator.h" -#include "itkProgressAccumulator.h" - -namespace itk -{ - -template -void -HigherOrderAccurateDerivativeImageFilter::GenerateInputRequestedRegion() -{ - // 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 - HigherOrderAccurateDerivativeOperator oper; - oper.SetDirection(m_Direction); - oper.SetOrder(m_Order); - oper.SetOrderOfAccuracy(m_OrderOfAccuracy); - oper.CreateDirectional(); - - // 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(oper.GetRadius()); - - // 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 -HigherOrderAccurateDerivativeImageFilter::GenerateData() -{ - ZeroFluxNeumannBoundaryCondition nbc; - - // Define the operator value type so that we can filter integral - // images and have the proper operator defined. - using OperatorValueType = typename NumericTraits::RealType; - - // Filter - HigherOrderAccurateDerivativeOperator oper; - oper.SetDirection(m_Direction); - oper.SetOrder(m_Order); - oper.SetOrderOfAccuracy(m_OrderOfAccuracy); - oper.CreateDirectional(); - oper.FlipAxes(); - - if (m_UseImageSpacing == true) - { - if (this->GetInput()->GetSpacing()[m_Direction] == 0.0) - { - itkExceptionMacro(<< "Image spacing cannot be zero."); - } - else - { - oper.ScaleCoefficients(1.0 / this->GetInput()->GetSpacing()[m_Direction]); - } - } - - typename NeighborhoodOperatorImageFilter::Pointer filter = - NeighborhoodOperatorImageFilter::New(); - - // Create a process accumulator for tracking the progress of this minipipeline - ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); - progress->SetMiniPipelineFilter(this); - - // Register the filter with the with progress accumulator using - // equal weight proportion - progress->RegisterInternalFilter(filter, 1.0f); - - filter->OverrideBoundaryCondition(&nbc); - - // - // Set up the mini-pipline - // - filter->SetOperator(oper); - filter->SetInput(this->GetInput()); - - // Graft this filter's output to the mini-pipeline. this sets up - // the mini-pipeline to write to this filter's output and copies - // region ivars and meta-data - filter->GraftOutput(this->GetOutput()); - - // Execute the mini-pipeline. - filter->Update(); - - // Graft the output of the mini-pipeline back onto the filter's output, - // this copies back the region ivars and meta-data. - this->GraftOutput(filter->GetOutput()); -} - - -template -void -HigherOrderAccurateDerivativeImageFilter::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - - os << indent << "Order: " << m_Order << std::endl; - os << indent << "OrderOfAccuracy: " << m_OrderOfAccuracy << std::endl; - os << indent << "Direction: " << m_Direction << std::endl; - os << indent << "UseImageSpacing: " << m_UseImageSpacing << std::endl; -} - -} // end namespace itk - -#endif diff --git a/include/itkHigherOrderAccurateDerivativeOperator.h b/include/itkHigherOrderAccurateDerivativeOperator.h deleted file mode 100644 index 118a6ca..0000000 --- a/include/itkHigherOrderAccurateDerivativeOperator.h +++ /dev/null @@ -1,166 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateDerivativeOperator_h -#define itkHigherOrderAccurateDerivativeOperator_h - -#include "itkNeighborhoodOperator.h" - -namespace itk -{ - -/** - * \class HigherOrderAccurateDerivativeOperator - * \brief A NeighborhoodOperator for calculating an n-th order accurate derivative - * at a pixel. - * - * \brief Calculate the image derivative from a higher order accurate - * central-difference derivative kernel. - * - * Based on the work here: - * - * Khan, IR and Ohba, Ryoji. "Closed-form expressions for the finite difference - * approximations of first and higher derivatives based on Taylor series." - * Journal of Computational and Applied Mathematics. vol 107. p. 179-193. - * 1999. - * - * Khan, IR and Ohba, Ryoji. "Taylor series based finite difference - * approximations of higher-degree derivatives." Journal of Computational and - * Applied Mathematics. vol 154. p. 115-124. 2003. - * - * To specify the order of accuracy, use SetOrderOfAccuracy(). The - * approximation will be accurate to two times the OrderOfAccuracy in terms of - * Taylor series terms. - * - * @todo: implement support for higher order derivatives. - * - * \sa DerivativeOperator - * \sa NeighborhoodOperator - * \sa Neighborhood - * \sa ForwardDifferenceOperator - * \sa BackwardDifferenceOperator - * - * \ingroup Operators - * \ingroup HigherOrderAccurateGradient - */ -template > -class HigherOrderAccurateDerivativeOperator : public NeighborhoodOperator -{ -public: - /** Standard class type alias. */ - using Self = HigherOrderAccurateDerivativeOperator; - using Superclass = NeighborhoodOperator; - - using PixelType = typename Superclass::PixelType; - using PixelRealType = typename Superclass::PixelRealType; - - /** Run-time type information (and related methods). */ - itkTypeMacro(HigherOrderAccurateDerivativeOperator, NeighborhoodOperator); - - /** Constructor. */ - HigherOrderAccurateDerivativeOperator() - - = default; - - /** Copy constructor. */ - HigherOrderAccurateDerivativeOperator(const Self & other) - : NeighborhoodOperator(other) - { - m_Order = other.m_Order; - } - - /** Assignment operator */ - Self & - operator=(const Self & other) - { - Superclass::operator=(other); - m_Order = other.m_Order; - return *this; - } - - /** Sets the order of the derivative. */ - void - SetOrder(const unsigned int & order) - { - this->m_Order = order; - } - - /** Returns the order of the derivative. */ - unsigned int - GetOrder() const - { - return m_Order; - } - - /** Sets the order of accuracy of the derivative. The derivative estimate will - * be accurate out to two times the given order in terms of Taylor Series terms. The - * radius of the neighborhood operator is also equal to the given order. */ - void - SetOrderOfAccuracy(const unsigned int & order) - { - this->m_OrderOfAccuracy = order; - } - - unsigned int - GetOrderOfAccuracy() const - { - return m_OrderOfAccuracy; - } - - /** Prints some debugging information */ - void - PrintSelf(std::ostream & os, Indent i) const override - { - os << i << "HigherOrderAccurateDerivativeOperator { this=" << this << ", m_Order = " << m_Order - << ", m_OrderOfAccuracy = " << m_OrderOfAccuracy << "}" << std::endl; - Superclass::PrintSelf(os, i.GetNextIndent()); - } - -protected: - /** Typedef support for coefficient vector type. Necessary to - * work around compiler bug on VC++. */ - using CoefficientVector = typename Superclass::CoefficientVector; - - /** Calculates operator coefficients. */ - CoefficientVector - GenerateCoefficients() override; - - /** Arranges coefficients spatially in the memory buffer. */ - void - Fill(const CoefficientVector & coeff) override - { - Superclass::FillCenteredDirectional(coeff); - } - -private: - CoefficientVector - GenerateFirstOrderCoefficients(); - - /** Order of the derivative. */ - unsigned int m_Order{ 1 }; - - /** Order of accuracy. */ - unsigned int m_OrderOfAccuracy{ 2 }; -}; - -} // namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkHigherOrderAccurateDerivativeOperator.hxx" -#endif - -#endif diff --git a/include/itkHigherOrderAccurateDerivativeOperator.hxx b/include/itkHigherOrderAccurateDerivativeOperator.hxx deleted file mode 100644 index 07f5760..0000000 --- a/include/itkHigherOrderAccurateDerivativeOperator.hxx +++ /dev/null @@ -1,75 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateDerivativeOperator_hxx -#define itkHigherOrderAccurateDerivativeOperator_hxx - -#include "itkNumericTraits.h" - -namespace itk -{ - -template -typename HigherOrderAccurateDerivativeOperator::CoefficientVector -HigherOrderAccurateDerivativeOperator::GenerateCoefficients() -{ - switch (m_Order) - { - case 1: - return this->GenerateFirstOrderCoefficients(); - default: - itkExceptionMacro(<< "The specified derivative order/degree is not yet supported."); - } -} - - -template -typename HigherOrderAccurateDerivativeOperator::CoefficientVector -HigherOrderAccurateDerivativeOperator::GenerateFirstOrderCoefficients() -{ - unsigned int order = this->m_OrderOfAccuracy; - unsigned int length = 2 * order + 1; - CoefficientVector coeff(length); - - coeff[order + 1] = static_cast(order) / (order + 1); - coeff[order - 1] = -1 * coeff[order + 1]; - - unsigned int i; - // TODO Try to refactor this loop to pull out common multiplications - for (i = 1; i < order; ++i) - { - coeff[order + 1 + i] = - -1 * (i * static_cast(order - i)) / (static_cast(order + i + 1) * (i + 1)) * coeff[order + i]; - coeff[order - 1 - i] = -1 * coeff[order + 1 + i]; - } - - // We perform a flip of axes here to keep in line with - // itk::DerivativeOperator. The DerivativeImageFilter then calls FlipAxes(), - // so I am not sure why they put it in reverse order in the first place. Note - // that a flip in this case is the same as flipping the sign. - for (i = 0; i < length; ++i) - coeff[i] *= -1; - - // Center point. - coeff[order] = 0.0; - - return coeff; -} - -} // namespace itk - -#endif diff --git a/include/itkHigherOrderAccurateGradientImageFilter.h b/include/itkHigherOrderAccurateGradientImageFilter.h deleted file mode 100644 index efc2058..0000000 --- a/include/itkHigherOrderAccurateGradientImageFilter.h +++ /dev/null @@ -1,169 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateGradientImageFilter_h -#define itkHigherOrderAccurateGradientImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkCovariantVector.h" - -namespace itk -{ - -/** \class HigherOrderAccurateGradientImageFilter - * - * \brief Calculate the image gradient from a higher order accurate - * central-difference derivative kernel. - * - * Based on the work here: - * - * Khan, IR and Ohba, Ryoji. "Closed-form expressions for the finite difference - * approximations of first and higher derivatives based on Taylor series." - * Journal of Computational and Applied Mathematics. vol 107. p. 179-193. - * 1999. - * - * Khan, IR and Ohba, Ryoji. "Taylor series based finite difference - * approximations of higher-degree derivatives." Journal of Computational and - * Applied Mathematics. vol 154. p. 115-124. 2003. - * - * To specify the order of accuracy, use SetOrderOfAccuracy(). The - * approximation will be accurate to two times the OrderOfAccuracy in terms of - * Taylor series terms. - * - * \sa HigherOrderAccurateDerivativeOperator - * \sa HigherOrderAccurateDerivativeImageFilter - * - * \ingroup GradientFilters - * \ingroup HigherOrderAccurateGradient - */ -template -class HigherOrderAccurateGradientImageFilter - : public ImageToImageFilter< - TInputImage, - Image, TInputImage::ImageDimension>> -{ -public: - ITK_DISALLOW_COPY_AND_MOVE(HigherOrderAccurateGradientImageFilter); - - /** Extract dimension from input image. */ - static constexpr unsigned int ImageDimension = TInputImage::ImageDimension; - - /** Standard class type alias. */ - using Self = HigherOrderAccurateGradientImageFilter; - - /** Convenient type alias for simplifying declarations. */ - using InputImageType = TInputImage; - using InputImagePointer = typename InputImageType::Pointer; - using OutputImageType = Image, - itkGetStaticConstMacro(OutputImageDimension)>; - using OutputImagePointer = typename OutputImageType::Pointer; - - /** Standard class type alias. */ - 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(HigherOrderAccurateGradientImageFilter, ImageToImageFilter); - - /** Image type alias support. */ - using InputPixelType = typename InputImageType::PixelType; - using OperatorValueType = TOperatorValueType; - using OutputValueType = TOutputValueType; - using OutputPixelType = CovariantVector; - using OutputImageRegionType = typename OutputImageType::RegionType; - - /** Set/Get whether or not the filter will use the spacing of the input - image in its calculations */ - itkSetMacro(UseImageSpacing, bool); - itkGetConstMacro(UseImageSpacing, bool); - itkBooleanMacro(UseImageSpacing); - -#ifdef ITK_USE_CONCEPT_CHECKING - /** Begin concept checking */ - itkConceptMacro(InputConvertibleToOutputCheck, (Concept::Convertible)); - itkConceptMacro(OutputHasNumericTraitsCheck, (Concept::HasNumericTraits)); - /** End concept checking */ -#endif - - /** The UseImageDirection flag determines whether image derivatives are - * computed with respect to the image grid or with respect to the physical - * space. When this flag is ON the derivatives are computed with respect to - * the coodinate system of physical space. The difference is whether we take - * into account the image Direction or not. The flag ON will take into - * account the image direction and will result in an extra matrix - * multiplication compared to the amount of computation performed when the - * flag is OFF. - * The default value of this flag is On. - */ - itkSetMacro(UseImageDirection, bool); - itkGetConstMacro(UseImageDirection, bool); - itkBooleanMacro(UseImageDirection); - - /** Set/Get the order of accuracy of the derivative operator. For more - * information, see HigherOrderAccurateDerivativeOperator. */ - itkSetMacro(OrderOfAccuracy, unsigned int); - itkGetConstMacro(OrderOfAccuracy, unsigned int); - -protected: - HigherOrderAccurateGradientImageFilter(); - ~HigherOrderAccurateGradientImageFilter() override = default; - void - PrintSelf(std::ostream & os, Indent indent) const override; - - /** GradientImageFilter needs a larger input requested region than - * the output requested region. As such, GradientImageFilter needs - * to provide an implementation for GenerateInputRequestedRegion() - * in order to inform the pipeline execution model. - * - * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ - void - GenerateInputRequestedRegion() override; - - /** GradientImageFilter can be implemented as a multithreaded filter. - * Therefore, this implementation provides a ThreadedGenerateData() - * routine which is called for each processing thread. The output - * image data is allocated automatically by the superclass prior to - * calling ThreadedGenerateData(). ThreadedGenerateData can only - * write to the portion of the output image specified by the - * parameter "outputRegionForThread" - * - * \sa ImageToImageFilter::ThreadedGenerateData(), - * ImageToImageFilter::GenerateData() */ - void - DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override; - -private: - bool m_UseImageSpacing{ true }; - - // flag to take or not the image direction into account - // when computing the derivatives. - bool m_UseImageDirection{ true }; - - unsigned int m_OrderOfAccuracy{ 2 }; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -# include "itkHigherOrderAccurateGradientImageFilter.hxx" -#endif - -#endif diff --git a/include/itkHigherOrderAccurateGradientImageFilter.hxx b/include/itkHigherOrderAccurateGradientImageFilter.hxx deleted file mode 100644 index 9616d52..0000000 --- a/include/itkHigherOrderAccurateGradientImageFilter.hxx +++ /dev/null @@ -1,213 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#ifndef itkHigherOrderAccurateGradientImageFilter_hxx -#define itkHigherOrderAccurateGradientImageFilter_hxx - -#include "itkConstNeighborhoodIterator.h" -#include "itkNeighborhoodInnerProduct.h" -#include "itkImageRegionIterator.h" -#include "itkHigherOrderAccurateDerivativeOperator.h" -#include "itkNeighborhoodAlgorithm.h" -#include "itkOffset.h" - -namespace itk -{ - -template -HigherOrderAccurateGradientImageFilter:: - HigherOrderAccurateGradientImageFilter() - - = default; - - -template -void -HigherOrderAccurateGradientImageFilter:: - GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the input and output - InputImagePointer inputPtr = const_cast(this->GetInput()); - OutputImagePointer outputPtr = this->GetOutput(); - - if (!inputPtr || !outputPtr) - { - return; - } - - // Build an operator so that we can determine the kernel size - HigherOrderAccurateDerivativeOperator oper; - oper.SetDirection(0); - oper.SetOrder(1); - oper.SetOrderOfAccuracy(this->m_OrderOfAccuracy); - oper.CreateDirectional(); - unsigned long radius = oper.GetRadius()[0]; - - // 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 -HigherOrderAccurateGradientImageFilter::DynamicThreadedGenerateData( - const OutputImageRegionType & outputRegionForThread) -{ - unsigned int i; - OutputPixelType gradient; - - ZeroFluxNeumannBoundaryCondition nbc; - - ConstNeighborhoodIterator nit; - ImageRegionIterator it; - - NeighborhoodInnerProduct SIP; - - // Get the input and output - OutputImageType * outputImage = this->GetOutput(); - const InputImageType * inputImage = this->GetInput(); - - // Set up operators - HigherOrderAccurateDerivativeOperator op[ImageDimension]; - - for (i = 0; i < ImageDimension; i++) - { - op[i].SetDirection(0); - op[i].SetOrder(1); - op[i].SetOrderOfAccuracy(this->m_OrderOfAccuracy); - op[i].CreateDirectional(); - - // Reverse order of coefficients for the convolution with the image to - // follow. - op[i].FlipAxes(); - - // Take into account the pixel spacing if necessary - if (m_UseImageSpacing == true) - { - if (this->GetInput()->GetSpacing()[i] == 0.0) - { - itkExceptionMacro(<< "Image spacing cannot be zero."); - } - else - { - op[i].ScaleCoefficients(1.0 / this->GetInput()->GetSpacing()[i]); - } - } - } - - // Calculate iterator radius - Size radius; - for (i = 0; i < ImageDimension; ++i) - { - radius[i] = op[0].GetRadius()[0]; - } - - // Find the data-set boundary "faces" - typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType faceList; - NeighborhoodAlgorithm::ImageBoundaryFacesCalculator bC; - faceList = bC(inputImage, outputRegionForThread, radius); - - typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType::iterator fit; - fit = faceList.begin(); - - // Initialize the x_slice array - nit = ConstNeighborhoodIterator(radius, inputImage, *fit); - - std::slice x_slice[ImageDimension]; - const unsigned long center = nit.Size() / 2; - for (i = 0; i < ImageDimension; ++i) - { - x_slice[i] = std::slice(center - nit.GetStride(i) * radius[i], op[i].GetSize()[0], nit.GetStride(i)); - } - - // Process non-boundary face and then each of the boundary faces. - // These are N-d regions which border the edge of the buffer. - for (fit = faceList.begin(); fit != faceList.end(); ++fit) - { - nit = ConstNeighborhoodIterator(radius, inputImage, *fit); - it = ImageRegionIterator(outputImage, *fit); - nit.OverrideBoundaryCondition(&nbc); - nit.GoToBegin(); - - while (!nit.IsAtEnd()) - { - for (i = 0; i < ImageDimension; ++i) - { - gradient[i] = SIP(x_slice[i], nit, op[i]); - } - - if (this->m_UseImageDirection) - { - inputImage->TransformLocalVectorToPhysicalVector(gradient, it.Value()); - } - else - { - it.Value() = gradient; - } - ++nit; - ++it; - } - } -} - - -template -void -HigherOrderAccurateGradientImageFilter::PrintSelf( - std::ostream & os, - Indent indent) const -{ - Superclass::PrintSelf(os, indent); - - os << indent << "UseImageSpacing: " << (this->m_UseImageSpacing ? "On" : "Off") << std::endl; - os << indent << "UseImageDirection = " << (this->m_UseImageDirection ? "On" : "Off") << std::endl; - os << indent << "OrderOfAccuracy: " << this->m_OrderOfAccuracy << std::endl; -} - -} // end namespace itk - -#endif diff --git a/README.rst b/info.rst similarity index 100% rename from README.rst rename to info.rst diff --git a/itk-module.cmake b/itk-module.cmake deleted file mode 100644 index c03af8f..0000000 --- a/itk-module.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Maintainer: Matt McCormick -set(DOCUMENTATION "This module contains a filter to compute higher order -accurate numerical derivatives and gradients from an input scalar image. -Higher Order Accurate Derivative and Gradient Calculation in ITK -https://www.insight-journal.org/browse/publication/775 -https://hdl.handle.net/10380/3231 -") - -itk_module(HigherOrderAccurateGradient - DEPENDS - ITKCommon - ITKImageGradient - ITKImageIntensity - ITKImageFeature - TEST_DEPENDS - ITKTestKernel - EXCLUDE_FROM_DEFAULT - DESCRIPTION - "${DOCUMENTATION}" -) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 62f2d1e..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -itk_module_test() - -set(HigherOrderAccurateGradientTests - itkHigherOrderAccurateGradientImageFilterTest.cxx - itkHigherOrderAccurateDerivativeImageFilterTest.cxx - ) - -CreateTestDriver(HigherOrderAccurateGradient "${HigherOrderAccurateGradient-Test_LIBRARIES}" "${HigherOrderAccurateGradientTests}") - -itk_add_test(NAME itkHigherOrderAccurateGradientImageFilterTest - COMMAND HigherOrderAccurateGradientTestDriver - --compare ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateGradientImageFilterTest_Accuracy1_Magnitude.mha - ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateGradientImageFilterTest_GradientImageFilter_Magnitude.mha - itkHigherOrderAccurateGradientImageFilterTest - DATA{Input/foot.mha} - ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateGradientImageFilterTest - ) - -itk_add_test(NAME itkHigherOrderAccurateDerivativeImageFilterTest - COMMAND HigherOrderAccurateGradientTestDriver - --compare ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateDerivativeImageFilterTest_Accuracy1_Direction0.mha - ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateDerivativeImageFilterTest_DerivativeImageFilter_Direction0.mha - --compare ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateDerivativeImageFilterTest_Accuracy1_Direction1.mha - ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateDerivativeImageFilterTest_DerivativeImageFilter_Direction1.mha - itkHigherOrderAccurateDerivativeImageFilterTest - DATA{Input/foot.mha} - ${ITK_TEST_OUTPUT_DIR}/itkHigherOrderAccurateDerivativeImageFilterTest - ) diff --git a/test/Input/foot.mha.cid b/test/Input/foot.mha.cid deleted file mode 100644 index cb03d7b..0000000 --- a/test/Input/foot.mha.cid +++ /dev/null @@ -1 +0,0 @@ -bafkreicsnenkzoqwpvk5qscxqdmavlmfjmb3totuplgy6btdkiauwj5gma diff --git a/test/itkHigherOrderAccurateDerivativeImageFilterTest.cxx b/test/itkHigherOrderAccurateDerivativeImageFilterTest.cxx deleted file mode 100644 index 9fb7d05..0000000 --- a/test/itkHigherOrderAccurateDerivativeImageFilterTest.cxx +++ /dev/null @@ -1,94 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#include "itkDerivativeImageFilter.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkHigherOrderAccurateDerivativeImageFilter.h" - -int -itkHigherOrderAccurateDerivativeImageFilterTest(int argc, char * argv[]) -{ - if (argc < 3) - { - std::cerr << "Usage: " << argv[0]; - std::cerr << " inputImage outputPrefix "; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = float; - using ImageType = itk::Image; - - std::string outputPrefix = argv[2]; - - using ReaderType = itk::ImageFileReader; - ReaderType::Pointer reader = ReaderType::New(); - reader->SetFileName(argv[1]); - - using HigherFilterType = itk::HigherOrderAccurateDerivativeImageFilter; - HigherFilterType::Pointer nthFilter = HigherFilterType::New(); - nthFilter->SetInput(reader->GetOutput()); - nthFilter->SetOrder(1); - - using WriterType = itk::ImageFileWriter; - WriterType::Pointer nthWriter = WriterType::New(); - nthWriter->SetInput(nthFilter->GetOutput()); - - // First order accurate. - using FirstFilterType = itk::DerivativeImageFilter; - FirstFilterType::Pointer firstFilter = FirstFilterType::New(); - firstFilter->SetInput(reader->GetOutput()); - firstFilter->SetOrder(1); - - using WriterType = itk::ImageFileWriter; - WriterType::Pointer firstWriter = WriterType::New(); - firstWriter->SetInput(firstFilter->GetOutput()); - - std::ostringstream ostrm; - try - { - for (unsigned int direction = 0; direction < 2; ++direction) - { - firstFilter->SetDirection(direction); - ostrm.str(""); - ostrm << outputPrefix << "_DerivativeImageFilter_Direction" << direction << ".mha"; - firstWriter->SetFileName(ostrm.str()); - firstWriter->Update(); - - for (unsigned int accuracy = 1; accuracy < 6; ++accuracy) - { - nthFilter->SetDirection(direction); - nthFilter->SetOrderOfAccuracy(accuracy); - ostrm.str(""); - ostrm << outputPrefix << "_Accuracy" << accuracy << "_Direction" << direction << ".mha"; - nthWriter->SetFileName(ostrm.str()); - nthWriter->Update(); - } - } - } - catch (itk::ExceptionObject & ex) - { - std::cerr << "Exception caught!" << std::endl; - std::cerr << ex << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/test/itkHigherOrderAccurateGradientImageFilterTest.cxx b/test/itkHigherOrderAccurateGradientImageFilterTest.cxx deleted file mode 100644 index d23e0d0..0000000 --- a/test/itkHigherOrderAccurateGradientImageFilterTest.cxx +++ /dev/null @@ -1,89 +0,0 @@ -/*========================================================================= - * - * Copyright NumFOCUS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *=========================================================================*/ -#include "itkGradientImageFilter.h" -#include "itkVectorMagnitudeImageFilter.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkHigherOrderAccurateGradientImageFilter.h" - -int -itkHigherOrderAccurateGradientImageFilterTest(int argc, char * argv[]) -{ - if (argc < 3) - { - std::cerr << "Usage: " << argv[0]; - std::cerr << " inputImage outputPrefix "; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = float; - using ImageType = itk::Image; - - using ReaderType = itk::ImageFileReader; - ReaderType::Pointer reader = ReaderType::New(); - reader->SetFileName(argv[1]); - - // First order accurate. - using FirstFilterType = itk::GradientImageFilter; - FirstFilterType::Pointer firstFilter = FirstFilterType::New(); - firstFilter->SetInput(reader->GetOutput()); - - using FilterType = itk::HigherOrderAccurateGradientImageFilter; - using GradientImageType = FilterType::OutputImageType; - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(reader->GetOutput()); - - std::string outputPrefix = argv[2]; - - using GradientMagnitudeFilterType = itk::VectorMagnitudeImageFilter; - GradientMagnitudeFilterType::Pointer gradientMagnitude = GradientMagnitudeFilterType::New(); - - using GradientMagnitudeWriterType = itk::ImageFileWriter; - GradientMagnitudeWriterType::Pointer gradientMagnitudeWriter = GradientMagnitudeWriterType::New(); - gradientMagnitudeWriter->SetInput(gradientMagnitude->GetOutput()); - - std::ostringstream ostrm; - try - { - gradientMagnitude->SetInput(firstFilter->GetOutput()); - ostrm.str(""); - ostrm << outputPrefix + "_GradientImageFilter_Magnitude.mha"; - gradientMagnitudeWriter->SetFileName(ostrm.str()); - gradientMagnitudeWriter->Update(); - gradientMagnitude->SetInput(filter->GetOutput()); - for (unsigned int accuracy = 1; accuracy < 6; ++accuracy) - { - filter->SetOrderOfAccuracy(accuracy); - ostrm.str(""); - ostrm << outputPrefix << "_Accuracy" << accuracy << "_Magnitude.mha"; - gradientMagnitudeWriter->SetFileName(ostrm.str()); - gradientMagnitudeWriter->Update(); - } - } - catch (itk::ExceptionObject & ex) - { - std::cerr << "Exception caught!" << std::endl; - std::cerr << ex << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/wrapping/CMakeLists.txt b/wrapping/CMakeLists.txt deleted file mode 100644 index 8385239..0000000 --- a/wrapping/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -itk_wrap_module(HigherOrderAccurateGradient) -itk_auto_load_submodules() -itk_end_wrap_module() diff --git a/wrapping/itkHigherOrderAccurateDerivativeImageFilter.wrap b/wrapping/itkHigherOrderAccurateDerivativeImageFilter.wrap deleted file mode 100644 index b1081cb..0000000 --- a/wrapping/itkHigherOrderAccurateDerivativeImageFilter.wrap +++ /dev/null @@ -1,9 +0,0 @@ -itk_wrap_class("itk::HigherOrderAccurateDerivativeImageFilter" POINTER) - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - foreach(t ${WRAP_ITK_REAL}) - itk_wrap_template( - "${ITKM_I${t}${d}}${ITKM_I${t}${d}}" - "${ITKT_I${t}${d}}, ${ITKT_I${t}${d}}") - endforeach() - endforeach() -itk_end_wrap_class() diff --git a/wrapping/itkHigherOrderAccurateGradientmageFilter.wrap b/wrapping/itkHigherOrderAccurateGradientmageFilter.wrap deleted file mode 100644 index 9b48cc9..0000000 --- a/wrapping/itkHigherOrderAccurateGradientmageFilter.wrap +++ /dev/null @@ -1,9 +0,0 @@ -itk_wrap_class("itk::HigherOrderAccurateGradientImageFilter" POINTER) - foreach(d ${ITK_WRAP_IMAGE_DIMS}) - foreach(t ${WRAP_ITK_REAL}) - itk_wrap_template( - "${ITKM_I${t}${d}}${ITKM_${t}}${ITKM_${t}}" - "${ITKT_I${t}${d}}, ${ITKT_${t}}, ${ITKT_${t}}") - endforeach() - endforeach() -itk_end_wrap_class()