Smooth Image While Preserving Edges#

Synopsis#

Smooth an image while preserving edges.

Results#

../../../../_images/Yinyang10.png

Input image.#

../../../../_images/SmoothImageWhilePreservingEdges.png

Output In VTK Window#

Code#

C++#

#include "itkImage.h"
#include "itkCastImageFilter.h"
#include "itkImageFileReader.h"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.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 VectorGradientAnisotropicDiffusionImageFilterType =
    itk::VectorGradientAnisotropicDiffusionImageFilter<FloatImageType, FloatImageType>;
  VectorGradientAnisotropicDiffusionImageFilterType::Pointer filter =
    VectorGradientAnisotropicDiffusionImageFilterType::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 << "VectorGradientAnisotropicDiffusionImageFilter\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 VectorGradientAnisotropicDiffusionImageFilter : public itk::AnisotropicDiffusionImageFilter<TInputImage, TOutputImage>

This filter performs anisotropic diffusion on a vector itk::Image using the anisotropic diffusion function implemented implemented in itkVectorGradientNDAnisotropicDiffusionFunction. For detailed information on anisotropic diffusion see itkAnisotropicDiffusionFunction, itkVectorGradientNDAnisotropicDiffusionFunction, and itkGradientAnisotropicDiffusionFunction.

The maximum allowable time step for this filter is 1/2^N, where N is the dimensionality of the image. For 2D images any value below 0.250 is stable, and for 3D images, any value below 0.125 is stable.

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 read all the documentation found in AnisotropicDiffusionImageFilter and AnisotropicDiffusionFunction. Also see VectorGradientNDAnisotropicDiffusionFunction.

ITK Sphinx Examples:

See itk::VectorGradientAnisotropicDiffusionImageFilter for additional documentation.