otsu自动阈值对图像二值化程序

otsu算法网上都是,原理就不细说了,下面给出一个基于opencv的图像二值化算法。opencv2.0已经包含了这个算法,如果装opencv2.0的话就不用自己写了,cvThreshold的最后一个参数可以选择是否是用otsu自动阈值

frame为输入图像,dst为二值化后的图像

void otsuThreshold(IplImage *frame,IplImage* dst)
{
 int width = frame->width;
 int height = frame->height;
 
 int i, j, pixelSum = width * height, threshold = 0;
 int pixelCount[255]={0};
 float pixelPro[255]={0};
 //uchar* data = (uchar*)frame->imageData;
 
 for(i = 0; i < GrayScale; i++)
 {
  pixelCount[i] = 0;
  pixelPro[i] = 0;
 }
 int dd=0;
 //统计灰度级中每个像素在整幅图像中的个数
 for(j = 0; j < height; j++)
 {
  for(i = 0;i < width;i++)
  {
   //pixelCount[(int)data[i * width + j]]++;
    dd=S(frame,i,j);
   pixelCount[S(frame,i,j)]++;
   if(dd!=255)
   {
    int kk=12;
   }
  }
 }
 
 //计算每个像素在整幅图像中的比例
 for(i = 0; i < GrayScale; i++)
 {
  pixelPro[i] = (float)pixelCount[i] / pixelSum;
 }
 
 //遍历灰度级[0,255]
 float w0, w1, u0tmp, u1tmp, u0, u1, u,
  deltaTmp, deltaMax = 0;
 for(i = 0; i < GrayScale; i++)
 {
  w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
  for(j = 0; j < GrayScale; j++)
  {
   if(j <= i)   //背景部分
   {
    w0 += pixelPro[j];
    u0tmp += j * pixelPro[j];
   }
   else   //前景部分
   {
    w1 += pixelPro[j];
    u1tmp += j * pixelPro[j];
   }
  }
  u0 = u0tmp / w0;
  u1 = u1tmp / w1;
  u = u0tmp + u1tmp;
  deltaTmp =
   w0 * (float)pow((u0 - u), 2) + w1 * (float)pow((u1 - u), 2);
  if(deltaTmp > deltaMax)
  {
   deltaMax = deltaTmp;
   threshold = i;
  }
 }
 cvThreshold(frame,dst,threshold,255,CV_THRESH_BINARY);
}

你可能感兴趣的:(otsu自动阈值对图像二值化程序)