A well-known and effective method for global thresholding is the Otsu method [1]. It is optimal in the sense that it maximizes the variance σ2B between classes. The algorithm is not iterative, but usually all threshold values are checked for optimality. We are looking for which threshold valueT is σ2B(T) maximum:

σ2B(T)=P1(T)(m1(T)mG))2+P2(T)(m2(T)mG))2

where

mG=L1i=0ipi

m1(T)=1P1(T)Ti=0ipi

m2(T)=1P2(T)L1i=T+1ipi

where

P1(T)=Ti=0pi

P2(T)=L1i=T+1pi

pi=niMN

where ni is the number of points with brightness level i, L is the number of brightness levels in the image M,N are the dimensions of the image. It turns out that the maximum always exists. If the maximum is reached for several T values, the average of these values is usually considered as the result.

The derivation of the mentioned algorithm and the discussion of its properties is given in [1]. 

Analogously, it is possible to derive a relation for K classes for which we are looking for K1 optimal thresholds T1,..TK1. Then we maximize:

σ2B=Kj=1Pj(mjmG))2

where

mj=1PjTji=Tj1+1ipi

Pj=Tji=Tj1+1pi

pi=niMN

where ni is the number of points with brightness level i, L is the number of brightness levels in the image, M,N are the dimensions of the image and T0=1,TK=L1

In the MATLAB environment, Otsu thresholding is implemented using the function graythresh (argument is an image) and otsuthresh (argument is the number of points ni with brightness level i) - for two classes and multithresh - for multiple classes.

An example of the use of Otsu thresholding is shown in Fig. 1. The task is to find the optimal threshold between two classes. We see how the presence of stronger noise can make it difficult to determine the threshold.

Fig. 1 Example of Otsu thresholding with a noisy input signal. In the upper row there is a weaker noisy signal, in the lower

Fig. 1 Example of Otsu thresholding with a noisy input signal. In the upper row there is a weaker noisy signal, in the lower row it is stronger

References

[1] Gonzalez, R., C., Woods, E., W., Digital Image Processing, Global Edition, 4th edition, Pearson  2018, ISBN 10: 1-292-22304-9


Appendix

The source code of the program that created Fig. 1

clear all; close all; clc;
N=256
mtx=uint8(128*ones(N,N));
imshow(mtx,[0,255]);
h = drawcircle('Center',[N/2 N/2],"Radius",N/3);
mask = createMask(h);
mtx(mask>0)=128+64;

fig=figure
subplot(2,3,1)
myvar=0.001
mtxn = imnoise(mtx,'gaussian',0,myvar);
imshow(mtxn,[0,255]);
title(sprintf("original + g. noise(var=%.3f)",myvar))

subplot(2,3,2)
imhist(mtxn);
hold on
[T,EM] = graythresh(mtxn)
myT=T*255;
myYlim=ylim;
plot([myT myT],[myYlim(1) myYlim(2)],"red","LineWidth",3)
text(myT,1000,sprintf("T_{Otsu}=%.0d\\rightarrow",myT),...
    'HorizontalAlignment','right',"FontSize",12,"Color","red")
title("histogram")


subplot(2,3,3)
BW = imbinarize(mtxn,T);
imshow(BW);
title("binarised result")

subplot(2,3,4)
myvar=0.2
mtxn = imnoise(mtx,'gaussian',0,myvar);
imshow(mtxn,[0,255]);
title(sprintf("original + g. noise(var=%.3f)",myvar))

subplot(2,3,5)
imhist(mtxn);
hold on
[T,EM] = graythresh(mtxn)
myT=T*255;
myYlim=ylim;
plot([myT myT],[myYlim(1) myYlim(2)],"red","LineWidth",3)
text(myT,700,sprintf("T_{Otsu}=%i\\rightarrow",myT),...
    'HorizontalAlignment','right',"FontSize",12,"Color","red")
title("histogram")


subplot(2,3,6)
BW = imbinarize(mtxn,T);
imshow(BW);
title("binarised result")

fig.PaperUnits = 'inches';
fig.PaperPosition = [0 0 10 6];
print(fig,"segmOtsuNoise.png",'-dpng');


 


The PDF version of this text is available here: segmentation_otsu_eng.pdf