OTSU算法对图像二值化


版权声明:本文为博主原创文章,未经博主允许不得转载。
       转载请注明出处:http://blog.csdn.net/WuHaibing_CVer
       OTSU算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。
       1. OTSU算法原理简介
       对于一幅图像,设当前景与背景的分割阈值为t时,前景点占图像比例为w0,均值为u0,背景点占图像比例为w1,均值为u1。则整个图像的均值为u = w0*u0+w1*u1。建立目标函数g(t)=w0*(u0-u)^2+w1*(u1-u)^2,g(t)就是当分割阈值为t时的类间方差表达式。OTSU算法使得g(t)取得全局最大值,当g(t)为最大时所对应的t称为最佳阈值。OTSU算法又称为最大类间方差法。
       2.OTSU算法例程
下面是OSTU算法的C语言代码及其测试,代码基于opencv。
  
  
  1. #include <cv.h>  
  2. #include <highgui.h>  
  3.   
  4. int otsu(IplImage *image)  
  5. {  
  6.     assert(NULL != image);  
  7.   
  8.     int width = image->width;  
  9.     int height = image->height;  
  10.     int x=0,y=0;  
  11.     int pixelCount[256];  
  12.     float pixelPro[256];  
  13.     int i, j, pixelSum = width * height, threshold = 0;  
  14.   
  15.     uchar* data = (uchar*)image->imageData;  
  16.   
  17.     //初始化  
  18.     for(i = 0; i < 256; i++)  
  19.     {  
  20.         pixelCount[i] = 0;  
  21.         pixelPro[i] = 0;  
  22.     }  
  23.   
  24.     //统计灰度级中每个像素在整幅图像中的个数  
  25.     for(i = y; i < height; i++)  
  26.     {  
  27.         for(j = x;j <width;j++)  
  28.         {  
  29.             pixelCount[data[i * image->widthStep + j]]++;  
  30.         }  
  31.     }  
  32.   
  33.   
  34.     //计算每个像素在整幅图像中的比例  
  35.     for(i = 0; i < 256; i++)  
  36.     {  
  37.         pixelPro[i] = (float)(pixelCount[i]) / (float)(pixelSum);  
  38.     }  
  39.   
  40.     //经典ostu算法,得到前景和背景的分割  
  41.     //遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值  
  42.     float w0, w1, u0tmp, u1tmp, u0, u1, u,deltaTmp, deltaMax = 0;  
  43.     for(i = 0; i < 256; i++)  
  44.     {  
  45.         w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;  
  46.   
  47.         for(j = 0; j < 256; j++)  
  48.         {  
  49.             if(j <= i) //背景部分  
  50.             {  
  51.                 //以i为阈值分类,第一类总的概率  
  52.                 w0 += pixelPro[j];        
  53.                 u0tmp += j * pixelPro[j];  
  54.             }  
  55.             else       //前景部分  
  56.             {  
  57.                 //以i为阈值分类,第二类总的概率  
  58.                 w1 += pixelPro[j];        
  59.                 u1tmp += j * pixelPro[j];  
  60.             }  
  61.         }  
  62.   
  63.         u0 = u0tmp / w0;        //第一类的平均灰度  
  64.         u1 = u1tmp / w1;        //第二类的平均灰度  
  65.         u = u0tmp + u1tmp;      //整幅图像的平均灰度  
  66.         //计算类间方差  
  67.         deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 * (u1 - u)*(u1 - u);  
  68.         //找出最大类间方差以及对应的阈值  
  69.         if(deltaTmp > deltaMax)  
  70.         {     
  71.             deltaMax = deltaTmp;  
  72.             threshold = i;  
  73.         }  
  74.     }  
  75.     //返回最佳阈值;  
  76.     return threshold;  
  77. }  
  78.   
  79. int main(int argc, char* argv[])  
  80. {  
  81.     IplImage* srcImage = cvLoadImage("D:\\technology\\CV\\Database\\image\\rice.png",0);  
  82.     assert(NULL != srcImage);  
  83.   
  84.     cvNamedWindow("src");  
  85.     cvShowImage("src",srcImage);  
  86.   
  87.     IplImage* biImage = cvCreateImage(cvGetSize(srcImage),8,1);  
  88.   
  89.     //计算最佳阈值  
  90.     int threshold = otsu(srcImage);  
  91.     //对图像二值化  
  92.     cvThreshold(srcImage,biImage,threshold,255,CV_THRESH_BINARY);  
  93.   
  94.     cvNamedWindow("binary");  
  95.     cvShowImage("binary",biImage);  
  96.       
  97.     cvWaitKey(0);  
  98.   
  99.     cvReleaseImage(&srcImage);  
  100.     cvReleaseImage(&biImage);  
  101.     cvDestroyWindow("src");  
  102.     cvDestroyWindow("binary");  
  103.   
  104.     return 0;  
  105. }  
下面是上述代码的运行结果图片。其中左边为原图像,右边为使用OTSU算法进行二值化后的图像。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值