二值化图像

 

    阈值T:按照个人理解就是通常咱们用摄像头拍摄照片或者视频咱们一般把拍摄的照片或者视html

      频转化为RGB565图像,而后经过RGB的转化算出像素经过设置一个阈值像素,大于算法

      这个值咱们把它设置为白色,小于这个值得咱们把它设置为黑色。这个就是图像二值ide

      化。post

  图像二值化的原理spa

         图像的二值化处理就是将图像上的点的灰度置为0或255,也就是将整个图像视频

  呈现出明显的黑白效果。即将256个亮度等级的灰度图像经过适当的阈值选取而获htm

  得仍然能够反映图像总体和局部特征的二值化图像。在数字图像处理中,二值图像blog

  占有很是重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的get

  系统是不少的,要进行二值图像的处理与分析,首先要把灰度图像二值化,获得二it

  值化图像,这样子有利于在对图像作进一步处理时,图像的集合性质只与像素值为

  0或255的点的位置有关,再也不涉及像素的多级值,使处理变得简单,并且数据的

  处理和压缩量小。为了获得理想的二值图像,通常采用封闭、连通的边界定义不交

  叠的区域。全部灰度大于或等于阈值的像素被断定为属于特定物体,其灰度值为255

  表示,则这些像素点被排除在物体区域之外,灰度值为0,表示背景或者例外的物体

  区域。若是某特定物体在内部有均匀一致的灰度值,而且其处在一个具备其余等级灰

  度值的均匀背景下,使用阈值法就能够获得比较的分割效果。若是物体同背景的差异

  表现不在灰度值上(好比纹理不一样),以将这个差异特征转换为灰度的差异,而后利用

  阈值选取技术来分割该图像。动态调节阈值实现图像的二值化可动态观察其分割图像

  的具体结果。

 

  图像二值化的方法

  (1)全局二值化

  一幅图像包括目标物体背景还有噪声,要想从多值的数字图像中直接提取出目标物体,

  最经常使用的方法就是设定一个全局的阈值T,用T将图像的数据分红两部

  全局二值化全局二值化

  分:大于T的像素群和小于T的像素群。将大于T的像素群的像素值设定为白色(或者

  黑色),小于T的像素群的像素值设定为黑色(或者白色)。

  (2)局部二值化

  全局二值化,在表现图像细节方面存在很大缺陷。为了弥补这个缺陷,出现了局部

  二值化方法。

  局部二值化的方法就是按照必定的规则将整幅图像划分为N个窗口,对这N个窗口中

  的每个窗口再按照一个统一的阈值T将该窗口内的像素划分为两部分,进行二值

  化处理。

  (3)局部自适应二值化

  局部二值化也有一个缺陷。这个缺陷存在于那个统一阈值的选定。这个阈值是没有 

  通过合理的运算得来,通常是取该窗口的平局值。这就致使在每个窗口内仍然出 

  现的是全局二值化的缺陷。为了解决这个问题,就出现了局部自适应二值化方法。

  局部自适应二值化,该方法就是在局部二值化的基础之上,将阈值的设定更加合理

  化。该方法的阈值是经过对该窗口像素的平均值E,像素之间的差平方P,像素之间 

  的均方根值Q等各类局部特征,设定一个参数方程进行阈值的计算,例如:T=a*E

  +b*P+c*Q,其中a,b,c是自由参数。这样得出来的二值化图像就更能表现出二值化

  图像中的细节。

 

 

  此篇介绍两种全局阈值方法,下篇介绍自适应方法。

  1:经典算法OTSU

  OTSU的中心思想是阈值T应使目标与背景两类的类间方差最大。

  //用类间方差最大思想计算阈值

  int Threshold(int *hist)  //compute the threshold
  {
     float u0, u1;
     float w0, w1;
     int count0;
     int t, maxT;
     float devi, maxDevi = 0; //方差及最大方差
     int i;
     int sum = 0;
     for (i = 0; i < 256; i++)
     {
        sum = sum + hist[i];
     }
     for (t = 0; t < 255; t++)
     {
        u0 = 0; count0 = 0;
        //阈值为t时,c0组的均值及产生的几率
        for (i = 0; i <= t; i++)
        {
           u0 += i * hist[i]; count0 += hist[i]; 
        }
        u0 = u0 / count0; w0 = (float)count0/sum;
        //阈值为t时,c1组的均值及产生的几率
        u1 = 0;
        for (i = t + 1; i < 256; i++)
        {
           u1 += i * hist[i];  
        }
        u1 = u1 / (sum - count0); w1 = 1 - w0;

        //两类间方差
        devi = w0 * w1 * (u1 - u0) * (u1 - u0);
        //记录最大的方差及最佳位置
        if (devi > maxDevi)
        {
           maxDevi = devi;
           maxT = t;
        }
     }
     return maxT;
  }

  //二值化处理
  void OTSU(IplImage *src, IplImage *dst)
  {
     int i = 0, j = 0;
     int wide = src->widthStep;
     int high = src->height;
     int hist[256] = {0};
     int t;
     unsigned char *p, *q;
     for (j = 0; j < high; j ++)
     {
        p = (unsigned char *)(src->imageData + j * wide);
        for (i = 0; i < wide; i++)
        {
           hist[p[i]]++;   //统计直方图
        }
     }
     t = Threshold(hist);

     for (j = 0; j < high; j ++)
     {
        q = (unsigned char *)(dst->imageData + j * wide);
        p = (unsigned char *)(src->imageData + j * wide);
        for (i = 0; i < wide; i++)
        {
           q[i] = p[i] >= t ? 255 : 0;
        }
     }
  }

  2:另一个Kittler算法,是一种快速的全局阈值法。它的效果不比OTSU差多少,但速度快好多倍,若是能够应用在图像质量不错的环境。

  它的中心思想是,计算整幅图像的梯度灰度的平均值,以此平均值作为阈值。

  //kittler算法
    for (i=1;i<high-1;i++)              
   {
      plineadd=src->imageData+i*wide;
      pNextLine=src->imageData+(i+1)*wide;
      pPreLine=src->imageData+(i-1)*wide; 
      for(j=1;j<wide-1;j++)
      {

      //求水平或垂直方向的最大梯度
         Grads=MAX(abs((uchar)pPreLine[j]-(uchar)pNextLine[j]),abs((uchar)plineadd[j-1]-(uchar)plineadd[j+1])); //max(xGrads,yGrads)
         sumGrads += Grads;

      //梯度与当前点灰度的积
         sumGrayGrads += Grads*((uchar)plineadd[j]);   
      }
   }
   threshold=sumGrayGrads/sumGrads;
  // printf("%d\n",threshold);
   for(i=0;i<high;i++)
   { 
      plineadd=src->imageData+i*wide;
      pTempLine=kittler->imageData+i*wide;
      for(j=0;j<wide;j++)
      {
         pTempLine[j]=(uchar)plineadd[j]>threshold?255:0;
      }
   }

相关文章
相关标签/搜索