1. 程式人生 > >自適應閾值分割(最大類間方差法、大津法、OTSU)

自適應閾值分割(最大類間方差法、大津法、OTSU)

最大類間方差法是由日本學者大津(Nobuyuki Otsu)於1979年提出的,是一種自適應的閾值確定的方法,又叫大津法,簡稱OTSU。它是按影象的灰度特性,將影象分成背景和目標兩部分,或者說,是尋找一個閾值為K,將影象的顏色分為1,2.....K和K+1.....256兩部分。

如何確定這個閾值K?演算法分類的原理是讓背景和目標之間的類間方差最大,因為背景和目標之間的類間方差越大,說明構成影象的2部分的差別越大,錯分的可能性越小。下面進行公式推導:

首先是符號說明:對於影象I(x,y),前景(即目標)和背景的分割閾值記作T,屬於前景的畫素點數佔整幅影象的比例記為ω0,其平均灰度μ0;背景畫素點數佔整幅影象的比例為ω1

,其平均灰度為μ1。影象的總平均灰度記為μ,類間方差記為g。假設影象的背景較暗,並且影象的大小為M×N,影象中畫素的灰度值小於閾值T的畫素個數記作N0,畫素灰度大於閾值T的畫素個數記作N1

   

採用遍歷的方法得到尋找到類間方差最大值,對應的閾值,即為所求。

程式碼區:

int myOtsu(const IplImage *frame) //大津法求閾值
{
#define GrayScale 256    //frame灰度級
    int width = frame->width;
    int height = frame->height;
    int pixelCount[GrayScale]={0};
    float pixelPro[GrayScale]={0};
    int i, j, pixelSum = width * height, threshold = 0;
    uchar* data = (uchar*)frame->imageData;

    //統計每個灰度級中畫素的個數
    for(i = 0; i < height; i++)
    {
        for(j = 0;j < width;j++)
        {
            pixelCount[(int)data[i * width + j]]++;
        }
    }

    //計算每個灰度級的畫素數目佔整幅影象的比例
    for(i = 0; i < GrayScale; i++)
    {
        pixelPro[i] = (float)pixelCount[i] / pixelSum;
    }

    //遍歷灰度級[0,255],尋找合適的threshold
    float w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0;
    for(i = 0; i < GrayScale; i++)
    {
        w0 = w1 = u0tmp = u1tmp = u0 = u1 = deltaTmp = 0;
        for(j = 0; j < GrayScale; j++)
        {
            if(j <= i)   //背景部分
            {
                w0 += pixelPro[j];
                u0tmp += j * pixelPro[j];
            }
            else   //前景部分
            {
                w1 += pixelPro[j];
                u1tmp += j * pixelPro[j];
            }
        }
        u0 = u0tmp / w0;
        u1 = u1tmp / w1;
        deltaTmp = (float)(w0 *w1* pow((u0 - u1), 2)) ;
        if(deltaTmp > deltaMax)
        {
            deltaMax = deltaTmp;
            threshold = i;
        }
    }
    return threshold;
}