Otsu详细算法解析


前言


一、OTSU算法是什么?

        OTSU算法又名最大类间方差法,是由日本学者大津展之于1979 年提出,利用整副图像的直方图特性,选择全局阈值T。文字图片和背景通常会出现两个驼峰,确定一个灰度值作为阈值,将灰度值小于阈值的点作为目标,大于等于阈值的点作为背景。遍历整副图像灰度值,选择类间方差最大时对应的灰度值作为阈值,OTSU算法为目前比较好的确定阈值的算法。

二、算法详解

该博文由该算法的原理:
OpenCV — Otsu 算法_FlyDremever的博客-CSDN博客_opencv otsu

 2.算法实现

代码如下(示例):

//算法实现步骤
//Step1 计算灰度图像的全局期望
//Step2 遍历灰度值从0到255将灰度图像分为前景与背景
//Step2.1 求前景的期望与概率
//Step2.2 求背景的期望与概率
//Step2.3 由间类方差定义求当前阈值的间类方差
//遍历过程中,不断比较求得最大的间类方差


int thresh_otsu(Mat input)
{
    int histogram[256] = { 0 };//计算各灰度级的像素数目
    double global_mean = 0;//全局期望
    int imgSize = input.size().area();//图像的大小
    //遍历图像
    for (int i = 0; i < input.rows; i++)
    {
        uchar *data = input.ptr(i);//当前行地址
        for (int j = 0; j < input.cols; j++)//遍历当前行
        {
            histogram[data[j]]++;//当前灰度级为data[j]的数值
            global_mean += data[j];//统计整幅图像的像素值之和
        }
    }
    //期望(平均) = 总和 / 个数 
    global_mean /= imgSize;//统计完后根据均值定义求得图像的均值

    double p1 = 0, p2 = 0, m1 = 0, m2 = 0;
    //p1 m1 分别为背景的概率与背景的期望
    //p2 m2 分别为前景的概率与前景的期望
    double sg = 0;//间类方差
    double temp_sg = -1;//用于交换的变量
    int k = 0;
    //遍历i求当前阈值i得到的间类方差,找到间类方差最大值对应的阈值i
    for (int i = 0; i < 256; i++)
    {
        //小于阈值i为前景(目标)
        for (int j = 0; j <= i; j++)
        {
            p2 += histogram[j];//统计前景的像素值 个数 总和 即小于阈值i的像素点个数之和  
            m2 += (histogram[j] * j);//统计前景的像素值 总和  即小于阈值i的像素值之和
        }
        m2 = m2 / p2;//由期望公式得到期望 (前景)

        //大于阈值i为背景
        for (int j = i + 1; j < 256; j++)
        {
            p1 += histogram[j];
            m1 += (histogram[j] * j);
        }
        m1 /= p1;//由期望公式得到期望 (背景)

        p2 /= imgSize;//求前景的概率 = 前景像素点个数 / 图像总像素个数

        p1 = 1 - p2;//求背景的概率

        sg = p1 * p2*(m1 - m2)*(m1 - m2); //计算当前阈值i的类间方差

        //找出 阈值i分割的前景与背景的最大间类方差  
        if (sg > temp_sg)
        {
            temp_sg = sg;
            k = i;
        }
        p1 = 0, p2 = 0, m1 = 0, m2 = 0;//求完后这些数据要重置为0 计算新的阈值的相应的数据
    }
    //cout<<"k = "<


总结

你可能感兴趣的:(图像处理实战,算法)