Kittler二值化方法,是一种经典的基于直方图的二值化方法。由J. Kittler在1986年发表的论文“Minimum Error Thresholding”提出。论文是对贝叶斯最小错误阈值的准则做了改进,使得计算更加的简单和有效。

  Divijver 和 Kittler的贝叶斯最小错误准则为:

  因为需要求解二次方程和对正态分布的均值和方差进行估计,Nagawa 和 Rosenfeld提出了求解和估计的方法(Some Experiments on Variable Thresholding)。但他们的方法计算式很耗时的。作者做了一个修改,从而得到了计算更简单的准则函数。假设已知直方图h, 则通过以下目标函数寻找最优为:

,

其中

  该方法对于双峰的图像,双峰差别特别大的图像有很好的分割效果,这样的的场景在工业视觉中的零部件中常常遇到。如打光部件后是很容易形成双波峰的,这样该方法的分割往往会得到很好的效果,下面的实验也说明该方法在这类场景中是要更优于大津法和一维最大熵法的。

  论文中还提到了一种变化阈值的求解办法。其思想是:首先将图像割成大小一样的小块(patch),然后对每个小块都使用论文所提到的方法计算得到一个局部(相对于整幅图片)的阈值,接着用双边插值法对计算得到的阈值进行插值,从而得到了每个像素点的二值化分割阈值。文中对一个工业器件进行分割,并给出了效果图:

  代码实现参考了ImageShop提供的C#版本(http://www.cnblogs.com/Imageshop/p/3307308.html),做了简单修改得到了C++版本,代码如下:

/*灰度图像的二值化方法*/

class CxThreshold
{
public:
static int CalcKittlerMinError(int* HistGram)
{
int X, Y;
int MinValue, MaxValue;
int Threshold ;
long PixelBack, PixelFore;
double OmegaBack, OmegaFore, MinSigma, Sigma, SigmaBack, SigmaFore;
for (MinValue = ; MinValue < && HistGram[MinValue] == ; MinValue++) ;
for (MaxValue = ; MaxValue > MinValue && HistGram[MinValue] == ; MaxValue--) ;
if (MaxValue == MinValue) return MaxValue; // 图像中只有一个颜色
if (MinValue + == MaxValue) return MinValue; // 图像中只有二个颜色
Threshold = -;
MinSigma = 1E+;
for (Y = MinValue; Y < MaxValue; Y++){
PixelBack = ; PixelFore = ;
OmegaBack = ; OmegaFore = ;
for (X = MinValue; X <= Y; X++){
PixelBack += HistGram[X];
OmegaBack = OmegaBack + X * HistGram[X];
}
for (X = Y + ; X <= MaxValue; X++){
PixelFore += HistGram[X];
OmegaFore = OmegaFore + X * HistGram[X];
}
OmegaBack = OmegaBack / PixelBack;
OmegaFore = OmegaFore / PixelFore;
SigmaBack = ; SigmaFore = ;
for (X = MinValue; X <= Y; X++) SigmaBack = SigmaBack + (X - OmegaBack) * (X - OmegaBack) * HistGram[X];
for (X = Y + ; X <= MaxValue; X++) SigmaFore = SigmaFore + (X - OmegaFore) * (X - OmegaFore) * HistGram[X];
if (SigmaBack == || SigmaFore == ){
if (Threshold == -)Threshold = Y;
}
else{
SigmaBack = sqrt(SigmaBack / PixelBack);
SigmaFore = sqrt(SigmaFore / PixelFore);
//Sigma = 1 + 2 * (PixelBack * log(SigmaBack / PixelBack) + PixelFore * log(SigmaFore / PixelFore));
Sigma = PixelBack * log(SigmaBack / PixelBack) + PixelFore * log(SigmaFore / PixelFore) - PixelBack * log( PixelBack) - PixelFore* log(PixelFore);
if (Sigma < MinSigma){
MinSigma = Sigma;
Threshold = Y;
}
}
}
return Threshold;
}
};
 
  实验不同算法的效果:
  kettler法,获得最佳的分割效果,纽扣完整性最好。

  大津法,对纽扣亮色部分分割不好。

  一维最大熵法。获得了最差的效果,纽扣完整性不好。对和白色接近的颜色分割较差。

												

二值化方法:Kittler:Minimum Error Thresholding的更多相关文章

  1. python实现超大图像的二值化方法

    一,分块处理超大图像的二值化问题   (1) 全局阈值处理  (2) 局部阈值 二,空白区域过滤 三,先缩放进行二值化,然后还原大小 np.mean() 返回数组元素的平均值 np.std() 返回数 ...

  2. [python-opencv]超大图像二值化方法

    *分块 *全局阈值 VS 局部阈值 import cv2 as cv import numpy as np def big_image_binary(image): print(image.shape ...

  3. 二值法方法综述及matlab程序

    在某些图像处理当中一个关键步是二值法,二值化一方面能够去除冗余信息,另一方面也会使有效信息丢失.所以有效的二值化算法是后续的处理的基础.比如对于想要最大限度的保留下面图的中文字,以便后续的定位处理. ...

  4. 一种局部二值化算法:Sauvola算法

    之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...

  5. openCV_java 图像二值化

    较为常用的图像二值化方法有:1)全局固定阈值:2)局部自适应阈值:3)OTSU等. 局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值.这样做的好处在于每个像素位置处的二值化 ...

  6. 二值化函数cvThreshold()参数CV_THRESH_OTSU的疑惑【转】

    查看OpenCV文档cvThreshold(),在二值化函数cvThreshold(const CvArr* src, CvArr* dst, double threshold, double max ...

  7. [python-opencv]图像二值化【图像阈值】

    图像二值化[图像阈值]简介: 如果灰度图像的像素值大于阈值,则为其分配一个值(可以是白色255),否则为其分配另一个值(可以是黑色0) 图像二值化就是将灰度图像上的像素值设置为0或255,也就是将整个 ...

  8. OpenCV_基于局部自适应阈值的图像二值化

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

  9. OpenCV---超大图像二值化和空白区域过滤

    超大图像的二值化方法 1.可以采用分块方法, 2.先缩放处理就行二值化,然后还原大小 一:分块处理超大图像的二值化问题 def big_image_binary(image): print(image ...

随机推荐

  1. Github授权新的设备ssh接入

    为Mac生成公钥 步骤: 检查本机是否已有公钥 ls -la ~/.ssh 将原来的公钥删除 rm -rf ~/.ssh 生成新的公钥(填自己的邮箱),然后除了密码,一路默认 ssh-keygen - ...

  2. Webmin试玩

    安装: # cd /opt # wget http://www.webmin.com/jcameron-key.asc # wget http://www.webmin.com/download/rp ...

  3. Linux 获取网关地址

    route命令的用法:操作或者显示IP路由表route:DESCRIPTION Route manipulates the kernel's IP routing tables. Its primar ...

  4. Python列表(list)

    序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. 此外,Python已经内置确定序列的长度以及确定最大和最小的元素 ...

  5. 列表CListCtrl类使用

    CListCtrl是列表控件类,列表控件的每一行叫做一个item,每一列叫做一个subitem.每一行和每一列都有个ID号,可以确定唯一的单元格. 最近使用了这个控件,有心得总结如下: (Dialog ...

  6. 5 个非常有用的 Laravel Blade 指令,你用过哪些?

    接下来我将带大家认识下五个 Laravel Blade 指令,这些指令将让你在解决特定问题时如虎添翼.如果你是刚接触 Laravel 的用户,这些小技巧能带你认识到 Laravel Blade 模板引 ...

  7. Codeforces 777E - Hanoi Factory(贪心+栈)

    题目链接:http://codeforces.com/problemset/problem/777/E 题意:有n个环给你内环半径.外环半径和高度,叠这些环还要满足以下要求: ①:下面的环的外径要&g ...

  8. 最邻近规则分类KNN算法

    例子: 求未知电影属于什么类型: 算法介绍: 步骤:  为了判断未知实例的类别,以所有已知类别的实例作为参照      选择参数K      计算未知实例与所有已知实例的距离      选择最近K个已 ...

  9. hdu 1171 有num1个w1 , num2个w2 ……. (母函数)

    输入n,代表学院里面有n种设备,并且在下面输入n行,每一行输入v,m代表设备的价格为v,设备的数量是m.然后要求把这些设备的总价值分摊,尽量平分,使其总价值接近相等,最好是相等 比如样例二(1+X10 ...

  10. 【BZOJ】4894: 天赋

    题解 这道题是求一个有向图的外向生成树 入度矩阵对应着外向生成树,出度矩阵对应着内向生成树,知道了这个就可以求出基尔霍夫矩阵了,同时n - 1阶主子式一定要删掉根节点的一行一列 代码 #include ...