Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
86b10d0
ENH: Initial commit.
thewtex May 28, 2015
156817c
BUG: Remove executable bit from source files.
thewtex May 28, 2015
883b102
BUG: Move headers into the module include/ directory.
thewtex May 28, 2015
8f64253
DOC: Add link to the IJ article in the module documentation.
thewtex May 28, 2015
514b74d
ENH: Remove "ITK" from the module name.
thewtex May 28, 2015
e60a208
BUG: Remove unnecessary include/CMakeLists.txt
thewtex May 28, 2015
9dce3fb
ENH: Cleanup of the src/ directory.
thewtex May 28, 2015
f5b6ef0
BUG: Add missing content link dereferences in test/CMakeLists.txt.
thewtex May 28, 2015
888f1e1
STYLE: Rename header files to have the itk prefix.
thewtex May 28, 2015
27c8b22
BUG: Add missing license headers.
thewtex May 28, 2015
e517fc2
BUG: Get StructureTensorImageFilter to compile.
thewtex May 28, 2015
1ed2e65
DOC: Fix the doxygen group test.
thewtex Jun 1, 2015
262e1b2
STYLE: Fix KWStyle test.
thewtex Jun 1, 2015
8ad47ff
COMP: Add missing includes.
thewtex Jun 20, 2015
d04d660
ENH: Use explicit name in CMakeLists.txt.
thewtex Jun 20, 2015
2a6cb9a
STYLE: Style fixes to CoherenecEnhancingDiffusionCommandLine.
thewtex Jun 20, 2015
e70ab47
ENH: Move the CoherenceEnhanncingDiffusion executable into an example…
thewtex Jun 20, 2015
27d00bb
ENH: Create the ImageIO directly get the input image information.
thewtex Jun 21, 2015
dd0157f
ENH: Use itk::TimeProbe to measure runtime.
thewtex Jun 21, 2015
2f412b5
ENH: Add check for valid ImageIO created.
thewtex Jun 22, 2015
85eee03
COMP: Add missing SymmetricSecondRankTensor header.
thewtex Jun 24, 2015
40b9064
COMP: Remove sys/time.h header.
thewtex Jun 24, 2015
942a3c9
BUG: Fix ReportProgressToCOutType name.
thewtex Jun 24, 2015
074c93f
COMP: Address CoherenceEnhancingDiffusionTest signature.
thewtex Jun 25, 2015
c87674c
COMP: Use overload dispatch for stencil computation.
thewtex Jun 26, 2015
7595326
COMP: Use overload dispatch in StructureTensorImageFilter.
thewtex Jun 26, 2015
8e186a9
COMP: Remove doxygen unknown command \br.
thewtex Jul 28, 2015
47d5ac8
BUG: Update ExternalModule build for ITK 4.9.
thewtex Jan 18, 2016
fbc250f
ENH: Add better default template argument for TScalar (RealType)
thewtex Sep 12, 2016
4715bf7
ENH: Add Python wrapping
thewtex Sep 12, 2016
8c90ef1
STYLE: Rename itk::CoherenceEnhancingDiffusionImageFilter
thewtex Sep 12, 2016
ced16af
COMP: Add missing header to itkStructureTensorImageFilter.hxx
thewtex Sep 12, 2016
930e678
Merge pull request #1 from thewtex/wrapping
thewtex Sep 12, 2016
8e2d0eb
BUG: Missing include header in hxx files
fbudin69500 Jan 2, 2017
2f6c3d8
Merge pull request #2 from fbudin69500/Missing_include_header
dzenanz Jan 2, 2017
23b2c69
COMP: Add missing ImageToImageFilter base class #include
thewtex Aug 31, 2017
85605d3
Merge pull request #10 from thewtex/ImageToImageFilterInclude
thewtex Aug 31, 2017
954f435
BUG: Add module Doxygen group
thewtex Sep 1, 2017
47e1510
Merge pull request #11 from thewtex/doxygen-group
thewtex Sep 1, 2017
7430c68
BUG: Correct command line example diffusion types
thewtex Sep 8, 2017
7b0e3a8
Merge pull request #12 from thewtex/example-diffusion-types
thewtex Sep 8, 2017
3ebd7e6
ENH: Require cmake minimum version to be 3.9.5.
Jan 17, 2018
0e9535c
Merge pull request #13 from jhlegarreta/ChangeRequiredCMakeMinimumVer…
dzenanz Jan 19, 2018
7455c3a
ENH: ITKv5 override consistency
hjmjohnson Dec 17, 2017
f40517b
COMP: Use C++11 override directly
hjmjohnson Dec 17, 2017
e979121
STYLE: Remove unused typedef
hjmjohnson Jan 14, 2018
253edb1
STYLE: Prefer C++11 type alias over typedef
hjmjohnson Feb 13, 2018
748fe00
STYLE: Prefer constexpr for const numeric literals
hjmjohnson Feb 13, 2018
ae33fde
DOC: Fix EED and CED diffusion tensor eignevalues doc error.
Feb 19, 2018
4866475
COMP: Move ITK_DISALLOW_COPY_AND_ASSIGN calls to public section.
Apr 14, 2018
8861318
COMP: Set the minimum required CMake version to 3.10.2.
May 5, 2018
d5a5315
Merge pull request #21 from jhlegarreta/UpdateCMakeMinimumRequiredVer…
thewtex May 6, 2018
1e244aa
BUG: Fix test errors steming from the new multi-threading mechanism.
May 21, 2018
fee2958
Merge pull request #22 from jhlegarreta/FixPoolMultiThreaderErrors
thewtex May 28, 2018
2a64ac2
STYLE: Prefer error checked std::sto[id] over ato[if].
jhlegarreta Nov 2, 2018
6e6b3d8
Fix type in CoherenceEnhancingDiffusionImageFilter brief section
blowekamp Mar 21, 2018
5e3efc4
COMP: Clean up class constructors and destructors
thewtex Dec 22, 2018
c320f71
Merge pull request #27 from thewtex/destructor-override
thewtex Dec 22, 2018
e5993d2
ENH: Allow building examples.
jhlegarreta Dec 24, 2018
d0701a1
Merge pull request #28 from jhlegarreta/AllowBuildingExamples
thewtex Jan 3, 2019
157b10d
COMP: Fix compiler warnings
jhlegarreta Mar 26, 2019
1094407
Merge pull request #29 from jhlegarreta/FixCompilerWarnings
thewtex Mar 31, 2019
516ffa6
COMP: Fix compiler warnings
jhlegarreta Apr 5, 2019
ca0bdd4
Merge pull request #30 from jhlegarreta/FixSignedUnsignedComparisonWa…
thewtex Apr 8, 2019
fd2c83c
COMP: Fix signed and unsigned integer comparison warnings
jhlegarreta Apr 9, 2019
ade5eb7
Merge pull request #31 from jhlegarreta/FixDifferentIntegerComparison…
dzenanz Apr 9, 2019
a4598ab
ENH: Fix spelling error s/tropci/tropic/g
hjmjohnson Jul 30, 2019
ba170b3
Merge pull request #34 from InsightSoftwareConsortium/fix-linkage-line
dzenanz Jul 31, 2019
49d5d2e
STYLE: Change enum to new enum class definition
mseng10 Aug 16, 2019
5ca42b9
Merge pull request #35 from mseng10/enh-move-enum-class-modules
thewtex Aug 29, 2019
21d9287
ENH: Add .gitattributes to allow running ITK clang-formatting scripts
hjmjohnson Feb 19, 2020
4b5dc91
ENH: Update enums from recent enum changes in ITK
mseng10 Feb 17, 2020
c4d7296
BUG: Fixes header mismatch test fail
mseng10 Feb 18, 2020
61437e7
STYLE: Use default member initialization
hjmjohnson Feb 17, 2020
92292b3
DOC: Update copyright assignment to NumFOCUS
hjmjohnson Feb 19, 2020
fda8f3a
ENH: Make similar to module template
hjmjohnson Feb 20, 2020
2a8cc28
COMP: Update to new ITK_DISALLOW_COPY_AND_MOVE macro
hjmjohnson Dec 26, 2020
5815444
COMP: Constrain wrapping to 2D, 3D images
thewtex Mar 16, 2021
60b12ac
Merge pull request #47 from mseng10/update-ci
thewtex Mar 16, 2021
03b0c98
COMP: Remove inclusion of .hxx files as headers
hjmjohnson Dec 17, 2021
c4b43af
COMP: Avoid single value vector constructor
hjmjohnson Mar 9, 2022
6f9a6c2
ENH: Bump ITK and replace http with https using script
tbirdso May 31, 2022
a740b7e
ENH: Update minimum cmake version to 3.16.3
hjmjohnson Mar 16, 2025
a0696cd
COMP: Use modern macro for name of class
hjmjohnson Jan 25, 2025
66bdade
STYLE: Update to match clang-format-19 from ITK
hjmjohnson Jan 25, 2025
4c0df82
BUG: Ensure itkAnisotropicDiffusionLBRImageFilter wrapped first
thewtex Mar 18, 2025
21b8426
COMP: Fix warnings: ITK type not wrapped, or currently not known
dzenanz Mar 24, 2025
b380487
Merge pull request #58 from InsightSoftwareConsortium/fix-legacy-remove
dzenanz Mar 24, 2025
281f76a
ENH: Ingest ITKAnisotropicDiffusionLBR into Modules/Filtering
hjmjohnson Apr 22, 2026
0560906
DOC: Add README.md pointing at archived upstream for AnisotropicDiffu…
hjmjohnson Apr 22, 2026
55453da
COMP: Fix upstream bugs in ingested AnisotropicDiffusionLBR
hjmjohnson Apr 22, 2026
7c22321
COMP: Remove AnisotropicDiffusionLBR.remote.cmake; now in-tree
hjmjohnson Apr 22, 2026
9ab5f3f
ENH: Enable AnisotropicDiffusionLBR in CI via configure-ci
hjmjohnson Apr 22, 2026
0fe0ab3
STYLE: Apply ITK gersemi formatting to ingested AnisotropicDiffusionLBR
hjmjohnson Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Modules/Filtering/AnisotropicDiffusionLBR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.16.3)

project(
AnisotropicDiffusionLBR
VERSION
5.1.0 #Version should track with ITK
LANGUAGES
CXX
)

# Header only module, no libraries set(AnisotropicDiffusionLBR_LIBRARIES AnisotropicDiffusionLBR)

if(NOT ITK_SOURCE_DIR)
find_package(ITK 5.1 REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${ITK_CMAKE_DIR})
include(ITKModuleExternal)
else()
set(ITK_DIR ${CMAKE_BINARY_DIR})
itk_module_impl()
endif()

# itk_module_examples() is intentionally omitted: the upstream
# examples/ directory is not part of the whitelist-based ingest
# (see Modules/Filtering/AnisotropicDiffusionLBR/README.md), so
# expanding this call under BUILD_EXAMPLES=ON would fail at CMake
# configure time looking for a non-existent subdirectory.
60 changes: 60 additions & 0 deletions Modules/Filtering/AnisotropicDiffusionLBR/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# AnisotropicDiffusionLBR

In-tree ITK module providing coherence-enhancing (CED) and
edge-enhancing (EED) anisotropic diffusion filters built on the
Lattice-Basis-Reduction (LBR) stencil scheme by Jean-Marie Mirebeau.

## Origin

Ingested from the standalone remote module
[**InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR**](https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR)
on 2026-04-22, at upstream commit
[`203260b9`](https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR/commit/203260b929acda68a1f64b1267b0d89e825904ec).
The upstream repository will be archived read-only after this PR
merges; it remains reachable at the URL above.

## What lives here

Per the v3 ingestion strategy (see
`Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md`), only
paths matching the narrow whitelist (code, headers, tests, wrapping,
module CMake) crossed the merge boundary:

- `include/` — public C++ headers.
- `test/` — Google-test / CTest drivers and content-link stubs.
- `wrapping/` — Python wrapping descriptors.
- `CMakeLists.txt`, `itk-module.cmake` — build + module descriptors.

Every surviving commit preserves original authorship; `git blame`
walks across the merge boundary to upstream authors from 2014.

## What was intentionally left upstream

Everything outside the whitelist stays in the archived upstream repo.
If you need any of it, clone
<https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR>.

| Content in upstream | Why it did not ingest |
|---|---|
| `Old/` | Pre-refactor legacy trees; no current test depends on them. |
| `examples/` + `examples/Data/` | Per-module `examples/` are routed to top-level [`Examples/`](https://github.com/InsightSoftwareConsortium/ITK/tree/main/Examples) via a separate follow-up PR. |
| `README.rst` | Algorithm citations + background are folded into the Doxygen on the filter headers. |
| `test/azure-pipelines.yml`, `test/Docker/` | Standalone-build CI scaffolding; not useful in-tree. |
| `CTestConfig.cmake`, `pyproject.toml`, `.github/`, `.clang-format`, `LICENSE` | Packaging / CI / style scaffolding superseded by ITK root. |

## Long-form documentation

- **Algorithm description** — see the Doxygen on
`itkAnisotropicDiffusionLBRImageFilter` and
`itkCoherenceEnhancingDiffusionImageFilter`, plus embedded citations
(Mirebeau et al.).
- **Standalone build + usage examples** — see the archived upstream at
<https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR>.

## Content-link status

The 24 baseline and input content-links under `test/Baseline/` and
`test/Input/` are currently `.md5` stubs. Per the v3 strategy they
should be normalized to `.cid` (IPFS Content Identifier) before this
PR merges; see
`Utilities/Maintenance/RemoteModuleIngest/cid-normalize.sh`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/*=========================================================================
*
* 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.
*
*=========================================================================*/
//
//
// Created by Jean-Marie Mirebeau on 20/11/2014.
//
//

#ifndef itkDiffusion_CoherenceEnhancingDiffusionCommandLine_h
#define itkDiffusion_CoherenceEnhancingDiffusionCommandLine_h

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCoherenceEnhancingDiffusionImageFilter.h"
#include "LinearAnisotropicDiffusionCommandLine.h"
#include "itkTimeProbe.h"

namespace CoherenceEnhancingDiffusionCommandLine
{

inline void
Usage()
{
std::cerr << "Input image filename. 2D and 3D images supported. Required.\n"
<< "Output image filename. Required.\n"
<< "Diffusion time. Suggested range: 0.5-5, up to 50 for strong noise. Default: 2.\n"
<< "Lambda. Small values detect more edges. Suggested range: 0.05, 0.0001. Default: 0.01\n"
<< "Weickert diffusion type. Accepted values: CED, cCED, EED, cEED, Isotropic. Default: CED.\n"
<< "Noise scale. Suggested range: 0.5 - 4. Default 1.\n"
<< "Feature scale. Suggested range: 2-6. Default 2.\n"
<< "\n";
}

using namespace itk;

int
Execute(int argc, char * argv[]);

template <int VDimension>
int
Execute(int argc, char * argv[], itk::ImageIOBase::IOComponentEnum, int nComponents);

template <int VDimension, typename ScalarType, typename ComponentType>
int
Execute(int argc, char * argv[], int nComponents);

template <int VDimension, typename ScalarType, typename PixelType, typename ExportPixelType>
int
Execute(int argc, char * argv[]);


using ReportProgressToCOutType = LinearAnisotropicDiffusionCommandLine::ReportProgressToCOutType;

inline int
Execute(int argc, char * argv[])
{
using std::cerr;
using std::endl;
using namespace itk;

if (argc < 2 + 1)
{
Usage();
return EXIT_SUCCESS;
}

const char * imageFileName = argv[1];

itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(imageFileName, itk::IOFileModeEnum::ReadMode);
if (imageIO.IsNull())
{
std::cerr << "Could not create ImageIO" << std::endl;
return EXIT_FAILURE;
}
imageIO->SetFileName(imageFileName);
imageIO->ReadImageInformation();

const unsigned int imageDimension = imageIO->GetNumberOfDimensions();
const itk::ImageIOBase::IOComponentEnum componentType = imageIO->GetComponentType();
const unsigned int nComponents = imageIO->GetNumberOfComponents();

switch (imageDimension)
{
case 2:
return Execute<2>(argc, argv, componentType, nComponents);
case 3:
return Execute<3>(argc, argv, componentType, nComponents);
default:
itkGenericExceptionMacro("Sorry, unsupported image dimension.");
}
}

template <int Dimension>
int
Execute(int argc, char * argv[], itk::IOComponentEnum componentType, int nComponents)
{
switch (componentType)
{
case itk::IOComponentEnum::UCHAR:
return Execute<Dimension, float, unsigned char>(argc, argv, nComponents);
case itk::IOComponentEnum::FLOAT:
return Execute<Dimension, float, float>(argc, argv, nComponents);
case itk::IOComponentEnum::DOUBLE:
return Execute<Dimension, double, double>(argc, argv, nComponents);
default:
itkGenericExceptionMacro("Sorry, unsupported component type");
}
}

template <int Dimension, typename ScalarType, typename ComponentType>
int
Execute(int argc, char * argv[], int nComponents)
{
switch (nComponents)
{
case 1:
return Execute<Dimension, ScalarType, ScalarType, ComponentType>(argc, argv);
case 2:
return Execute<Dimension, ScalarType, Vector<ScalarType, 2>, Vector<ComponentType, 2>>(argc, argv);
case 3:
return Execute<Dimension, ScalarType, Vector<ScalarType, 3>, Vector<ComponentType, 3>>(argc, argv);
default:
itkGenericExceptionMacro("Sorry, unsupported number of components");
}
}

template <int Dimension, typename ScalarType, typename PixelType, typename ExportPixelType>
int
Execute(int argc, char * argv[])
{
using ImageType = Image<PixelType, Dimension>;

using ReaderType = ImageFileReader<ImageType>;
typename ReaderType::Pointer reader = ReaderType::New();

const char * imageFileName = argv[1];
const char * outputFileName = argv[2];
reader->SetFileName(imageFileName);

using DiffusionFilterType = CoherenceEnhancingDiffusionImageFilter<ImageType, ScalarType>;
typename DiffusionFilterType::Pointer diffusionFilter = DiffusionFilterType::New();
diffusionFilter->SetInput(reader->GetOutput());

ReportProgressToCOutType::Pointer reportDiffusionProgress = ReportProgressToCOutType::New();
diffusionFilter->AddObserver(ProgressEvent(), reportDiffusionProgress);

int argIndex = 3;
if (argIndex < argc)
{
const double diffusionTime = std::stod(argv[argIndex++]);
if (diffusionTime == 0)
itkGenericExceptionMacro("Error: Unrecognized diffusion time (third argument).\n");
diffusionFilter->SetDiffusionTime(diffusionTime);
}

if (argIndex < argc)
{
const double lambda = std::stod(argv[argIndex++]);
if (lambda == 0.)
itkGenericExceptionMacro("Error: Unrecognized lambda (fourth argument).\n");
diffusionFilter->SetLambda(lambda);
}

if (argIndex < argc)
{
const char * enhancement = argv[argIndex++];
if (!strcmp(enhancement, "EED"))
diffusionFilter->SetEnhancement(DiffusionFilterType::EED); // Weickert's exponent : 4.
else if (!strcmp(enhancement, "cEED"))
diffusionFilter->SetEnhancement(DiffusionFilterType::cEED); // Weickert's exponent : 4.
else if (!strcmp(enhancement, "CED"))
diffusionFilter->SetEnhancement(DiffusionFilterType::CED); // Weickert's exponent : 2.
else if (!strcmp(enhancement, "cCED"))
diffusionFilter->SetEnhancement(DiffusionFilterType::cCED); // Weickert's exponent : 2.
else if (!strcmp(enhancement, "Isotropic"))
diffusionFilter->SetEnhancement(DiffusionFilterType::Isotropic); // Perona-Mali's exponent: 2.
else
itkGenericExceptionMacro("Error: Unrecognized enhancement (fifth argument).\n");
}

if (argIndex < argc)
{
const double noiseScale = std::stod(argv[argIndex++]);
if (noiseScale == 0.)
itkGenericExceptionMacro("Error: Unrecognized noiseScale (sixth argument).\n");
diffusionFilter->SetNoiseScale(noiseScale);
}

if (argIndex < argc)
{
const double featureScale = std::stod(argv[argIndex++]);
if (featureScale == 0.)
itkGenericExceptionMacro("Error: Unrecognized featureScale (seventh argument).\n");
diffusionFilter->SetFeatureScale(featureScale);
}

if (argIndex < argc)
{
const double exponent = std::stod(argv[argIndex++]);
if (exponent == 0.)
itkGenericExceptionMacro("Error: Unrecognized exponent (eighth argument).\n");
diffusionFilter->SetExponent(exponent);
}

if (argIndex < argc)
{
itkGenericExceptionMacro("Error: excessive number of arguments");
}

/*{
std::cerr <<
"T: " << diffusionFilter->GetDiffusionTime() << "\n" <<
"Lambda: " << diffusionFilter->GetLambda() << "\n" <<
"argc: " << argc << "\n";

diffusionFilter->Update();
auto image = diffusionFilter->GetOutput();
std::cerr <<
image->GetBufferedRegion() << "\n\n" <<
"pixel export size: " << sizeof(ExportPixelType) << "\n";
;

}*/

using ExportImageType = Image<ExportPixelType, Dimension>;
using CasterType = CastImageFilter<ImageType, ExportImageType>;
typename CasterType::Pointer caster = CasterType::New();
caster->SetInput(diffusionFilter->GetOutput());

// using ScalarImageType = typename DiffusionFilterType::ScalarImageType;
using WriterType = ImageFileWriter<ExportImageType>;
typename WriterType::Pointer writer = WriterType::New();
writer->SetInput(caster->GetOutput());
writer->SetFileName(outputFileName);

itk::TimeProbe clock;
clock.Start();
writer->Update();
clock.Stop();
std::cout << "Took: " << clock.GetMean() << " seconds\n";

return EXIT_SUCCESS;
}

} // end namespace CoherenceEnhancingDiffusionCommandLine

#endif
Loading
Loading