基于直方图的图像全局二值化算法原理、实现--基于谷底最小值的阈值

来源:互联网 发布:ubuntu 修复win7引导 编辑:程序博客网 时间:2024/06/10 15:11

 1、描述:

  此方法实用于具有明显双峰直方图的图像,其寻找双峰的谷底作为阈值,但是该方法不一定能获得阈值,对于那些具有平坦的直方图或单峰图像,该方法不合适。

  2、实现过程:

  该函数的实现是一个迭代的过程,每次处理前对直方图数据进行判断,看其是否已经是一个双峰的直方图,如果不是,则对直方图数据进行半径为1(窗口大小为3)的平滑,如果迭代了一定的数量比如1000次后仍未获得一个双峰的直方图,则函数执行失败,如成功获得,则最终阈值取两个双峰之间的谷底值作为阈值。

     注意在编码过程中,平滑的处理需要当前像素之前的信息,因此需要对平滑前的数据进行一个备份。另外,首数据类型精度限制,不应用整形的直方图数据,必须转换为浮点类型数据来进行处理,否则得不到正确的结果。

 3、实现代码:

     int GetMinimumThreshold(int* HistGram)
     {        int Y, Iter = 0;        double *HistGramC = new double[256];           // 基于精度问题,一定要用浮点数来处理,否则得不到正确的结果        double *HistGramCC = new double[256];          // 求均值的过程会破坏前面的数据,因此需要两份数据        for (Y = 0; Y < 256; Y++)        {            HistGramC[Y] = HistGram[Y];            HistGramCC[Y] = HistGram[Y];        }        // 通过三点求均值来平滑直方图        while (IsDimodal(HistGramCC) == false)                                        // 判断是否已经是双峰的图像了              {            HistGramCC[0] = (HistGramC[0] + HistGramC[0] + HistGramC[1]) / 3;                 // 第一点            for (Y = 1; Y < 255; Y++)                HistGramCC[Y] = (HistGramC[Y - 1] + HistGramC[Y] + HistGramC[Y + 1]) / 3;     // 中间的点            HistGramCC[255] = (HistGramC[254] + HistGramC[255] + HistGramC[255]) / 3;         // 最后一点            System.Buffer.BlockCopy(HistGramCC, 0, HistGramC, 0, 256 * sizeof(double));            Iter++;            if (Iter >= 1000) return -1;                                                   // 直方图无法平滑为双峰的,返回错误代码        }       // 阈值极为两峰之间的最小值         bool Peakfound = false;        for (Y = 1; Y < 255; Y++)        {            if (HistGramCC[Y - 1] < HistGramCC[Y] && HistGramCC[Y + 1] < HistGramCC[Y]) Peakfound = true;            if (Peakfound == true && HistGramCC[Y - 1] >= HistGramCC[Y] && HistGramCC[Y + 1] >= HistGramCC[Y])                return Y - 1;        }        return -1;    }
复制代码

  其中IsDimodal函数为判断直方图是否是双峰的函数,代码如下:


   bool IsDimodal(double* HistGram)       // 检测直方图是否为双峰的    {        // 对直方图的峰进行计数,只有峰数位2才为双峰         int Count = 0;        for (int Y = 1; Y < 255; Y++)        {            if (HistGram[Y - 1] < HistGram[Y] && HistGram[Y + 1] < HistGram[Y])            {                Count++;                if (Count > 2) return false;            }        }        if (Count == 2)            return true;        else            return false;    }

1 0
原创粉丝点击