zoukankan      html  css  js  c++  java
  • 图像处理------常见二值化方法汇总 分类: 视频图像处理 2015-07-24 14:51 33人阅读 评论(0) 收藏

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

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

    足大多数图像处理的需要。主要本文讨论的方法仅针对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步,

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

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

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

    效果如下:


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    phpcms调用指定文章内容模型的ID
    phpcms V9的各种功能总结
    如何使用ajax与php实现简单的流程管理
    键盘按键和键盘对应代码表
    ajax实现省、市、区、三级联动(例题)
    用ajax做登录与删除
    var_dump、echo、print_r 的区别
    字符串删除重复字符
    树的非递归遍历
    字符串操作_(不使用库函数)
  • 原文地址:https://www.cnblogs.com/mao0504/p/4705512.html
Copyright © 2011-2022 走看看