自適應閾值分割(最大類間方差法、大津法、OTSU)
阿新 • • 發佈:2018-12-21
最大類間方差法是由日本學者大津(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; }