Multilevel thresholding for image segmentation

Sujoy Kumar Goswami
Analytics Vidhya
Published in
2 min readSep 7, 2021

Thresholding techniques can be divided into bi-level and multi-level category, depending on number of image segments. In bi-level thresholding, image is segmented into two different regions. The pixels with gray values greater than a certain value T are classified as object pixels, and the others with gray values lesser than T are classified as background pixels.

Multilevel thresholding is a process that segments a gray level image into several distinct regions. This technique determines more than one threshold for the given image and segments the image into certain brightness regions, which correspond to one background and several objects. The method works very well for objects with colored or complex backgrounds, on which bi-level thresholding fails to produce satisfactory results.

The full paper can be found here. Here the authors used mean and the variance of the image to find optimum thresholds for segmenting the image into multiple levels. The algorithm is applied recursively on sub-ranges computed from the previous step so as to find a threshold and a new sub-range for the next step.

The Python (>3.0) code for the above approach for n Thresholds is given below:

import cv2
import numpy as np
import math

img = cv2.imread('path-to-image')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
a = 0
b = 255
n = 6 # number of thresholds (better choose even value)
k = 0.7 # free variable to take any positive value
T = [] # list which will contain 'n' thresholds

def multiThresh(img, a, b):
if a>b:
s=-1
m=-1
return m,s

img = np.array(img)
t1 = (img>=a)
t2 = (img<=b)
X = np.multiply(t1,t2)
Y = np.multiply(img,X)
s = np.sum(X)
m = np.sum(Y)/s
return m,s

for i in range(int(n/2-1)):
img = np.array(img)
t1 = (img>=a)
t2 = (img<=b)
X = np.multiply(t1,t2)
Y = np.multiply(img,X)
mu = np.sum(Y)/np.sum(X)

Z = Y - mu
Z = np.multiply(Z,X)
W = np.multiply(Z,Z)
sigma = math.sqrt(np.sum(W)/np.sum(X))

T1 = mu - k*sigma
T2 = mu + k*sigma

x, y = multiThresh(img, a, T1)
w, z = multiThresh(img, T2, b)

T.append(x)
T.append(w)

a = T1+1
b = T2-1
k = k*(i+1)

T1 = mu
T2 = mu+1
x, y = multiThresh(img, a, T1)
w, z = multiThresh(img, T2, b)
T.append(x)
T.append(w)
T.sort()
print(T)

You can find another approach, Multi-Otsu Thresholding, by scikit-image library. Several other approaches are there. Thank you !!!

--

--