Remove Holes Not Connected to Image Boundaries#

Synopsis#

Remove holes in one binary image not connected to its boundary. In this case the foreground value for the image is taken to be zero (black), and everything is filled in within the black boundary.

Results#

Input image

Input image#

Output image

Output image#

Code#

Python#

#!/usr/bin/env python

import itk
import argparse

parser = argparse.ArgumentParser(
    description="Remove Holes Not Connected To Image Boundaries."
)
parser.add_argument("input_image")
parser.add_argument("output_image")
args = parser.parse_args()

Dimension = 2

PixelType = itk.UC
ImageType = itk.Image[PixelType, Dimension]

ReaderType = itk.ImageFileReader[ImageType]
reader = ReaderType.New()
reader.SetFileName(args.input_image)

FilterType = itk.BinaryFillholeImageFilter[ImageType]
binaryfillholefilter = FilterType.New()
binaryfillholefilter.SetInput(reader.GetOutput())
binaryfillholefilter.SetForegroundValue(itk.NumericTraits[PixelType].min())

WriterType = itk.ImageFileWriter[ImageType]
writer = WriterType.New()
writer.SetFileName(args.output_image)
writer.SetInput(binaryfillholefilter.GetOutput())
writer.Update()

C++#

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkBinaryFillholeImageFilter.h"

int
main(int argc, char * argv[])
{
  if (argc != 3)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0];
    std::cerr << " <InputFileName> <OutputFileName>";
    std::cerr << std::endl;
    return EXIT_FAILURE;
  }

  const char * inputFileName = argv[1];
  const char * outputFileName = argv[2];

  constexpr unsigned int Dimension = 2;

  using PixelType = unsigned char;
  using ImageType = itk::Image<PixelType, Dimension>;

  const auto input = itk::ReadImage<ImageType>(inputFileName);

  using FilterType = itk::BinaryFillholeImageFilter<ImageType>;
  auto filter = FilterType::New();
  filter->SetInput(input);
  filter->SetForegroundValue(itk::NumericTraits<PixelType>::min());

  try
  {
    itk::WriteImage(filter->GetOutput(), outputFileName);
  }
  catch (const itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Classes demonstrated#

template<typename TInputImage>
class BinaryFillholeImageFilter : public itk::ImageToImageFilter<TInputImage, TInputImage>

Remove holes not connected to the boundary of the image.

BinaryFillholeImageFilter fills holes in a binary image.

Geodesic morphology and the Fillhole algorithm is described in Chapter 6 of Pierre Soille’s book “Morphological Image Analysis:

Principles and Applications”, Second Edition, Springer, 2003.

This implementation was taken from the Insight Journal paper:

https://www.insight-journal.org/browse/publication/176
Author

Gaetan Lehmann. Biologie du Developpement et de la Reproduction, INRA de Jouy-en-Josas, France.

See

GrayscaleFillholeImageFilter

See itk::BinaryFillholeImageFilter for additional documentation.