基于直方图的图像全局二值化算法原理、实现--OSTU大律法

来源:互联网 发布:vc串口编程 编辑:程序博客网 时间:2024/05/17 07:42

1、描述:

   主要是思想是取某个阈值,使得前景和背景两类的类间方差最大,matlab中的graythresh即是以该算法为原理执行的。

该算法是日本人Otsu提出的一种动态阈值分割算法。它的主要思想是按照灰度特性将图像划分为背景和目标2部分,划分依据为选取门限值,使得背景和目标之间的方差最大。(背景和目标之间的类间方差越大,说明这两部分的差别越大,当部分目标被错划分为背景或部分背景错划分为目标都会导致这两部分差别变小。因此,使用类间方差最大的分割意味着错分概率最小。)这是该方法的主要思路。其主要的实现原理为如下:

      1)建立图像灰度直方图(共有L个灰度级,每个出现概率为p)


      2)计算背景和目标的出现概率,计算方法如下:


      上式中假设t为所选定的阈值,A代表背景(灰度级为0~N),根据直方图中的元素可知,Pa为背景出现的概率,同理B为目标,Pb为目标出现的概率。

      3)计算A和B两个区域的类间方差如下:


        第一个表达式分别计算A和B区域的平均灰度值;

      第二个表达式计算灰度图像全局的灰度平均值;

      第三个表达式计算A、B两个区域的类间方差。

2、参考代码:

int GetOSTUThreshold(int* HistGram)
    {        int X, Y, Amount = 0;        int PixelBack = 0, PixelFore = 0, PixelIntegralBack = 0, PixelIntegralFore = 0, PixelIntegral = 0;        double OmegaBack, OmegaFore, MicroBack, MicroFore, SigmaB, Sigma;              // 类间方差;        int MinValue, MaxValue;        int Threshold = 0;        for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++) ;        for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--) ;        if (MaxValue == MinValue) return MaxValue;          // 图像中只有一个颜色                     if (MinValue + 1 == MaxValue) return MinValue;      // 图像中只有二个颜色        for (Y = MinValue; Y <= MaxValue; Y++) Amount += HistGram[Y];        //  像素总数        PixelIntegral = 0;        for (Y = MinValue; Y <= MaxValue; Y++) PixelIntegral += HistGram[Y] * Y;        SigmaB = -1;        for (Y = MinValue; Y < MaxValue; Y++)        {            PixelBack = PixelBack + HistGram[Y];            PixelFore = Amount - PixelBack;            OmegaBack = (double)PixelBack / Amount;            OmegaFore = (double)PixelFore / Amount;            PixelIntegralBack += HistGram[Y] * Y;            PixelIntegralFore = PixelIntegral - PixelIntegralBack;            MicroBack = (double)PixelIntegralBack / PixelBack;            MicroFore = (double)PixelIntegralFore / PixelFore;            Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore);            if (Sigma > SigmaB)            {                SigmaB = Sigma;                Threshold = Y;            }        }        return Threshold;    }
0 0
原创粉丝点击