### How To Make Otsu Thresholding Algorithm With C#

Otsu thresholding is a global thresholding method, with which we find optimal threshold intensity to ensure the maximum separability.

Filter by Category

- C# Tutorial(84)
- C# Image Processing(69)
- Morphological Processes(20)
- Image Processing(16)
- Image Restoration and Reconstruction(16)
- Image Segmentation(13)
- Frequency Domain Filtering(8)
- Color Image Processing(8)
- Image Noise(6)
- Grayscale Morphology(5)
- Thresholding(4)
- Mean Filters(4)
- Order-Statistic Filters(4)
- Morphological Reconstruction(3)
- Edge Detection(3)
- Adaptive Filters(2)
- RGB to HSI Color Model(2)
- Tone and Color Corrections(2)
- Landing Pages(1)
- Point Detection(1)
- Line Detection(1)
- Social Games(1)
- Region Growing Segmentation(1)
- Region Splitting And Merging(1)
- Region Segmentation With K Means Clustering(1)
- Region Segmentation Using Superpixels(1)
- Bandreject Filters(1)
- Bandpass filters(1)
- Notch Filters(1)
- Intensity Slicing and Color Coding(1)
- Color Slicing(1)
- Histogram Processing Color Images(1)
- Color Image Smoothing And Sharpening(1)
- Using Color In Image Segmentation(1)
- Digital Image Watermarking(1)

Back to Latest Articles
###
How To Make Otsu Thresholding Algorithm With C#

###
How To Make A Basic Global Thresholding Algorithm – C#

###
How To Make Canny Edge Detection Algorithm With C#

###
How To Make Marr Hildreth Edge Detection Algorithm In C#

###
How To Make Basic Edge Detection Algorithm With C#

###
How To Make Line Detection Algorithm With C#

###
How To Make Point Detection Algorithm With C#

###
How To Make Texture Segmentation Work With C#

###
How To Make Granulometry Work With C#

###
How To Make Top Hat Transformation Work With C#

Thresholding

Otsu thresholding is a global thresholding method, with which we find optimal threshold intensity to ensure the maximum separability.

Thresholding

This tutorial demonstrates how to get optimal threshold value for basic global thresholding operation for segmentation in image processing.

Edge Detection

Canny edge detection process is an edge detection based segmentation operation in image processing for accurately extracting edges.

Edge Detection

Marr hildreth edge detection process is one of the earliest sophisticated edge detection based segmentation operations in image processing.

Edge Detection

Edge detection is a segmentation technique in image processing for extracting object boundaries based on abrupt intensity changes.

Line Detection

Line detection is a segmentation technique in image processing, with which we can extract thin lines with respect to each filter kernel.

Point Detection

Point detection is a segmentation technique in image processing, we can use to get the position of point objects in the image.

Grayscale Morphology

Texture segmentation is a customizable morphological process, with which we can find boundaries between regions based on their texture content

Grayscale Morphology

Granulometry is a grayscale morphological operation in image processing for estimating distribution of different sized particles.

Grayscale Morphology

Top hat transformation is a grayscale morphological operation in image processing, we can use for extraction of certain objects in the image.

How To Make Otsu Thresholding Algorithm With...

Otsu thresholding is a slightly more complex operation for segmenting image pixels into two groups. Furthermore, its advantage is in finding the optimal threshold intensity.

In general, thresholding objective is to minimize average error when we’re assigning pixels into 2 or more groups. In our case, we’re dealing with global thresholding, so we’ll segment image into two groups or classes.

We’re going to use Bayesian decision function to find the optimal threshold. This simply implies that we’re going to use a separability function to measure which intensity yields the biggest separability. It also means, we’re going to do computation only on histogram values.

This function is based on probability density function of intensities for each group of pixels. Therefore, we’re going to normalize histogram values, so the sum of its values will be equal to 1. In other words, we’re going to divide each histogram value with the number of all pixels in the image.

As we mentioned above, we’re going to need a function for finding optimal threshold intensity. Therefore, we’re using Otsu’s method, which maximizes between-class variance.

*What is between-class variance?*

Between-class variance is a variable, which tells us how good is the separability between the two classes of pixels. However, it’s not a separability measure, it’s its parameter.

But we can still use it to find the optimal intensity. The reason for that is because the other parameter, global variance, is a constant. And the separability measure is just a ratio between the two, which yields a value between 0 and 1.

*What’s the process sequence?*

First of all, as we mentioned already, we need to get normalized histogram. Secondly, we need to get cumulative sums of each classes. In other words, we split the normalized histogram at the threshold and sum together each part separately.

Next step is to get the cumulative means, which are simply sums of products between each intensity and its probability. We’ll also need the global mean intensity value, which is just the average intensity on the entire image.

Next step is most important for this process, which is calculation of between-class variance. In order to find the optimal threshold, we need to check for all possible intensities and find which one yields the largest between-class vairance.

And finally once we have the optimal threshold intensity, we apply thresholding process as we did in other segmentation operations. Therefore, pixels that have larger intensity than threshold turn white and those that have lower or equal turn black.

```
public static Bitmap OtsuThresholding(this Bitmap image)
{
int w = image.Width;
int h = image.Height;
```` BitmapData image_data = image.LockBits(`

` new Rectangle(0, 0, w, h),`

` ImageLockMode.ReadOnly,`

` PixelFormat.Format24bppRgb);`

` int bytes = image_data.Stride * image_data.Height;`

` byte[] buffer = new byte[bytes];`

` byte[] result = new byte[bytes];`

` Marshal.Copy(image_data.Scan0, buffer, 0, bytes);`

` image.UnlockBits(image_data);`

` //Get histogram values`

` double[] histogram = new double[256];`

` for (int i = 0; i < bytes; i+=3)`

` {`

` histogram[buffer[i]]++;`

` }`

` //Normalize histogram`

` histogram = histogram.Select(x => (x / (w * h))).ToArray();`

` //Global mean`

` double mg = 0;`

` for (int i = 0; i < 255; i++)`

` {`

` mg += i * histogram[i];`

` }`

` //Get max between-class variance`

` double bcv = 0;`

` int threshold = 0;`

` for (int i = 0; i < 256; i++)`

` {`

` double cs = 0;`

` double m = 0;`

` for (int j = 0; j < i; j++)`

` {`

` cs += histogram[j];`

` m += j * histogram[j];`

` }`

` if (cs == 0)`

` {`

` continue;`

` }`

` double old_bcv = bcv;`

` bcv = Math.Max(bcv, Math.Pow(mg * cs - m, 2) / (cs * (1 - cs)));`

` if (bcv > old_bcv)`

` {`

` threshold = i;`

` }`

` }`

` for (int i = 0; i < bytes; i++)`

` {`

` result[i] = (byte)((buffer[i] > threshold) ? 255 : 0);`

` }`

` Bitmap res_img = new Bitmap(w, h);`

` BitmapData res_data = res_img.LockBits(`

` new Rectangle(0, 0, w, h),`

` ImageLockMode.WriteOnly,`

` PixelFormat.Format24bppRgb);`

` Marshal.Copy(result, 0, res_data.Scan0, bytes);`

` res_img.UnlockBits(res_data);`

` return res_img;`

` }`

I hope this tutorial was helpful in understanding in how Otsu thresholding works.

You can also **download the demo project** and try it out yourself.

## Comments