图像处理之积分图应用四(基于局部均值的图像二值化算法)

来源:互联网 发布:收银进销存软件 编辑:程序博客网 时间:2024/05/22 03:48

图像处理之积分图应用四(基于局部均值的图像二值化算法)

基本原理
均值法,选择的阈值是局部范围内像素的灰度均值(gray mean),该方法的一个变种是用常量C减去均值Mean,然后根据均值实现如下操作:
pixel = (pixel > (mean - c)) ? object : background
其中默认情况下参数C取值为0。object表示前景像素,background表示背景像素。

实现步骤
1. 彩色图像转灰度图像
2. 获取灰度图像的像素数据,预计算积分图
3. 根据输入的参数窗口半径大小从积分图中获取像素总和,求得平均值
4.循环每个像素,根据局部均值实现中心像素的二值化赋值
5.输入二值图像

运行结果:
这里写图片描述

代码实现:

package com.gloomyfish.ii.demo;import java.awt.image.BufferedImage;public class FastMeanBinaryFilter extends AbstractImageOptionFilter {    private int constant;    private int radius;    public FastMeanBinaryFilter() {        constant = 10;        radius = 7; // 1,2,3,4,5,6,7,8    }    public int getConstant() {        return constant;    }    public void setConstant(int constant) {        this.constant = constant;    }    public int getRadius() {        return radius;    }    public void setRadius(int radius) {        this.radius = radius;    }    @Override    public BufferedImage process(BufferedImage image) {        int width = image.getWidth();        int height = image.getHeight();        BufferedImage dest = createCompatibleDestImage( image, null );        // 图像灰度化        int[] inPixels = new int[width*height];        int[] outPixels = new int[width*height];        byte[] binData = new byte[width*height];        getRGB( image, 0, 0, width, height, inPixels );        int index = 0;        for(int row=0; row<height; row++) {            int ta = 0, tr = 0, tg = 0, tb = 0;            for(int col=0; col<width; col++) {                index = row * width + col;                ta = (inPixels[index] >> 24) & 0xff;                tr = (inPixels[index] >> 16) & 0xff;                tg = (inPixels[index] >> 8) & 0xff;                tb = inPixels[index] & 0xff;                int gray= (int)(0.299 *tr + 0.587*tg + 0.114*tb);                binData[index] = (byte)gray;            }        }        // per-calculate integral image        IntIntegralImage grayii = new IntIntegralImage();        grayii.setImage(binData);        grayii.process(width, height);        int yr = radius;        int xr = radius;        int size = (yr * 2 + 1)*(xr * 2 + 1);        for (int row = 0; row < height; row++) {            for (int col = 0; col < width; col++) {                index = row * width + col;                // 计算均值                int sr = grayii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));                int mean = sr / size;                int pixel = binData[index]&0xff;                // 二值化                if(pixel > (mean-constant)) {                    outPixels[row * width + col] = (0xff << 24) | (0xff << 16) | (0xff << 8) | 0xff;                } else {                    outPixels[row * width + col] = (0xff << 24) | (0x00 << 16) | (0x00 << 8) | 0x00;                }            }        }        // 返回结果        setRGB(dest, 0, 0, width, height, outPixels);        return dest;    }}

2017年已经开始啦!博客每个月都会有图像处理相关技术文章更新,欢迎大家继续关注!

2 1
原创粉丝点击