数字图像处理之OSTU二值化

#include<stdlib.h>
bool tobinary(unsigned char *pImage, int width, int height, int biBitCount)
{
    int i, j, k;
    int h[256]={0};
    unsigned int ip1, ip2, is1, is2=0; //存储前景和背景的灰度总和及像素个数
    double w0, w1=0; //前景和背景像素的比例
    double mean1, mean2=0; //前景和背景的平均灰度
    double g[245]={0}; //存储类间方差
    double gmax=0; //最大类间方差
    unsigned char th=0; //二值化阈值
    //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
    int lineByte=(width * biBitCount/8+3)/4*4;




    for(i=0; i<height; i++) //灰度直方图
    for(j=0; j<width; j++)
        {
            k = *(pImage+i*lineByte+j);
            h[k]++;
        }


    for(i=10; i<245; i++) //阈值一般不会超出这个范围
    {
        ip1=0; ip2=0; is1=0; is2=0;
        w0=0; w1=0;
        for(j=0; j<i; j++)
        {
            ip1+=h[j]*j; is1+=h[j];
        }
        mean1=ip1/is1;
        w0=double(is1)/double(width*height);


        for (j=i; j<256; j++)
        {
            ip2+=h[j]*j; is2+=h[j];
        }
        mean2=ip2/is2;
        w1=1-w0;


        g[i]=w0*w1*(mean1-mean2)*(mean1-mean2);
    }
    gmax=g[10];
    th=10;
    for(i=11; i<245; i++)
        if(g[i]>gmax)
        {
            gmax=g[i]; th=i;
        }


    for(i=0; i<height; i++)
        for(j=0; j<width; j++)
            *(pImage+i*lineByte+j)=*(pImage+i*lineByte+j)>th?255:0;
    return 1;

}     

这个语句要注意 w0=double(is1)/double(width*height); 因为如果不加强制转换的话,右边一个小的整数除以一个大的整数结果为0。
程序中有这么一句 int lineByte=(width * biBitCount/8+3)/4*4; 这是因为Windows系统中一行像素所占的字节数为4的倍数,因此不是4的倍数时要补充为4的倍数,这样在寻址每一个像素的时候,像素的地址为 pImage+i*lineByte+j ;而循环控制语句for(j=0; j<width; j++)中仍用width,不用lineByte,因为补充的数据不是原图像数据,我们不需要处理。
该函数在Eclipse上调试通过。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值