Smooth RGB Image Using Curvature Flow

Synopsis

Smooth an RGB image using curvature flow.

Results

input image

Input image.

../../../../_images/SmoothRGBImageUsingCurvatureFlow.png

Output In VTK Window

Code

C++

#include "itkImageAdaptor.h"
#include "itkImageRegionIterator.h"
#include "itkNthElementImageAdaptor.h"
#include "itkCurvatureFlowImageFilter.h"
#include "itkComposeImageFilter.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkRGBPixel.h"

#include <sstream>

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

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

  int iterations = 5;
  if (argc > 2)
  {
    std::stringstream ss(argv[2]);
    ss >> iterations;
  }
  std::string inputFilename = argv[1];

  // Setup types
  using ComponentType = float;
  using PixelType = itk::RGBPixel<ComponentType>;
  using RGBImageType = itk::Image<PixelType, 2>;
  using ImageType = itk::Image<ComponentType, 2>;
  using ReaderType = itk::ImageFileReader<RGBImageType>;
  using ImageAdaptorType = itk::NthElementImageAdaptor<RGBImageType, unsigned char>;
  using ComposeType = itk::ComposeImageFilter<ImageType, RGBImageType>;
  using CurvatureFlowType = itk::CurvatureFlowImageFilter<ImageAdaptorType, ImageType>;

  // Create and setup a reader
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFilename);
  reader->Update();

  // Run the filter for each component
  ImageAdaptorType::Pointer rAdaptor = ImageAdaptorType::New();
  rAdaptor->SelectNthElement(0);
  rAdaptor->SetImage(reader->GetOutput());

  CurvatureFlowType::Pointer rCurvatureFilter = CurvatureFlowType::New();
  rCurvatureFilter->SetInput(rAdaptor);
  rCurvatureFilter->SetNumberOfIterations(iterations);
  rCurvatureFilter->Update();

  ImageAdaptorType::Pointer gAdaptor = ImageAdaptorType::New();
  gAdaptor->SelectNthElement(1);
  gAdaptor->SetImage(reader->GetOutput());

  CurvatureFlowType::Pointer gCurvatureFilter = CurvatureFlowType::New();
  gCurvatureFilter->SetInput(gAdaptor);
  gCurvatureFilter->SetNumberOfIterations(iterations);
  gCurvatureFilter->Update();

  ImageAdaptorType::Pointer bAdaptor = ImageAdaptorType::New();
  bAdaptor->SelectNthElement(2);
  bAdaptor->SetImage(reader->GetOutput());

  CurvatureFlowType::Pointer bCurvatureFilter = CurvatureFlowType::New();
  bCurvatureFilter->SetInput(bAdaptor);
  bCurvatureFilter->SetNumberOfIterations(iterations);
  bCurvatureFilter->Update();

  // compose an RGB image from the three filtered images

  ComposeType::Pointer compose = ComposeType::New();
  compose->SetInput1(rCurvatureFilter->GetOutput());
  compose->SetInput2(gCurvatureFilter->GetOutput());
  compose->SetInput3(bCurvatureFilter->GetOutput());

#ifdef ENABLE_QUICKVIEW
  QuickView viewer;
  viewer.AddRGBImage(reader->GetOutput(), true, itksys::SystemTools::GetFilenameName(inputFilename));

  std::stringstream desc;
  desc << "CurvatureFlow iterations = " << iterations;
  viewer.AddRGBImage(compose->GetOutput(), true, desc.str());

  viewer.Visualize();
#endif
  return EXIT_SUCCESS;
}

Classes demonstrated