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\n ", 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'.\n ");
  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'\n ", 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值