Smooth Image While Preserving Edges (Curvature)#

Synopsis#

Smooth an image while preserving edges.

Results#

../../../../_images/Yinyang11.png

Input image.#

../../../../_images/SmoothImageWhilePreservingEdges2.png

Output In VTK Window#

Code#

C++#

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorToRGBImageAdaptor.h"
#include "itkRGBToVectorImageAdaptor.h"
#include "itkCastImageFilter.h"

#include "itksys/SystemTools.hxx"
#include <sstream>

#ifdef ENABLE_QUICKVIEW
#  include "QuickView.h"
#endif

int
main(int argc, char * argv[])
{
  // Verify arguments
  if (argc < 2)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0];
    std::cerr << " InputFileName";
    std::cerr << " [NumberOfIterations] ";
    std::cerr << " [Conductance]" << std::endl;
    return EXIT_FAILURE;
  }

  // 0) Parse arguments
  std::string inputFileName = argv[1];

  using FloatImageType = itk::Image<itk::Vector<float, 3>, 2>;
  using RGBImageType = itk::Image<itk::RGBPixel<float>, 2>;

  // 1) Read the RGB image
  const auto input = itk::ReadImage<RGBImageType>(inputFileName);

  // 2) Cast to Vector image for processing
  using AdaptorInputType = itk::RGBToVectorImageAdaptor<RGBImageType>;
  auto adaptInput = AdaptorInputType::New();
  adaptInput->SetImage(input);
  using CastInputType = itk::CastImageFilter<AdaptorInputType, FloatImageType>;
  auto castInput = CastInputType::New();
  castInput->SetInput(adaptInput);

  // 3) Smooth the image
  using VectorCurvatureAnisotropicDiffusionImageFilterType =
    itk::VectorCurvatureAnisotropicDiffusionImageFilter<FloatImageType, FloatImageType>;
  VectorCurvatureAnisotropicDiffusionImageFilterType::Pointer filter =
    VectorCurvatureAnisotropicDiffusionImageFilterType::New();
  filter->SetInput(castInput->GetOutput());
  filter->SetTimeStep(0.125);
  if (argc > 2)
  {
    filter->SetNumberOfIterations(atoi(argv[2]));
  }
  if (argc > 3)
  {
    filter->SetConductanceParameter(atof(argv[3]));
  }

  // 4) Cast the Vector image to an RGB image for display
  using AdaptorOutputType = itk::VectorToRGBImageAdaptor<FloatImageType>;
  auto adaptOutput = AdaptorOutputType::New();
  adaptOutput->SetImage(filter->GetOutput());
  using CastOutputType = itk::CastImageFilter<AdaptorOutputType, RGBImageType>;
  auto castOutput = CastOutputType::New();
  castOutput->SetInput(adaptOutput);

  // 5) Display the input and smoothed images
#ifdef ENABLE_QUICKVIEW
  QuickView viewer;
  viewer.AddRGBImage(input.GetPointer(), true, itksys::SystemTools::GetFilenameName(inputFileName));

  std::stringstream desc;
  desc << "VectorCurvatureAnisotropicDiffusionImageFilter\niterations: " << filter->GetNumberOfIterations()
       << " conductance: " << filter->GetConductanceParameter();
  viewer.AddRGBImage(castOutput->GetOutput(), true, desc.str());

  viewer.Visualize();
#endif

  return EXIT_SUCCESS;
}

Classes demonstrated#

template<typename TInputImage, typename TOutputImage>
class VectorCurvatureAnisotropicDiffusionImageFilter : public itk::AnisotropicDiffusionImageFilter<TInputImage, TOutputImage>

This filter performs anisotropic diffusion on a vector itk::Image using the modified curvature diffusion equation (MCDE) implemented in itkVectorCurvatureNDAnisotropicDiffusionFunction. For detailed information on anisotropic diffusion and the MCDE see itkAnisotropicDiffusionFunction, itkVectorCurvatureNDAnisotropicDiffusionFunction, and itkCurvatureNDAnisotropicDiffusionFunction.

The default time step for this filter is set to the maximum theoretically stable value: 0.5 / 2^N, where N is the dimensionality of the image. For a 2D image, this means valid time steps are below 0.1250. For a 3D image, valid time steps are below 0.0625.

Inputs and Outputs

The input to this filter must be an itk::Image with pixel type which is either an itk::Vector, or a subclass of an itk::Vector. Additionally, the component type of the vector should be a numerical type (float or double, or a user defined type which correctly defines arithmetic operations with floating point accuracy). The output image type also has these requirements.

Parameters

Please first read all the documentation found in AnisotropicDiffusionImageFilter and AnisotropicDiffusionFunction. Also see VectorCurvatureNDAnisotropicDiffusionFunction.

See

AnisotropicDiffusionImageFilter

See

AnisotropicDiffusionFunction

See

CurvatureNDAnisotropicDiffusionFunction

ITK Sphinx Examples:

See itk::VectorCurvatureAnisotropicDiffusionImageFilter for additional documentation.