Core Optical, Inc.
OtsuThresholder ClassIndustrial Strength, Scientific Grade
Encapsulates the Otsu threshold binarization operation.
Inheritance Hierarchy

OnlineSystem Object
  PrecisionImage.BinarizationAndMorphology OtsuThresholder

Namespace: PrecisionImage.BinarizationAndMorphology
Assembly: PrecisionImage (in PrecisionImage.dll) Version: 2.0.0.0 (2.0.0.0)
Syntax

public class OtsuThresholder
Remarks

This class is used to apply the Otsu thresholding method of data binarization. The Otsu method computes a globally-optimum threshold based on the assumption that the input image consists of two classes of objects (typically referred to as foreground and background objects). The histogram of an input image is computed and a threshold value is chosen such that the variance between the foreground and background classes is at a maximum.

PrecisionImage.NET implements a version of the Otsu algorithm that takes, as an optional input argument, a BinaryMask object that can be used to instruct the algorithm to bypass arbitrarily-shaped regions in the input data when computing the histogram and threshold. If a BinaryMask object is included as an input argument, the masked regions in that object will be unmasked in the output BinaryMask object returned from the thresholding operation. Only the unmasked area in the optional input BinaryMask will be analyzed and thresholded. This affords a mechanism whereby the Otsu thresholding operation can be called recursively, with the BinaryMask object returned from one operation being fed into the following thresholding operation to iteratively segment foreground and background regions of an image.

If an (optional) region of interest is specified when invoking the thresholding operation, only the area of the image enclosed by the region of interest and the (optional) binary mask will be analyzed and thresholded.

Examples

The following example illustrates how to retrieve a BinaryMask object based on the Otsu-thresholded input data.

using PrecisionImage;
using PrecisionImage.HistogramProcessing;
using PrecisionImage.BinarizationAndMorphology;

// Read the source image from disk and load into a SourceData object: 
Uri imageUri                   = new Uri("Skull.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource SourceImage       = imageDecoder.Frames[0];
SourceData sourceData          = new SourceData(SourceImage, GammaEncoding.None);

// Instantiate an OtsuThresholder object and retrieve the thresholded BinaryMask: 
OtsuThresholder thresholder = new OtsuThresholder();
BinaryMask thresholdMask    = thresholder.GetThresholdBinaryMask(sourceData, 0, HistogramResolution.SixteenBit);

// Display the original image and the Otsu Binarymask:
image1.Source = sourceData.GetChannelImage(GrayBitDepth.EightBit, 0, GammaEncoding.None);
image2.Source = thresholdMask.GetMaskImage();

The above example generates the following image pair:

The Otsu thresholding operation can be made adaptive by preconditioning the input data with an adaptive contrast enhancement step. This is illustrated in the following example:

using PrecisionImage;
using PrecisionImage.HistogramProcessing;
using PrecisionImage.BinarizationAndMorphology;

// Read the source image from disk and load into a SourceData object: 
Uri imageUri                   = new Uri("Skull.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource SourceImage       = imageDecoder.Frames[0];
SourceData sourceData          = new SourceData(SourceImage, GammaEncoding.None);

// Clone the original data into a new object: 
SourceData equalizedSource = sourceData.Clone();

// Apply the adaptive contrast enhancement to the cloned data object: 
HistogramProcessor histogramProcessor = new HistogramProcessor();
histogramProcessor.AdaptivelyEqualizeHistogramInPlace(equalizedSource, 0, 35, 0.015f);

// Instantiate an OtsuThresholder object and retrieve the thresholded BinaryMask from the enhanced data: 
OtsuThresholder thresholder = new OtsuThresholder();
BinaryMask thresholdMask    = thresholder.GetThresholdBinaryMask(equalizedSource, 0, HistogramResolution.SixteenBit);

// Display the original image and the Otsu BinaryMask:
image1.Source = sourceData.GetChannelImage(GrayBitDepth.EightBit, 0, GammaEncoding.None);
image2.Source = thresholdMask.GetMaskImage();

The above example generates the following image pair:

Lastly, excellent results can be achieved by combining the results from the original Otsu thresholding with the adaptively enhanced thresholding via a mask fusion operation. This approach is illustrated in the following example:

using PrecisionImage;
using PrecisionImage.HistogramProcessing;
using PrecisionImage.BinarizationAndMorphology;

// Read the source image from disk and load into a SourceData object: 
Uri imageUri                   = new Uri("Skull.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource SourceImage       = imageDecoder.Frames[0];
SourceData sourceData          = new SourceData(SourceImage, GammaEncoding.None);

// Instantiate an OtsuThresholder object and retrieve the thresholded BinaryMask: 
OtsuThresholder thresholder = new OtsuThresholder();
BinaryMask thresholdMask    = thresholder.GetThresholdBinaryMask(sourceData, 0, HistogramResolution.SixteenBit);

// Clone the original data into a new object: 
SourceData equalizedSource = sourceData.Clone();

// Apply the adaptive contrast enhancement to the cloned data object: 
HistogramProcessor histogramProcessor = new HistogramProcessor();
histogramProcessor.AdaptivelyEqualizeHistogramInPlace(equalizedSource, 0, 35, 0.015f);

// Retrieve an Otsu-thresholded BinaryMask from the adaptively equalized data: 
BinaryMask equalizedMask = thresholder.GetThresholdBinaryMask(equalizedSource, 0, HistogramResolution.SixteenBit);

// Fuse the unmasked regions of the two BinaryMask objects to retrieve the final threshold result: 
BinaryMask adaptiveThresholdMask = BinaryMask.GetFusedMask(thresholdMask, equalizedMask, false);

The above example generates the following image pair:

See Also