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

Multilevel thresholding is an extension of Otsu's method of thresholding, which basically works for an arbitrary number of thresholds.

Filter by Category

- C# Tutorial(85)
- C# Image Processing(69)
- Morphological Processes(20)
- Image Processing(16)
- Image Restoration and Reconstruction(16)
- Image Segmentation(13)
- C# Data Structures And Algorithms(11)
- Frequency Domain Filtering(8)
- Color Image Processing(8)
- Image Noise(6)
- Grayscale Morphology(5)
- Thresholding(4)
- Sorting Algorithms(4)
- Mean Filters(4)
- Order-Statistic Filters(4)
- Morphological Reconstruction(3)
- Edge Detection(3)
- Simple Lists(2)
- Linked Lists(2)
- 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)
- C# Arrays(1)
- C# Basics(1)
- Sorted Lists(1)
- Stacks(1)
- Queues(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 Multilevel Thresholding Algorithm With C#

###
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#

Thresholding

Multilevel thresholding is an extension of Otsu's method of thresholding, which basically works for an arbitrary number of thresholds.

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.

How To Make Multilevel Thresholding...

Multilevel thresholding is an extension to Otsu thresholding method, where we search for multiple thresholding intensities. We also mentioned in another post that Otsu’s method searches for these intensities by maximizing between-class variance.

However, because we’re dealing with multiple thresholds , we’ll need to use a different formula for computing between-class variance. The reason for this is, because we need to take into account contribution from all thresholds together.

In case you’re familiar with other segmentation processes we’ve covered on this blog, you might know already that we used an example of hysteresis thresholding. This type of thresholding uses two thresholds. But we’ve yet to use Otsu’s method to find multiple, so this is what we’re going to do here.

We can use Otsu’s method to find an arbitrary number of thresholds, but the process itself starts to lose meaning as we increase this number above 2 or 3. Therefore, I’m going to demonstrate the process for finding only two thresholds.

Furthermore, we use multilevel thresholding only when we can effectively solve a problem with it. Usually, for problems, that require of us to use more than two thresholds, we use other parameters as well. In other words, we use other descriptors such as color.

There’s a recursive structure to this process and the number of recursions depend on the number of thresholds. I’m going to describe this process for finding two thresholds, which we also call hysteresis thresholding.

Firstly, we need to select the first threshold intensity. Secondly, we iterate through every possible intenisty that is larger than first threshold. As we iterate we compute which combination of the two thresholds yields the largest between-class variance.

When we iterate through all intensities for second threshold, we move on with the first threshold and repeat this process. By iterating both threshold intensites, we’re going to compute between-class variance for all possible combinations for two thresholds.

We use the following formula for each combination. First one is the between-class variance formula for all thresholds. And other two are cumulative sum and mean for each group of pixels.

The following code demonstrates the process I described above.

```
public static Bitmap HysteresisThreshold(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 normalized histogram`

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

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

` {`

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

` }`

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

` //Get global mean`

` double mg = 0;`

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

` {`

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

` }`

` int[] thresholds = new int[2];`

` double bcv = 0;`

` for (int i = 1; i < 254; i++)`

` {`

` double cs1 = 0;`

` double m1 = 0;`

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

` {`

` cs1 += histogram[j];`

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

` }`

` m1 /= cs1;`

` for (int j = i + 1; j < 253; j++)`

` {`

` double cs2 = 0;`

` double m2 = 0;`

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

` {`

` cs2 += histogram[k];`

` m2 += k * histogram[k];`

` }`

` m2 /= cs2;`

` double new_bcv = cs1 * Math.Pow(m1 - mg, 2) + cs2 * Math.Pow(m2 - mg, 2);`

` if (new_bcv > bcv)`

` {`

` bcv = new_bcv;`

` thresholds[0] = i;`

` thresholds[1] = j;`

` }`

` }`

` }`

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

` {`

` if (buffer[i] < thresholds[0])`

` {`

` result[i] = 0;`

` }`

` else if (buffer[i] >= thresholds[0] && buffer[i] < thresholds[1])`

` {`

` result[i] = 128;`

` }`

` else if (buffer[i] > thresholds[1])`

` {`

` result[i] = 255;`

` }`

` }`

` 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 giving you a better understanding on how multilevel thresholding works.

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

## Comments