最大類間方差法是由日本學者大津(Nobuyuki Otsu)於1979年提出的,是一種自適應的閾值確定的方法,又叫大津法,簡稱OTSU。它是按圖像的灰度特性,將圖像分成背景和目標2部分。背景和目標之間的類間方差越大,說明構成圖像的2部分的差別越大,當部分目標錯分為背景或部分背景錯分為目標都會導致2部分差別變小。因此,使類間方差最大的分割意味着錯分概率最小。對於圖像I(x,y),前景(即目標)和背景的分割閾值記作Th,屬於前景的像素點數占整幅圖像的比例記為w1,其平均灰度G1;背景像素點數占整幅圖像的比例為w2,其平均灰度為G2。圖像的總平均灰度記為G_Ave,類間方差記為 g。
假設圖像的背景較暗,並且圖像的大小為MXN,圖像中像素的灰度值小於閾值的像素個數記作N1,像素灰度大於閾值的像素個數記作N2,則有:
采用遍歷的方法得到使類間方差最大的閾值,即為所求。
代碼如下:
(C文件)
1 #include <stdio.h> 2 #include <math.h> 3 #include "myOtsu.h" 4 typedef unsigned char uchar; 5 int myOtsu(const IplImage *frame) //大津法求閾值 6 { 7 #define GrayScale 256 //frame灰度級 8 int width = frame->width; 9 int height = frame->height; 10 int pixelCount[GrayScale]={0}; 11 float pixelPro[GrayScale]={0}; 12 int i, j, pixelSum = width * height, threshold = 0; 13 float w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0; 14 uchar* data = (uchar*)frame->imageData; 15 16 //統計每個灰度級中像素的個數 17 for(i = 0; i < height; i++) 18 { 19 for(j = 0;j < width;j++) 20 { 21 pixelCount[(int)data[i * width + j]]++; 22 } 23 } 24 25 //計算每個灰度級的像素數目占整幅圖像的比例 26 for(i = 0; i < GrayScale; i++) 27 { 28 pixelPro[i] = (float)pixelCount[i] / pixelSum; 29 } 30 31 for(i = 0; i < GrayScale; i++)//遍歷所有從0到255灰度級的閾值分割條件,測試哪一個的類間方差最大 32 { 33 w0 = w1 = u0tmp = u1tmp = u0 = u1 = deltaTmp = 0; 34 for(j = 0; j < GrayScale; j++) 35 { 36 if(j <= i) //背景部分 37 { 38 w0 += pixelPro[j]; 39 u0tmp += j * pixelPro[j]; 40 } 41 else //前景部分 42 { 43 w1 += pixelPro[j]; 44 u1tmp += j * pixelPro[j]; 45 } 46 } 47 u0 = u0tmp / w0; 48 u1 = u1tmp / w1; 49 deltaTmp = (float)(w0 *w1* pow((u0 - u1), 2)) ; 50 if(deltaTmp > deltaMax) 51 { 52 deltaMax = deltaTmp; 53 threshold = i; 54 } 55 } 56 return threshold; 57 }
(H文件)
1 #ifndef MYOTSU_H_ 2 #define MYOTSU_H_ 3 typedef struct { 4 int width; 5 int height; 6 unsigned char imageData; 7 }IplImage; 8 extern int myOtsu(const IplImage *frame); 9 #endif /*MYOTSU_H_*/
大家轉載請注明出處!謝謝!
在這里要感謝GISPALAB實驗室的各位老師和學長學姐的幫助!謝謝~