Otsu Thresholding Explained: Hide Menu
Otsu Thresholding Explained: Hide Menu
Otsu Thresholding Explained: Hide Menu
html
Converting a greyscale image to monochrome is a common image processing task. Otsu's method, named after its
inventor Nobuyuki Otsu, is one of many binarization algorithms. This page describes how the algorithm works and
provides a Java implementation, which can be easily ported to other languages. If you are in a hurry, jump to the code.
Many thanks to Eric Moyer who spotted a potential overflow when two integers are multiplied in the variance calculation. The
example code has been updated with the integers cast to floats during the calculation.
The calculations for finding the foreground and background variances (the measure of spread) for a single threshold are now shown.
In this case the threshold value is 3.
The next step is to calculate the 'Within-Class Variance'. This is simply the sum of the two variances multiplied by their associated
weights.
This final value is the 'sum of weighted variances' for the threshold value 3. This same calculation needs to be performed for all the
possible threshold values 0 to 5. The table below shows the results for these calculations. The highlighted column shows the values
for the threshold calculated above.
Weight,
Wb = 0 Wb = 0.222 Wb = 0.4167 Wb = 0.4722 Wb = 0.6389 Wb = 0.8889
Background
Mean, Mb = 0 Mb = 0 Mb = 0.4667 Mb = 0.6471 Mb = 1.2609 Mb = 2.0313
Background
Variance,
σ2 b = 0 σ2b = 0 σ2b = 0.2489 σ2b = 0.4637 σ2b = 1.4102 σ2b = 2.5303
Background
Weight, Wf = 1 Wf = 0.7778 Wf = 0.5833 Wf = 0.5278 Wf = 0.3611 Wf = 0.1111
Foreground
Mean, Mf = 2.3611 Mf = 3.0357 Mf = 3.7143 Mf = 3.8947 Mf = 4.3077 Mf = 5.000
Foreground
Variance,
σ2f = 3.1196 σ2f = 1.9639 σ2f = 0.7755 σ2f = 0.5152 σ2f = 0.2130 σ2 f = 0
Foreground
Within Class
σ2W = 3.1196 σ2W = 1.5268 σ2W = 0.5561 σ2W = 0.4909 σ2W = 0.9779 σ2W = 2.2491
Variance
It can be seen that for the threshold equal to 3, as well as being used for the example, also has the lowest sum of weighted
variances. Therefore, this is the final selected threshold. All pixels with a level less than 3 are background, all those with a level equal
to or greater than 3 are foreground. As the images in the table show, this threshold works well.
This approach for calculating Otsu's threshold is useful for explaining the theory, but it is computationally intensive, especially if you
have a full 8-bit greyscale. The next section shows a faster method of performing the calculations which is much more appropriate
for implementations.
A Faster Approach
By a bit of manipulation, you can calculate what is called the between class variance, which is far quicker to calculate. Luckily, the
threshold with the maximum between class variance also has the minimum within class variance. So it can also be used for finding
the best threshold and therefore due to being simpler is a much better approach to use.
The table below shows the different variances for each threshold value.
Java Implementation
A simple demo program that uses the Otsu threshold is linked to below.
The important part of the algorithm is shown here. The input is an array of bytes, srcData that stores the greyscale image.
File Excerpt: OtsuThresholder.java
// Calculate histogram
int ptr = 0;
while (ptr < srcData.length) {
int h = 0xFF & srcData[ptr];
histData[h] ++;
ptr ++;
}
float sum = 0;
for (int t=0 ; t<256 ; t++) sum += t * histData[t];
float sumB = 0;
int wB = 0;
int wF = 0;
float varMax = 0;
threshold = 0;
Examples
Here are a number of examples of the Otsu Method in use. It works well with images that have a bi-modal histogram (those with two
distinct regions).