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. error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...

  2. Python subprocess- call、check_call、check_output

    简介 subprocess模块用来创建新的进程,连接到其stdin.stdout.stderr管道并获取它们的返回码.subprocess模块的出现是为了替代如下旧模块及函数:os.system.os ...

  3. 移动端默认meta标签

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><met ...

  4. gbdt和xgboost api

    class xgboost.XGBRegressor(max_depth=3, learning_rate=0.1, n_estimators=100, silent=True, objective= ...

  5. 为通过 ATS 检测 Tomcat 完全 TLS v1.2、完全正向加密及其结果检验

    2017 年起 app store 要求 app 对接的服务器支持 TLS v1.2,否则 ats 检测不予通过.有点强制推 TLS v1.2 的意味.本文介绍如何使 tomcat 强制执行 TLS ...

  6. spark java API 实现二次排序

    package com.spark.sort; import java.io.Serializable; import scala.math.Ordered; public class SecondS ...

  7. ClassLoader.loadClass和Class.forName的区别

    为什么要把ClassLoader.loadClass(String name)和Class.forName(String name)进行比较呢,因为他们都能在运行时对任意一个类,都能够知道该类的所有属 ...

  8. JS倒计时、计时

    倒计时 倒计时常用于发送验证码 前端代码如下: <!DOCTYPE html> <html> <head> <title>倒计时.计时</titl ...

  9. day5模块学习--yaml文件处理

    yaml文件处理(http://pyyaml.org/wiki/PyYAMLDocumentation)     摘要: 本文讲的是yaml在python上的使用教程详解, YAML是一种容易人类阅读 ...

  10. ASP.NET:MVC中文件上传与地址变化处理

    目录 文件的上传和路径处理必须解决下面列出的实际问题: 1.重复文件处理 2.单独文件上传 3.编辑器中文件上传 4.处理文章中的图片路径 5.处理上传地址的变化 一.上传文件和重复文件处理 文件处理 ...