大津法图像分割

  大津法是一种基于类间方差最大的图像分割(二值化)方法,在实际应用中被广泛使用。大津法属于阈值分割方法,它的阈值是全局的、自适应的。它的基本思想是这样的:

  设图像总像素数为 N ,灰度范围为 [0, L-1] 。灰度级为 i 的像素出现的频数为 n, i=0,1,...,L-1 。图像中的像素点可以用阈值T分割成两类,即[0, T]∈C1和[T+1, L-1]∈C2。设C1中的像素数为N1,C2中的像素数为N2(N2=N-N1),则C1和C2的均值分别为:

  

  令

  

  则整图的均值为:

  

  定义类间方差为: 

  

  遍历T的可能取值,即1 ~ L-2 ,使类间方差最大的阈值T即为大津法确定的最佳阈值。

 1 /////////////////////////////////////////////////////////////////
 2 //    功能:大津法自适应阈值(针对感兴趣区域)
 3 //    参数:
 4 //        pGry     - 灰度图像指针
 5 //        lineByte - 灰度图像的每行字节数
 6 //        roi      - 感兴趣区域(左开右闭、上开下闭区间)
 7 //    返回值:
 8 //        T        - 大津阈值
 9 ////////////////////////////////////////////////////////////////
10 
11 int Otsu(unsigned char *pGry, int lineByte, CRect roi)
12 {
13     int xMin = roi.left;
14     int xMax = roi.right;
15     int yMin = roi.top;
16     int yMax = roi.bottom;
17     
18     int i,j;
19     int r;
20     vector<int> hist(256, 0); //灰度直方图
21     for (i=yMin; i<yMax; i++)
22     {
23         r = i*lineByte;
24         for (j=xMin; j<xMax; j++)
25         {
26             hist[pGry[r+j]]++;
27         }
28     }
29 
30     int T; //大津阈值
31     int N = (xMax-xMin) * (yMax-yMin); //总像素数目
32     int N1,N2;     //两类别的像素数目
33     double u1,u2;  //两类别的像素均值
34 
35     double devi, maxDevi = 0;
36     for (i=1; i<255; i++)   //阈值的可能取值
37     {
38         N1 = 0;
39         u1 = u2 = 0;
40         for (j=0; j<i; j++)
41         {
42             u1 += j*hist[j];
43             N1 += hist[j];
44         }
45         u1 = N1>0 ? u1/N1 : 0;
46 
47         for (j=i; j<256; j++)
48         {
49             u2 += j*hist[j];
50         }
51         N2 = N - N1;
52         u2 = N2>0 ? u2/N2 : 0;
53 
54         devi = N1 * N2 * (u1-u2) * (u1-u2); //类间方差
55         if (devi >= maxDevi)
56         {
57             maxDevi = devi;
58             T = i;
59         }
60     }
61 
62     return T;
63 }

参考:[1] 姚敏. 数字图像处理(第二版)

   [2] 谢凤英. VC++数字图像处理(第二版)

 

posted on 2013-01-24 19:38  文森vincent  阅读(1407)  评论(0编辑  收藏  举报

导航