OTSU最大类间方差实现图像的二值化

OTSU方法又叫做最大类间方差,自适应选择一个合理的阈值,根据此阈值将灰度图像转换为二值图像,例如在车牌识别过程中,将摄像头拍到的图像转化为一副灰度图像,在提取车牌的有效信息中就需要图像的二值化化。
基础知识:
对于随机变量X,它的方差为E(X-EX)2,EX为数学期望,相当于均值,进行类比。
OTSU算法的步骤:
1.选定一个阈值T,将[0,255]的256个灰度值分为A,B两部分,即为A,B两类。
2.用P(A)表示A部分像素点所占总像素的比例,依次计算出P(B)。
3.用u表示整个图像的灰度均值,用u(A)表示A部分的像素均值,同理计算出u(B).
4.类间方差为P(A)(u-u(A))(u-u(A))+P(B)(u-u(B))(u-u(B))。
5.阈值T在[0,255]遍历去寻找最大类间方差。

int Otsu(Mat img)
{  //灰度图像的channels为1
    if (img.channels() != 1)
    {
        printf("请输入灰度图像");

        return -1;
    }
    int T = 0;//算法的阈值
    double MaxVariacne = 0;//
    double w0 = 0;//前景像素点数所占的比例
    double w1 = 0;//背景像素所占的比例
    double u0 = 0;//前景的平均灰度
    double  u1 = 0;//背景的平均灰度
    int Histogram[256] = { 0 };//256个发光等级
    uchar*  data = img.data;//得到矩阵的首地址
                            //得到像素的总和
    int totalNum = img.cols*img.rows;
    //统计每个灰度等级中像素的个数
    for (int i = 0; i < img.rows; i++)
    {
        uchar* data = img.ptr<uchar>(i);//得到i行的首地址 得到的data是首地址
        for (int j = 0; j < img.cols; j++)
        { //发光等级 data
            Histogram[data[j]] += 1;


        }
    }
    for (int i = 0; i<255; i++)
    {
        //每次遍历的之前初始化各类变量
        w1 = 0; u1 = 0; w0 = 0; u0 = 0;
        //背景各分量的计算  当灰度级别取2 为分割点的时候
        for (int j = 0; j <= i; j++)
        {
            w1 = w1 + Histogram[j];//背景各部分像素点的总数

            u1 = u1 + j*Histogram[j];  //计算出灰度数值之和

        }
        if (w1 == 0)
        {
            continue;

        }
        u1 = u1 / w1;//背景的平均灰度数值
        w1 = w1 / totalNum;//背景部分像素点所占的比例
                           //上面即是背景各分量计算

                           //前景各部分之间的计算
        for (int k = i + 1; k < 255; k++)
        {
            w0 = w0 + Histogram[k];//前景各部分像素点的总和  计算总灰度
            u0 = u0 + k*Histogram[k];


        }
        //计算平局灰度
        u0 = u0 / w0;
        //计算像素所占的比例
        w0 = w0 / totalNum;
        if (w0 == 0)
        {

            continue;
        }
        double variance = w0*w1*(u1 - u0)*(u1 - u0);


        if (MaxVariacne < variance)
        {
            MaxVariacne = variance;
            T = i;
        }

    }

    printf("经过计算最大的类方差为%lf\n", MaxVariacne);

    return T;
}

原始的图像程序运行结果输出图像源代码下载地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值