cv 灰阶分割

灰阶分割又称阈值操作, 是灰阶图像到二值图像的转换,区分对象和背景的操作,典型应用扫描文本图像的文本识别。是很多操作的基础,如细化、矢量化、形态学操作等。

阈值的选择是核心内容,灰阶直方图是根本工具。

1. 使用边缘像素。 边缘像素是指对象和背景之间的像素,由于采样问题,背景像素包含对象和背景像素,因此边缘像素的直方图会比较规整等反应对象和背景的分布。

思想:用拉普拉斯算子卷积图像,类似相当于提取边缘 。拉普拉斯算子计算后的图像像素加大的15%建立直方图,由此直方图选择阈值。

1 void thr_lap (IMAGE im)
  2 {
  3     float ** Lap;
  4     int i, j, t, v;
  5     unsigned char *p;
  6 
  7 /* Compute the Laplacian of 'im' */
  8     Lap = f2d (im->info->nr, im->info->nc);
  9     Laplacian (im, Lap);
 10 
 11 /* Find the high 85% of the Laplacian values */
 12     fhist (Lap, hist, im->info->nr, im->info->nc);
 13     hi_pct (hist, 2048, (long)im->info->nr*(long)im->info->nc, PCT, &v);
 14 
 15 /* Construct histogram of the grey levels of hi Laplacian pixels */
 16     peaks (im, hist, Lap, v, &t);
 17 
 18     fprintf (stderr, "Threshold is %d ", t);
 19 
 20 /* Threshold */
 21     for (i=0; i<im->info->nr; i++)
 22       for (j=0; j<im->info->nc; j++)
 23       if (im->data[i][j] < t)
 24         im->data[i][j] = 0;
 25       else
 26         im->data[i][j] = 255;
 27 }
 28 
 29 /*      Return the level marking the high 85% of pixels */
 30 void hi_pct (int *hist, int NH, long N, float pct, int *val)
 31 {
 32     int i,j=0, m;
 33 
 34     *val = -1;
 35     m = (pct/100.0) * N;
 36     for (i=0; i<NH; i++)
 37     {
 38       j += hist[i];
 39       if (j>=m)
 40       {
 41         *val = i;
 42         break;
 43       }
 44     }
 45     if (*val < 0) printf ("BAD HISTOGRAM in 'hi_pct'. ");
 46 }
 47 
 48 /*      Construct a histogram of a float matrix         */
 49 void fhist (float **data, int *hist, int nr, int nc)
 50 {
 51     int i,j;
 52 
 53     for (i=0; i<2048; i++) hist[i] = 0;
 54     for (i=0; i<nr; i++)
 55       for (j=0; j<nc; j++)
 56         hist[(int)(data[i][j])] += 1;
 57 }
 58 
 59 void Laplacian (IMAGE input, float **output)
 60 {
 61     int i,j;
 62 
 63     for (i=1; i<input->info->nr-1; i++)
 64       for (j=1; j<input->info->nc-1; j++)
 65         output[i][j] = pix_lap (input, i, j);
 66 }
 67 
 68 float pix_lap (IMAGE im, int r, int c)
 69 {
 70     int k=0, i,j;
 71 
 72 /*
 73     k = (int)im->data[r-1][c]+(int)im->data[r+1][c] +
 74         (int)im->data[r][c-1]+(int)im->data[r][c-1];
 75     k = k-(int)im->data[r][c]*4;
 76 
*/
 77     for (i= -1; i<=1; i++)
 78       for (j= -1; j<=1; j++)
 79         if (i!=0 || j!=0)
 80         k += im->data[i+r][j+c];
 81     k = k - 8*(int)im->data[r][c];
 82     if (k<=0return 0.0;
 83     return (float)k/8.0;
 84 }
 85 
 86 void peaks (IMAGE im, int *hist, float **lap, int lval, int *t)
 87 {
 88     int N, i,j,k;
 89 
 90     for (i=0; i<256; i++) hist[i] = 0;
 91     *t = -1;
 92 
 93 /* Find the histogram */
 94     N = im->info->nc*im->info->nr;
 95 
 96     for (i=0; i<im->info->nr; i++)
 97       for (j=0; j<im->info->nc; j++)
 98         if (lap[i][j] >= lval)
 99           hist[im->data[i][j]] += 1;
100 
101 /* Find the first peak */
102     j = 0;
103     for (i=0; i<256; i++)
104       if (hist[i] > hist[j]) j = i;
105 
106 /* Find the second peak */
107     k = 0;
108     for (i=0; i<256; i++)
109       if (i>0 && hist[i-1]<=hist[i] && i<255 && hist[i+1]<=hist[i])
110         if ((k-j)*(k-j)*hist[k] < (i-j)*(i-j)*hist[i]) k = i;
111 
112     *t = j;
113     if (j<k)
114     {
115       for (i=j; i<k; i++)
116         if (hist[i] < hist[*t]) *t = i;
117     } else {
118       for (i=k; i<j; i++)
119         if (hist[i] < hist[*t]) *t = i;
120     }
121 }
122 ……
123 int main (int argc, char** argv )
124 {
125     IMAGE x;
126     char name[128];
127     float max1=0.0f, max2=0.0f;
128 
129     // Try to read an image
130     printf ("Enter path to the image file to be processed: ");
131     scanf ("%s", name);
132     printf ("Opening file '%s' ", name);
133     x = get_image(name);
134     
135     if(x)
136     {
137         display_image (x);
138         thr_lap (x);
139         display_image (x);
140         save_image (x, "thrlap.jpg");
141     }
142     return 0;
143 }

 2.迭代选择法。以灰阶均值为初值划分两类灰阶,再分别求每一类的均值t0,t1,由这两个均值再求平均得一个新的阈值,又重新划分两类灰阶,重复这个步骤,知道阈值没有变化为止。

 3.最小化组间方差和总体方差的比之。

4. 熵entropy,系统的丰富度。熵越小,系统约有组织性;vice versa.最大化H=Hblack+Hwhite的t就是分割阈值。

……

5.移动平均法。 最后n个像素的平均值。

       0, gi<sum/N*85%

V={

       255, 其他

 1 void thrdd (IMAGE im)
 2 {
 3     int NC, row, col, inc;
 4     float mean, s, sum;
 5     unsigned char *p;
 6     long N, i;
 7 
 8     N = (long)im->info->nc * (long)im->info->nr;
 9     NC = im->info->nc;
10     s = (int)(float)(NC/Navg);
11     sum = 127*s;
12 
13     row = col = 0;
14     p = &(im->data[0][0]);
15     inc = 1;
16 
17     for (i=0; i<N-1; i++)
18     {
19       if (col >= NC)
20       {
21         col = NC-1; row++;
22         p = &(im->data[row][col]);
23         inc = -1;
24       } else if (col < 0)
25       {
26         col = 0;
27         row++;
28         p = &(im->data[row][col]);
29         inc = 1;
30       }
31 
32 /* Estimate the mean of the last NC/8 pixels. */
33       sum = sum - sum/s + *p;
34       mean = sum/s;
35       if (*p < mean*(100-pct)/100.0) *p = 0;
36         else *p = 255;
37       p += inc;
38       col += inc;
39     }

40 } 

 6.聚类

 7.松弛法

原文地址:https://www.cnblogs.com/Lemon-Li/p/3388968.html