关闭

图像处理之特殊灰度算法技巧

标签: 图像处理算法distancenullfilterfloat
23093人阅读 评论(24) 收藏 举报
分类:

图像处理之特殊灰度算法技巧


介绍几种特殊的灰度算法滤镜,将彩色图像转换为灰度图像。其中涉及到的有基于阈值的图

像二值化,弗洛伊德.斯坦德伯格抖动算法,基于阈值的部分灰度化

 

基础知识- 怎么把RGB转换为单色的[0 ~256]之间的灰度,最常用的转换公式如下:

Gray = 0.299 * red + 0.587 * green + 0.114 * blue;

 

1.       基于像素平均值的图像阈值二值化算法:

处理流程:

a.      首先将彩色图像转换为灰度图像

b.      计算灰度图像的算术平均值– M

c.      以M为阈值,完成对灰度图二值化( 大于阈值M,像素点赋值为白色,否则赋值为黑

色)

图像效果:


关键代码:

	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
            dest = createCompatibleDestImage( src, null );
        src = super.filter(src, dest);

        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB(src, 0, 0, width, height, inPixels );
        
        // calculate means of pixel  
        int index = 0;  
        double redSum = 0, greenSum = 0, blueSum = 0;  
        double total = height * width;  
        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;  
                redSum += tr;  
                greenSum += tg;  
                blueSum +=tb;  
            }  
        }
        int means = (int)(redSum / total);
        System.out.println(" threshold average value = " + means);
        
        // dithering 
        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;
                if(tr >=means) {
                	tr = tg = tb = 255;
                } else {
                	tr = tg = tb = 0;
                }
                outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
                
        	}
        }
        setRGB( dest, 0, 0, width, height, outPixels );
        return dest;
	}

2.       基于错误扩散的Floyd-Steinberg抖动算法

关于什么是Floyd-Steinberg抖动,参见这里

http://en.wikipedia.org/wiki/Floyd–Steinberg_dithering

图像效果:

关键代码:

	@Override
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
        	dest = createCompatibleDestImage( src, null );
        src = super.filter(src, dest);

        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 0, 0, width, height, inPixels );
        int index = 0;
        for(int row=0; row<height; row++) {
        	for(int col=0; col<width; col++) {
        		index = row * width + col;
                int r1 = (inPixels[index] >> 16) & 0xff;
                int g1 = (inPixels[index] >> 8) & 0xff;
                int b1 = inPixels[index] & 0xff;
                int cIndex = getCloseColor(r1, g1, b1);
                outPixels[index] = (255 << 24) | (COLOR_PALETTE[cIndex][0] << 16) | (COLOR_PALETTE[cIndex][1] << 8) | COLOR_PALETTE[cIndex][2];
                int er = r1 - COLOR_PALETTE[cIndex][0];
                int eg = g1 - COLOR_PALETTE[cIndex][1];
                int eb = b1 -  COLOR_PALETTE[cIndex][2];
                int k = 0;
                
                if(row + 1 < height && col - 1 > 0) {
                	k = (row + 1) * width + col - 1;
                    r1 = (inPixels[k] >> 16) & 0xff;
                    g1 = (inPixels[k] >> 8) & 0xff;
                    b1 = inPixels[k] & 0xff;
                    r1 += (int)(er * kernelData[0]);
                    g1 += (int)(eg * kernelData[0]);
                    b1 += (int)(eb * kernelData[0]);
                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);
                }
                
                if(col + 1 < width) {
                	k = row * width + col + 1;
                    r1 = (inPixels[k] >> 16) & 0xff;
                    g1 = (inPixels[k] >> 8) & 0xff;
                    b1 = inPixels[k] & 0xff;
                    r1 += (int)(er * kernelData[3]);
                    g1 += (int)(eg * kernelData[3]);
                    b1 += (int)(eb * kernelData[3]);
                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);
                }
                
                if(row + 1 < height) {
                	k = (row + 1) * width + col;
                    r1 = (inPixels[k] >> 16) & 0xff;
                    g1 = (inPixels[k] >> 8) & 0xff;
                    b1 = inPixels[k] & 0xff;
                    r1 += (int)(er * kernelData[1]);
                    g1 += (int)(eg * kernelData[1]);
                    b1 += (int)(eb * kernelData[1]);
                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);
                }
                
                if(row + 1 < height && col + 1 < width) {
                	k = (row + 1) * width + col + 1;
                    r1 = (inPixels[k] >> 16) & 0xff;
                    g1 = (inPixels[k] >> 8) & 0xff;
                    b1 = inPixels[k] & 0xff;
                    r1 += (int)(er * kernelData[2]);
                    g1 += (int)(eg * kernelData[2]);
                    b1 += (int)(eb * kernelData[2]);
                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);
                }
        	}
        }
        setRGB( dest, 0, 0, width, height, outPixels );
        return dest;
	}
3.       选择性灰度算法

计算选择的颜色与像素灰度颜色之间的几何距离值,跟阈值比较决定是否像素点为灰度

值,可以得到一些让你意想不到的图像处理效果!

图像效果 (Main Color = GREEN, 阈值 = 200)

原图:

处理以后

 关键代码:

	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();

        if ( dest == null )
        	dest = createCompatibleDestImage( src, null );

        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        getRGB( src, 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 * (double)tr + 0.587 * (double)tg + 0.114 * (double)tb);
                double distance = getDistance(tr, tg, tb);
                if(distance < threshold) {
                	double k = distance / threshold;
                	int[] rgb = getAdjustableRGB(tr, tg, tb, gray, (float)k);
                	tr = rgb[0];
                	tg = rgb[1];
                	tb = rgb[2];
                	outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
                } else {
                	outPixels[index] = (ta << 24) | (gray << 16) | (gray << 8) | gray;                	
                }
                
        	}
        }
        setRGB( dest, 0, 0, width, height, outPixels );
        return dest;
	}

创建新的目标Image
    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
        if ( dstCM == null )
            dstCM = src.getColorModel();
        return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
    }


12
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

图像处理--灰度化,二值化与反色

灰度化    在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有以下...
  • evsqiezi
  • evsqiezi
  • 2012-08-24 20:34
  • 14189

数字图像处理之灰度化

囧,ADK还要更新一大截。所以我还是接着写吧,接下来是数字图像的相关文章,全部使用Python实现。     首先讲的是灰度化。     开始,我们先讲讲什么是灰度。     大家都知道,一幅图片有很...
  • Geng19930909
  • Geng19930909
  • 2013-11-24 17:09
  • 2603

图像处理算法

  • 2012-11-25 10:31
  • 10.59MB
  • 下载

图像基本处理算法的简单实现(三)

原文地址链接 书内叙述的细化算法: /** * 对二值化Bitmap进行细化运算后返回 * * 采用“精通Visual.Cpp数字图像处理典型算法及实现(第2版)”内叙述的细化算法...
  • darkdragonking
  • darkdragonking
  • 2014-12-09 15:53
  • 317

图像灰度化方法总结及其VC实现

最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都是从一个图像处理初学者的角度来总结目标检测定位过程中所应用到的各种常见的算法,尤其是解决算法实现过程中由于粗心大意或者C编程基...
  • likezhaobin
  • likezhaobin
  • 2011-10-31 17:16
  • 22931

图像的灰度化原理和实现

一、图像的灰度化处理的基本原理将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(2...
  • chenamo9651
  • chenamo9651
  • 2006-07-06 23:31
  • 28123

图像处理算法

  • 2013-10-18 01:03
  • 37.56MB
  • 下载

图像的灰度化处理的基本原理

图像的灰度化处理的基本原理 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(2...
  • redfivehit
  • redfivehit
  • 2015-12-15 17:25
  • 3447

图像灰度化方法

目前,在图像处理过程中,最常用的彩色图片格式有RGB,HSV、YUV以及HLS三种。以下分别对这三种格式的彩色图像进行灰度化实现。 1、RGB空间图像      定义于RGB空间的彩色图,...
  • WiseClown
  • WiseClown
  • 2014-08-11 19:26
  • 4127
    个人说明
    独立图像处理开发者
    图像处理与对象识别算法外包
    OCR与美化类滤镜开发
    安卓与IOS图像类应用开发

    OpenCV学习群:376281510

    学习图像处理技术关注
    公众号:【OpenCV学堂】
    个人联系方式:
    QQ: 57558865
    个人资料
    • 访问:2807636次
    • 积分:23896
    • 等级:
    • 排名:第322名
    • 原创:257篇
    • 转载:1篇
    • 译文:2篇
    • 评论:1392条
    博客专栏
    最新评论