图像处理之常见二值化方法汇总

图像处理之常见二值化方法汇总

图像二值化是图像分析与处理中最常见最重要的处理手段,二值处理方法也非常多。越

精准的方法计算量也越大。本文主要介绍四种常见的二值处理方法,通常情况下可以满

足大多数图像处理的需要。主要本文讨论的方法仅针对RGB色彩空间。

方法一:

该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的

将像素值设为0(黑色),值大于等于127的像素值设为255(白色)。该方法的好处是计算

量少速度快。缺点更多首先阈值为127没有任何理由可以解释,其次完全不考虑图像的

像素分布情况与像素值特征。可以说该方法是史最弱智的二值处理方法一点也不为过。

方法二:

最常见的二值处理方法是计算像素的平均值K,扫描图像的每个像素值如像素值大于K

像素值设为255(白色),值小于等于K像素值设为0(黑色)。该方法相比方法一,阈值的

选取稍微有点智商,可以解释。但是使用平均值作为二值化阈值同样有个致命的缺点,

可能导致部分对象像素或者背景像素丢失。二值化结果不能真实反映源图像信息。

方法三:

使用直方图方法来寻找二值化阈值,直方图是图像的重要特质,直方图方法选择二值

化阈值主要是发现图像的两个最高的峰,然后在阈值取值在两个峰之间的峰谷最低处。

该方法相对前面两种方法而言稍微精准一点点。结果也更让人可以接受。

方法四:http://en.wikipedia.org/wiki/Thresholding_(image_processing)

使用近似一维Means方法寻找二值化阈值,该方法的大致步骤如下:

1.      一个初始化阈值T,可以自己设置或者根据随机方法生成。

2.      根据阈值图每个像素数据P(n,m)分为对象像素数据G1与背景像素数据G2。(n为

行,m为列)

3.      G1的平均值是m1, G2的平均值是m2

4.      一个新的阈值T’ = (m1 + m2)/2

5.      回到第二步,用新的阈值继续分像素数据为对象与北京像素数据,继续2~4步,

直到计算出来的新阈值等于上一次阈值。

前面三种在以前的博文中都有涉及,最后一种二值化方法的代码如下:

[java] view plaincopy

  1. package com.gloomyfish.filter.study;
  2. import java.awt.image.BufferedImage;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class ThresholdBinaryFilter extends GrayFilter {
  6. @Override
  7. public BufferedImage filter(BufferedImage src, BufferedImage dest) {
  8. int width = src.getWidth();
  9. int height = src.getHeight();
  10. if ( dest == null )
  11. dest = createCompatibleDestImage( src, null );
  12. int[] inPixels = new int[width*height];
  13. int[] outPixels = new int[width*height];
  14. src = super.filter(src, null); // we need to create new one
  15. getRGB( src, 0, 0, width, height, inPixels );
  16. int index = 0;
  17. int means = getThreshold(inPixels, height, width);
  18. for(int row=0; row<height; row++) {
  19. int ta = 0, tr = 0, tg = 0, tb = 0;
  20. for(int col=0; col<width; col++) {
  21. index = row * width + col;
  22. ta = (inPixels[index] >> 24) & 0xff;
  23. tr = (inPixels[index] >> 16) & 0xff;
  24. tg = (inPixels[index] >> 8) & 0xff;
  25. tb = inPixels[index] & 0xff;
  26. if(tr > means) {
  27. tr = tg = tb = 255; //white
  28. } else {
  29. tr = tg = tb = 0; // black
  30. }
  31. outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
  32. }
  33. }
  34. setRGB( dest, 0, 0, width, height, outPixels );
  35. return dest;
  36. }
  37. private int getThreshold(int[] inPixels, int height, int width) {
  38. // maybe this value can reduce the calculation consume;
  39. int inithreshold = 127;
  40. int finalthreshold = 0;
  41. int temp[] = new int[inPixels.length];
  42. for(int index=0; index<inPixels.length; index++) {
  43. temp[index] = (inPixels[index] >> 16) & 0xff;
  44. }
  45. List<Integer> sub1 = new ArrayList<Integer>();
  46. List<Integer> sub2 = new ArrayList<Integer>();
  47. int means1 = 0, means2 = 0;
  48. while(finalthreshold != inithreshold) {
  49. finalthreshold = inithreshold;
  50. for(int i=0; i<temp.length; i++) {
  51. if(temp[i] <= inithreshold) {
  52. sub1.add(temp[i]);
  53. } else {
  54. sub2.add(temp[i]);
  55. }
  56. }
  57. means1 = getMeans(sub1);
  58. means2 = getMeans(sub2);
  59. sub1.clear();
  60. sub2.clear();
  61. inithreshold = (means1 + means2) / 2;
  62. }
  63. long start = System.currentTimeMillis();
  64. System.out.println("Final threshold  = " + finalthreshold);
  65. long endTime = System.currentTimeMillis() - start;
  66. System.out.println("Time consumes : " + endTime);
  67. return finalthreshold;
  68. }
  69. private static int getMeans(List<Integer> data) {
  70. int result = 0;
  71. int size = data.size();
  72. for(Integer i : data) {
  73. result += i;
  74. }
  75. return (result/size);
  76. }
  77. }

效果如下:

时间: 2024-12-06 06:58:40

图像处理之常见二值化方法汇总的相关文章

二值化方法研究

1 otsu方法参考我的另一篇博文: OTSU算法学习 OTSU公式证明 2 sauvola方法, 参考我的另一篇博文: sauvola二值化算法研究 3 Bersen方法 Bersen方法感觉有些粗糙, 只是考虑目标点附近区域的像素灰度值的最大值和最小值, 阈值是最大值和最小值的均值.下面是它的matlab实现,出自这篇博文[二值化]Bernsen算法.如果用C语言实现要用积分图的方法. %局部阈值操作Bersen算法 clc clear I = imread('card8.bmp'); w

二值化方法总结

1.im2bw(Image, threshold_value) 2.最大类件方差(ostu): matlab:im2bw(image, graythresh(image)) 3.bernsen算法 较原始的Bernsen: 这个算法的中心思想是:设当前像素为P,计算以P为中心的大小为(2w+1)*(2w+1)窗口内的所有像素的最大值M与最小值N,两者的均值T, if(M-N)> S  则当前点P的阈值为T. else 当前窗口所在区域的灰度级差别较小,那么窗口在目标区或在背景区,若T>T'则当

数字图像处理_图像二值化_jzcjedu

皮卡丘:“师兄! ” 师兄:“干嘛…?” 皮卡丘:“你帮我看看这个,这是我打车的发票,看起来有点不太清晰,老板说不给我报销…” 师兄:“你仿佛在特意逗我笑,这不是很清楚嘛!!! ” 皮卡丘:“我老板有强迫症,他说这个扫描之后不清楚,让我弄清晰点再给他,不然就不给我钱.师兄,你一定要帮我呀,不然以后都不能打车了.” 师兄:“不急,我先看看,我记得当初张康老师教过我对于这种信噪比很高的图像你要提取出想要的信息的话用二值化处理又简单又方便.“ 皮卡丘:“这样啊,快弄给我看看.“ 稍等,我开一下MATL

atitit.验证码识别step4--------图形二值化 灰度化

atitit.验证码识别step4--------图形二值化 灰度化 1. 常见二值化的方法原理总结 1 1.1. 方法一:该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的将像素值设为0(黑色),值大于等于127的像素值设为255(白色). 1 1.2. 方法二:最常见的二值处理方法是计算像素的平均值K, 2 1.3. 方法三:使用直方图方法来寻找二值化阈值, 2 1.4. 方法四:使用近似一维Means方法寻找二值化阈值,(推荐) 3 2. 使用类库imagei

二值法方法综述及matlab程序

在某些图像处理当中一个关键步是二值法,二值化一方面能够去除冗余信息,另一方面也会使有效信息丢失.所以有效的二值化算法是后续的处理的基础.比如对于想要最大限度的保留下面图的中文字,以便后续的定位处理. 二值化算法包括全局二值化和局部二值化, 全局二值化具有速度快但效果相对差的特点, 局部二值化算法具有速度慢效果好的特点. 原图 全局阈值              方法一:直接采用im2bw ;手动阈值 方法二:迭代法求阈值 迭代式阈值选取的基本思路是:首先根据图像中物体的灰度分布情况,选取一个近似

[转载+原创]Emgu CV on C# (四) —— Emgu CV on 二值化

重点介绍了二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数)  1.概述 图像二值化是图像处理中的一项基本技术,也是很多图像处理技术的预处理过程. 图像的预处理在进行图像二值化操作前要对图像进行预处理,包括彩色图像灰化和增强.由于选取阈值需要参照直方图,因此在图像进行处理后,我们再获取图像的直方图以帮助选取阈值.整个流程如下所示: 读取图像→灰度图像→图像增强→图像直方图→二值化处理 2.数学原理(转载,基本可以不

二值化方法:Minimum Error Thresholding

Kittler二值化方法,是一种经典的基于直方图的二值化方法.由Kittler在1986年在论文“Minimum Error Thresholding”提出. 参考了ImageShop提供的C#版本(http://www.cnblogs.com/Imageshop/p/3307308.html),做了简单修改得到了C++版本的,代码如下: /*灰度图像的二值化方法*/ class CxThreshold { public: static int CalcKittlerMinError(int*

记录一个优秀的图像二值化代码

#region 二值化02 public Bitmap binaryzation(Bitmap srcBitmap, Bitmap dstBitmap) { int threshold = 0; Byte[,] BinaryArray = ToBinaryArray(srcBitmap, out threshold); dstBitmap = BinaryArrayToBinaryBitmap(BinaryArray); return dstBitmap; } /// <summary> //

二值化

https://zh.wikipedia.org/wiki/二值化 二值化是图像分割的一种方法.在二值化图象的时候把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化. 根据阈值选取的不同,二值化的算法分为固定阈值和自适应阈值. 比较常用的二值化方法则有:双峰法.P参数法.迭代法和OTSU法等.