自适应阈值二值化

最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU。它是按图像的灰度特性,将图像分成背景和目标2部分。背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。对于图像I(x,y),前景(即目标)和背景的分割阈值记作,属于前景的像素点数占整幅图像的比例记为,其平均灰度;背景像素点数占整幅图像的比例为,其平均灰度为。图像的总平均灰度记为,类间方差记为

假设图像的背景较暗,并且图像的大小为,图像中像素的灰度值小于阈值的像素个数记作,像素灰度大于阈值的像素个数记作,则有:

        

采用遍历的方法得到使类间方差最大的阈值,即为所求。



代码区


  1. OpenCV代码:  
  2. int myOtsu(const IplImage *frame) //大津法求阈值   
  3.  
  4. #define GrayScale 256   //frame灰度级   
  5.     int width frame->width;  
  6.     int height frame->height;  
  7.     int pixelCount[GrayScale]={0};  
  8.     float pixelPro[GrayScale]={0};  
  9.     int i, j, pixelSum width height, threshold 0;  
  10.     uchar* data (uchar*)frame->imageData;  
  11.   
  12.     //统计每个灰度级中像素的个数   
  13.     for(i 0; height; i++)  
  14.      
  15.         for(j 0;j width;j++)  
  16.          
  17.             pixelCount[(int)data[i width j]]++;  
  18.          
  19.      
  20.   
  21.     //计算每个灰度级的像素数目占整幅图像的比例   
  22.     for(i 0; GrayScale; i++)  
  23.      
  24.         pixelPro[i] (float)pixelCount[i] pixelSum;  
  25.      
  26.   
  27.     //遍历灰度级[0,255],寻找合适的threshold   
  28.     float w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax 0;  
  29.     for(i 0; GrayScale; i++)  
  30.      
  31.         w0 w1 u0tmp u1tmp u0 u1 deltaTmp 0;  
  32.         for(j 0; GrayScale; j++)  
  33.          
  34.             if(j <= i)   //背景部分   
  35.              
  36.                 w0 += pixelPro[j];  
  37.                 u0tmp += pixelPro[j];  
  38.              
  39.             else   //前景部分   
  40.              
  41.                 w1 += pixelPro[j];  
  42.                 u1tmp += pixelPro[j];  
  43.              
  44.          
  45.         u0 u0tmp w0;  
  46.         u1 u1tmp w1;  
  47.         deltaTmp (float)(w0 *w1* pow((u0 u1), 2))  
  48.         if(deltaTmp deltaMax)  
  49.          
  50.             deltaMax deltaTmp;  
  51.             threshold i;  
  52.          
  53.      
  54.     return threshold;  
  55.  
[plain]  view plain copy print ?
  1. MATLAB 代码1  
  2.   
  3. function binariedImage=OSTU(scoreImage)  
  4.   
  5. scoreImage=double(scoreImage);  
  6. [height,length]=size(scoreImage);  
  7. totalPixel=height*length;  
  8. maxPixNumber=max(max(scoreImage));  
  9. 这个地方为了以后计算方便 就不这样计算了 而是默认最大的为255  
  10.   
  11. pixelCount=zeros(1,256);%统计各个像素值的个数  
  12. 0-256  
  13. for i=1:length  
  14.     for j=1:height  
  15.         number=scoreImage(j,i)+1;  
  16.         pixelCount(number)=pixelCount(number)+1;  
  17.     end  
  18. end  
  19.   
  20. %概率  
  21. pf=pixelCount/totalPixel;  
  22. %前向累计概率密度函数  
  23. cpf=zeros(1,256);  
  24. cpf(1)=pf(1);  
  25. for i=2:256  
  26.     cpf(i)=cpf(i-1)+pf(i);  
  27. end  
  28. %后向累计概率密度函数  
  29. bpf=zeros(1,256);  
  30. bpf(256)=pf(256);  
  31. for j=256:-1:2  
  32.     bpf(j-1)=bpf(j)+pf(j-1);  
  33. end   
  34.   
  35.   
  36. %前向累计期望  
  37. meanForward=zeros(1,256);  
  38. meanForward(1)=1;  
  39. for i=2:256  
  40.     meanForward(i)=meanForward(i-1)*(cpf(i-1)/cpf(i))+(pf(i)/cpf(i))*i;  
  41. end  
  42.   
  43. %后向累计期望  
  44. meanBack=zeros(1,256);  
  45. meanBack(max(max(scoreImage)))=max(max(scoreImage));  
  46. for i=max(max(scoreImage)):-1:2  
  47.     meanBack(i-1)=meanBack(i)*(bpf(i)/bpf(i-1))+(pf(i-1)/bpf(i-1))*(i-1);  
  48. end  
  49.   
  50.   
  51. delta=cpf.*bpf.*(meanForward-meanBack).^2;  
  52. [value,index]=max(delta);  
  53. 返回的是逻辑的图像  
  54. binariedImage=scoreImage>index;  


[plain]  view plain copy print ?
  1.   

[plain]  view plain copy print ?
  1. MATLAB 代码2  
  2.   
  3. function binariedImage=OSTU(scoreImage)  
  4.   
  5.   
  6. [height,length]=size(scoreImage);  
  7. totalNum=height*length;  
  8. pixelCount=zeros(1,256);%统计各个像素值的个数  
  9. for i=1:length  
  10.     for j=1:height  
  11.         number=scoreImage(j,i)+1;  
  12.         pixelCount(number)=pixelCount(number)+1;  
  13.     end  
  14. end  
  15. pf=pixelCount/totalNum;  
  16. deltaMax=0;  
  17. a=1:256;  
  18. maxmax=max(max(scoreImage));  
  19. for i=1:maxmax  
  20.       
  21.     w1=sum(pf(1:i));  
  22.     w2=1-w1;  
  23.     mean1=sum(pf(1:i).*a(1:i))/sum(pf(1:i));  
  24.     mean2=sum(pf(i+1:maxmax).*a(i+1:maxmax))/sum(pf(i+1:maxmax));  
  25.     delta=w1*w2*(mean1-mean2)^2;  
  26.     if delta>deltaMax  
  27.         deltaMax=delta;  
  28.         threshold=i;  
  29.     end  
  30.       
  31. end  
  32.   
  33. 返回的是逻辑的图像  
  34. binariedImage=scoreImage>threshold; 

 OpenCV基于局部自适应阈值的图像二值化

本篇文章来源于 Linux公社网站(www.linuxidc.com 原文链接:http://www.linuxidc.com/Linux/2013-01/78174.htm

在图像处理应用中二值化操作是一个很常用的处理方式,例如零器件图片的处理、文本图片和验证码图片中字符的提取、车牌识别中的字符分割,以及视频图像中的运动目标检测中的前景分割,等等。

较为常用的图像二值化方法有:1)全局固定阈值;2)局部自适应阈值;3)OTSU等。

全局固定阈值很容易理解,就是对整幅图像都是用一个统一的阈值来进行二值化;

局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。

OpenCV中实现了以上几种二值化方法。

下面这段代码对比了全局固定阈值与局部自适应阈值的二值化结果。

//  基于局部自适应阈值的图像二值化
//  Author: http://blog.csdn.net/icvpr

#include
#include

int main(int argc, char** argv)
{
 cv::Mat image = cv::imread("../test.bmp", CV_LOAD_IMAGE_GRAYSCALE);
 if (image.empty())
 {
  std::cout<<"read image failure"<<std::endl;
  return -1;
 }


 // 全局二值化
 int th = 100;
 cv::Mat global;
 cv::threshold(image, global, th, 255, CV_THRESH_BINARY_INV);


 // 局部二值化

 int blockSize = 25;
 int constValue = 10;
 cv::Mat local;
 cv::adaptiveThreshold(image, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);


 cv::imshow("globalThreshold", global);
 cv::imshow("localThreshold", local);
 cv::waitKey(0);


 return 0;
}

原图:

 

全局固定阈值二值化结果(T = 100)

 

局部自适应阈值二值化结果(块大小 = 25)

[

本篇文章来源于 Linux公社网站(www.linuxidc.com 原文链接:http://www.linuxidc.com/Linux/2013-01/78174.htm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值