Median Filtering Of An RGB Image

Synopsis

Apply median filtering on a RGB Image. The sorting of pixel is performed on their luminance.

Results

Input image

Input image

Output image

Output image

Code

C++

#include "itkMedianImageFilter.h"

#include "itkRGBPixel.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

namespace itk
{
/** \class myRGBPixel
 * \brief Extends RGBPixel with operator <=
 *
 * This class overrides the <= and < operators to use Luminance as a sorting
 * value.
 */
template <typename TComponent = unsigned short>
class myRGBPixel : public RGBPixel<TComponent>
{
public:
  using Self = myRGBPixel;
  using Superclass = RGBPixel<TComponent>;

  using RGBPixel<TComponent>::operator=;

  bool
  operator<=(const Self & r) const
  {
    return (this->GetLuminance() <= r.GetLuminance());
  }
  bool
  operator<(const Self & r) const
  {
    return (this->GetLuminance() < r.GetLuminance());
  }
};
} // namespace itk

int
main(int argc, char * argv[])
{
  // Verify command line arguments
  if (argc != 4)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " <InputImageFile> <OutputImageFile> <radius>" << std::endl;
    return EXIT_FAILURE;
  }

  // Setup types
  constexpr unsigned int Dimension = 2;

  using MyPixelType = itk::myRGBPixel<unsigned char>;
  using MyImageType = itk::Image<MyPixelType, Dimension>;

  // Create and setup a reader
  using ReaderType = itk::ImageFileReader<MyImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(argv[1]);

  // Create and setup a median filter
  using FilterType = itk::MedianImageFilter<MyImageType, MyImageType>;
  FilterType::Pointer medianFilter = FilterType::New();

  FilterType::InputSizeType radius;
  radius.Fill(std::stoi(argv[3]));

  medianFilter->SetRadius(radius);
  medianFilter->SetInput(reader->GetOutput());

  // Cast the custom myRBGPixel's to RGBPixel's
  using RGBPixelType = itk::RGBPixel<unsigned char>;
  using RGBImageType = itk::Image<RGBPixelType, Dimension>;
  using CastType = itk::CastImageFilter<MyImageType, RGBImageType>;
  CastType::Pointer cast = CastType::New();
  cast->SetInput(medianFilter->GetOutput());

  using WriterType = itk::ImageFileWriter<RGBImageType>;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(cast->GetOutput());
  writer->SetFileName(argv[2]);

  try
  {
    writer->Update();
  }
  catch (itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Classes demonstrated