ImageDev

AutoThresholdingBright

Computes and applies an automatic threshold on a gray level image to detect bright particles on a dark background.

Access to parameter description

For an introduction: This algorithm computes an automatic threshold on a grayscale image; that is, it separates the input image in two classes of pixels from an input range $[I_1, I_2]$. Four methods of classification are available to determine $C_0$ and $C_1$: Entropy, Factorisation, Moments, and Isodata.
The computed threshold is returned in the AutoThresholdingMsr object.

Entropy

The entropy principle defines 2 classes in the image histogram by minimizing the total classes entropy. For a more theoretical context, one can refer to references [1] and [2].
Considering the first-order probability histogram of an image and assuming that all symbols in the following equation are statistically independent, its entropy (in the Shannon meaning) is defined as: $$ H=-\sum_{i=0}^{n} p[i] \times \log(p[i])_ 2 $$ Where $n+1$ is the number of grayscales, $p[i]$ the probability of the $i$ level occurrence, and $log(x)_2$ is the binary logarithm.

Let us denote $t$ as the value of the threshold, and $[I_1,I_2]$ the search interval. One can define two partial entropies: $$ H_w[t]=-\sum_{I_1}^{t} p_1[i] \times \log(p_1[i])_2 $$ $$ H_b[t]=-\sum_{t+1}^{I_2} p_2[i] \times \log(p_2[i])_2 $$ Where $p_1[i]$ defines the probability of the $i$ level occurrence in the range $[I_1,t]$ and $p_2[i]$ defines the probability of the $i$ level occurrence in the range [t+1,I2]. We search the threshold value $T$ which minimizes the sum $S(t)=H_w[t]+H_b[t]$: $$ T=\arg min_t(H_w[t]+H_b[t]) $$


Figure 1. Example of thresholding using the entropy method

Factorization

The factorization method is based on the Otsu criterion [3], i.e., minimizing the within-class variance of classes $C_0=[I_1,t]$ and $C_1=[t+1,I_2]$: $$\sigma^2_W[t]=w_0[t] \times \sigma_0^2[t]+w_1[t] \times \sigma_1^2[t]$$ Where $w_0[t]$ and $w_1[t]$ are the occurrence probabilities, $\sigma_0^2$ and $\sigma_1^2$ the variances, of classes $C_0$ and $C_1$.

A faster and equivalent approach is to maximize the between-class variance: $$ \sigma_B^2[t]=w_0[t] \times w_1[t] \times (\mu_0[t]-\mu_1[t])^2 $$ Where $\mu_0$ and $\mu_1$ are respectively the mean of the class $C_0$ and $C_1$.
The within-class variance calculation is based on the second-order statistics (variances), while the between-class variance calculation is based on the first order statistics (means). It is therefore simpler and faster to use this last optimization criterion. We then search the value $T$ which maximizes the between-class variance such as: $$ T=\arg min_t(\sigma_B^2[t]) $$


Figure 2. Example of thresholding using the factorization method

Moments

The moment method uses the moment-preserving bi-level thresholding described by W.H.Tsai in [4].
Moments of an image can be computed from its histogram in the following way: $$ m_j=\sum_{i=0}^n p[z_i]^j $$ Where $p[z_i]$ is the probability of occurrence of grayscale $z_i$.

For the following we note $f$ as the original grayscale image and $g$ as the thresholded image. Image $f$ can be considered as a blurred version of an ideal bi-level image which consists of pixels with only two gray values: $z_0$ and $z_1$.

The moment-preserving thresholding principle is to select a threshold value such that if all below-threshold gray values of the original image are replaced by $z_0$ and all above threshold gray values replaced by $z_1$, then the first three moments of the original image are preserved in the resulting bi-level image. Image $g$ so obtained may be regarded as an ideal unblurred version of $f$.
Let $p_0$ and $p_1$ denote the fractions of the below-threshold pixels and the above-threshold pixels in $f$, respectively, then the first three moments of $g$ are: $$ m'_j= p_0^j+p_1^j\mbox{, j=0,1,2,3} $$ And preserving the first three moments in $g$, means the equalities: $$ m'_j=m_j\mbox{, j=0,1,2,3} $$ To find the desired threshold value $T$, we can first solve the four equations system to obtain $p_0$ and $p_1$, and then choose $T$ as the $p_0$-tile of the histogram of $f$. Note that $z_0$ and $z_1$ also will be obtained simultaneously as part of the solutions of system.



Figure 3. Example of thresholding using the moment-preserving method

Isodata

The Isodata method implements an iterative global thresholding algorithm, which is based on the gray value histogram of the data [5].

From an initial threshold $t$, a new threshold $T$ is computed as the mean value of the averages of both classes: $$ T = \frac{\mu_0[t]+\mu_1[t]}{2} $$ Where $\mu_0$ and $\mu_1$ are respectively the mean of the class $C_0$ and $C_1$.
This process is reiterated until convergence; that is, when the new threshold $T$ is not significantly different than the previous one $t$.



Figure 4. Example of thresholding using the Isodata method


References: See also
See related example

Function Syntax

This function returns a AutoThresholdingBrightOutput structure containing outputBinaryImage and outputMeasurement.
// Output structure of the autoThresholdingBright function.
struct AutoThresholdingBrightOutput
{
    /// The output binary image. Its dimensions are forced to the same values as the input.
    std::shared_ptr< iolink::ImageView > outputBinaryImage;
    /// The computed threshold value.
    AutoThresholdingMsr::Ptr outputMeasurement;
};

// Function prototype
AutoThresholdingBrightOutput autoThresholdingBright( std::shared_ptr< iolink::ImageView > inputGrayImage, AutoThresholdingBright::RangeMode rangeMode, iolink::Vector2d intensityInputRange, AutoThresholdingBright::ThresholdCriterion thresholdCriterion, std::shared_ptr< iolink::ImageView > outputBinaryImage = NULL, AutoThresholdingMsr::Ptr outputMeasurement = NULL );
This function returns a tuple containing output_binary_image and output_measurement.
// Function prototype.
auto_thresholding_bright( input_gray_image,
                          range_mode = AutoThresholdingBright.RangeMode.MIN_MAX,
                          intensity_input_range = [0, 255],
                          threshold_criterion = AutoThresholdingBright.ThresholdCriterion.ENTROPY,
                          output_binary_image = None,
                          output_measurement = None )
This function returns a AutoThresholdingBrightOutput structure containing outputBinaryImage and outputMeasurement.
/// Output structure of the AutoThresholdingBright function.
public struct AutoThresholdingBrightOutput
{
    /// 
    /// The output binary image. Its dimensions are forced to the same values as the input.
    /// 
    public IOLink.ImageView outputBinaryImage;
    /// The computed threshold value.
    public AutoThresholdingMsr outputMeasurement;
};

// Function prototype.
public static AutoThresholdingBrightOutput
AutoThresholdingBright( IOLink.ImageView inputGrayImage,
                        AutoThresholdingBright.RangeMode rangeMode = ImageDev.AutoThresholdingBright.RangeMode.MIN_MAX,
                        double[] intensityInputRange = null,
                        AutoThresholdingBright.ThresholdCriterion thresholdCriterion = ImageDev.AutoThresholdingBright.ThresholdCriterion.ENTROPY,
                        IOLink.ImageView outputBinaryImage = null,
                        AutoThresholdingMsr outputMeasurement = null );

Class Syntax

Parameters

Class Name AutoThresholdingBright

Parameter Name Description Type Supported Values Default Value
input
inputGrayImage
The input grayscale image. Image Grayscale nullptr
input
rangeMode
The way to determine the input intensity range.
MIN_MAX The histogram is computed between the minimum and the maximum of the image.
OTHER The histogram is computed between user-defined bounds [a,b].
Enumeration MIN_MAX
input
intensityInputRange
The input intensity range [a,b] inside which the threshold is searched. This parameter is ignored if the range mode is set to MIN_MAX. Vector2d Any value {0.f, 255.f}
input
thresholdCriterion
The criterion to compute the threshold from the histogram.
ENTROPY The measure of dispersion used in the algorithm is the entropy of the intensity distribution.
FACTORISATION The measure of dispersion used in the algorithm is the variance of the intensity distribution (also known as Otsu method).
MOMENTS The measure of dispersion used in the algorithm is the moments of the intensity distribution.
ISODATA The measure of dispersion used in the algorithm is the isodata of the intensity distribution.
Enumeration ENTROPY
output
outputBinaryImage
The output binary image. Its dimensions are forced to the same values as the input. Image nullptr
output
outputMeasurement
The computed threshold value. AutoThresholdingMsr nullptr

Object Examples

std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" );

AutoThresholdingBright autoThresholdingBrightAlgo;
autoThresholdingBrightAlgo.setInputGrayImage( polystyrene );
autoThresholdingBrightAlgo.setRangeMode( AutoThresholdingBright::RangeMode::MIN_MAX );
autoThresholdingBrightAlgo.setIntensityInputRange( {0, 255} );
autoThresholdingBrightAlgo.setThresholdCriterion( AutoThresholdingBright::ThresholdCriterion::ENTROPY );
autoThresholdingBrightAlgo.execute();

std::cout << "outputBinaryImage:" << autoThresholdingBrightAlgo.outputBinaryImage()->toString();
std::cout << "threshold: " << autoThresholdingBrightAlgo.outputMeasurement()->threshold( 0 ) ;
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif"))

auto_thresholding_bright_algo = imagedev.AutoThresholdingBright()
auto_thresholding_bright_algo.input_gray_image = polystyrene
auto_thresholding_bright_algo.range_mode = imagedev.AutoThresholdingBright.MIN_MAX
auto_thresholding_bright_algo.intensity_input_range = [0, 255]
auto_thresholding_bright_algo.threshold_criterion = imagedev.AutoThresholdingBright.ENTROPY
auto_thresholding_bright_algo.execute()

print( "output_binary_image:", str( auto_thresholding_bright_algo.output_binary_image ) )
print( "threshold: ", str( auto_thresholding_bright_algo.output_measurement.threshold( 0 ) ) )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" );

AutoThresholdingBright autoThresholdingBrightAlgo = new AutoThresholdingBright
{
    inputGrayImage = polystyrene,
    rangeMode = AutoThresholdingBright.RangeMode.MIN_MAX,
    intensityInputRange = new double[]{0, 255},
    thresholdCriterion = AutoThresholdingBright.ThresholdCriterion.ENTROPY
};
autoThresholdingBrightAlgo.Execute();

Console.WriteLine( "outputBinaryImage:" + autoThresholdingBrightAlgo.outputBinaryImage.ToString() );
Console.WriteLine( "threshold: " + autoThresholdingBrightAlgo.outputMeasurement.threshold( 0 ) );

Function Examples

std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" );

auto result = autoThresholdingBright( polystyrene, AutoThresholdingBright::RangeMode::MIN_MAX, {0, 255}, AutoThresholdingBright::ThresholdCriterion::ENTROPY );

std::cout << "outputBinaryImage:" << result.outputBinaryImage->toString();
std::cout << "threshold: " << result.outputMeasurement->threshold( 0 ) ;
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif"))

result_output_binary_image, result_output_measurement = imagedev.auto_thresholding_bright( polystyrene, imagedev.AutoThresholdingBright.MIN_MAX, [0, 255], imagedev.AutoThresholdingBright.ENTROPY )

print( "output_binary_image:", str( result_output_binary_image ) )
print( "threshold: ", str( result_output_measurement.threshold( 0 ) )  )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" );

Processing.AutoThresholdingBrightOutput result = Processing.AutoThresholdingBright( polystyrene, AutoThresholdingBright.RangeMode.MIN_MAX, new double[]{0, 255}, AutoThresholdingBright.ThresholdCriterion.ENTROPY );

Console.WriteLine( "outputBinaryImage:" + result.outputBinaryImage.ToString() );
Console.WriteLine(  "threshold: " + result.outputMeasurement.threshold( 0 )  );