​第八篇 自动阈值----OTSU 大津法

时间:2024-05-21 07:10:59

OTSU法,专业术语叫最大类间方差法,又叫大津法,这个算法是由一个日本人,叫大津展之(Nobuyuki Otsu)的提出来的。嗯,网上对于这个算法的文章很多,大多从数学方面,公式方面来讲解的。

不过我想用自己的方式来讲解一下。首先这个算法是用于灰度图像的阈值的自动计算法。主要方法是从0-255,搜索每一个像素,假设搜索变量为X,则0-X之间为前景,x-255之间背景。这个好理解。不过在这之前,先要求出直方图,即所有像素在0-255之间的每个灰度值的像素总数。

先讲几个概念,

1. 平均灰度。 平均灰度,就是把所有像素的值全部相加除以像素总数。

(1) 像素总素为图像的长乘宽。

(2) 灰度总值则是每一个像素的灰度值累加。

2. 前景平均灰度。很好理解,即,0-X之间,每一个灰度值的直方图值相乘后累加,再除以直方图值的和。

3. 背景平均灰度。和前景一样。

我举一个简化版的例子。总共五个灰度值:1,2,3,4,5。每一个灰度的总数统计为,2,3,1,3,2。这么写 1(2),2(3),3(1),4(3),5(2);

平均灰度就是:(1*2+2*3+3+4*3+5*2) /(2+3+1+3+2)  前面是总灰度值,后面是总像素值。设3同灰度阈值。

则前景平均灰度为:(1*2+2*3+3) / (2+3+1);

 前面则是前景灰度值的总数,后者则是像素个数,背景也是同理。

最后求最大类间方差:

(前景平均灰度-总平均灰度)的平方 *前景百分比+(背景平均灰度-总平均灰度)的平方 *背景景百分比。取最大值。

贴一张网上的算法图:

​第八篇 自动阈值----OTSU 大津法

tnum = image->width*image->height;//像素总数

for (i = 0; i < height; i++)

{

for (j = 0; j < width; j++)

{

hist[cptr[i*step + j]]++;//直方图

totalgray += cptr[i*step + j];//灰度统计,也可以用直方图来求。

}

}

avg = totalgray / tnum;//总平均灰度。

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

{

fSum0 = 0;

bSum1 = 0;

fnum += hist[i];

bnum = tnum - fnum;

if (0 == bnum)

{

break;

}

if (0 == fnum)

{

continue;

}

fp = fnum / tnum;

bp = 1 - fp;

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

{

fSum0 += j*hist[j];

}

favg = fSum0 / fnum;

for (j = i + 1; j < 256; j++)

{

bSum1 += j*hist[j];

}

bavg = bSum1 / bnum;

g = fp*(favg - avg)*(favg - avg) + bp*(bavg - avg)*(bavg - avg);

if (tmpg < g)

{

tmpg = g;

T = i;

}

以lena为例,计算得出123为自动阈值。

结果二值化后的图像为:

​第八篇 自动阈值----OTSU 大津法

    这个的确是最优效果阈值。

 源代码链接:  https://download.****.net/download/finger157959/12528142

​第八篇 自动阈值----OTSU 大津法