Threshold an Image Using Otsu#
Synopsis#
Threshold an Image using Otsu’s method.
Results#
Code#
Python#
#!/usr/bin/env python
import itk
import argparse
parser = argparse.ArgumentParser(description="Threshold An Image Using Otsu.")
parser.add_argument("input_image")
parser.add_argument("output_image")
parser.add_argument("number_of_histogram_bins", type=int)
parser.add_argument("number_of_thresholds", type=int)
parser.add_argument("label_offset", type=int)
args = parser.parse_args()
PixelType = itk.UC
Dimension = 2
ImageType = itk.Image[PixelType, Dimension]
reader = itk.ImageFileReader[ImageType].New()
reader.SetFileName(args.input_image)
thresholdFilter = itk.OtsuMultipleThresholdsImageFilter[ImageType, ImageType].New()
thresholdFilter.SetInput(reader.GetOutput())
thresholdFilter.SetNumberOfHistogramBins(args.number_of_histogram_bins)
thresholdFilter.SetNumberOfThresholds(args.number_of_thresholds)
thresholdFilter.SetLabelOffset(args.label_offset)
rescaler = itk.RescaleIntensityImageFilter[ImageType, ImageType].New()
rescaler.SetInput(thresholdFilter.GetOutput())
rescaler.SetOutputMinimum(0)
rescaler.SetOutputMaximum(255)
writer = itk.ImageFileWriter[ImageType].New()
writer.SetFileName(args.output_image)
writer.SetInput(rescaler.GetOutput())
writer.Update()
C++#
#include "itkImageFileReader.h"
#include "itkOtsuMultipleThresholdsImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkImageFileWriter.h"
int
main(int argc, char * argv[])
{
if (argc < 6)
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << std::endl;
std::cerr << " <InputImage> <OutputImage> <NumberOfBins>";
std::cerr << " <NumberOfThresholds> <LabelOffset>" << std::endl;
return EXIT_FAILURE;
}
constexpr unsigned int Dimension = 2;
using PixelType = unsigned char;
using SizeType = itk::SizeValueType;
const char * InputImage = argv[1];
const char * OutputImage = argv[2];
const auto NumberOfHistogramBins = static_cast<SizeType>(atoi(argv[3]));
const auto NumberOfThresholds = static_cast<SizeType>(atoi(argv[4]));
const auto LabelOffset = static_cast<PixelType>(atoi(argv[5]));
using ImageType = itk::Image<PixelType, Dimension>;
const auto input = itk::ReadImage<ImageType>(InputImage);
using FilterType = itk::OtsuMultipleThresholdsImageFilter<ImageType, ImageType>;
auto filter = FilterType::New();
filter->SetInput(input);
filter->SetNumberOfHistogramBins(NumberOfHistogramBins);
filter->SetNumberOfThresholds(NumberOfThresholds);
filter->SetLabelOffset(LabelOffset);
FilterType::ThresholdVectorType thresholds = filter->GetThresholds();
std::cout << "Thresholds:" << std::endl;
for (double threshold : thresholds)
{
std::cout << threshold << std::endl;
}
std::cout << std::endl;
using RescaleType = itk::RescaleIntensityImageFilter<ImageType, ImageType>;
auto rescaler = RescaleType::New();
rescaler->SetInput(filter->GetOutput());
rescaler->SetOutputMinimum(0);
rescaler->SetOutputMaximum(255);
try
{
itk::WriteImage(rescaler->GetOutput(), OutputImage);
}
catch (const itk::ExceptionObject & e)
{
std::cerr << "Error: " << e << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Classes demonstrated#
-
template<typename TInputImage, typename TOutputImage>
class OtsuMultipleThresholdsImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage> Threshold an image using multiple Otsu Thresholds.
This filter creates a labeled image that separates the input image into various classes. The filter computes the thresholds using the OtsuMultipleThresholdsCalculator and applies those thresholds to the input image using the ThresholdLabelerImageFilter. The NumberOfHistogramBins and NumberOfThresholds can be set for the Calculator. The LabelOffset can be set for the ThresholdLabelerImageFilter.
This filter also includes an option to use the valley emphasis algorithm from H.F. Ng, “Automatic thresholding for defect detection”, Pattern Recognition Letters, (27): 1644-1649, 2006. The valley emphasis algorithm is particularly effective when the object to be thresholded is small. See the following tests for examples: itkOtsuMultipleThresholdsImageFilterTest3 and itkOtsuMultipleThresholdsImageFilterTest4 To use this algorithm, simple call the setter: SetValleyEmphasis(true) It is turned off by default.
- See
ScalarImageToHistogramGenerator
- See
OtsuMultipleThresholdsCalculator
- See
ThresholdLabelerImageFilter
- ITK Sphinx Examples: