开发者社区> 毛毛虫的爹> 正文

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

简介: <p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">介绍几种特殊的灰度算法滤镜,将彩色图像转换为灰度图像。其中涉及到的有基于阈值的图</p> <p style="color: rgb(51, 51, 51); font-family: Arial; font-siz
+关注继续查看

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

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

 

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

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

 

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

处理流程:

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

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

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

色)

图像效果:


关键代码:

[java] view plaincopy
  1. public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  2.     int width = src.getWidth();  
  3.        int height = src.getHeight();  
  4.   
  5.        if ( dest == null )  
  6.            dest = createCompatibleDestImage( src, null );  
  7.        src = super.filter(src, dest);  
  8.   
  9.        int[] inPixels = new int[width*height];  
  10.        int[] outPixels = new int[width*height];  
  11.        getRGB(src, 00, width, height, inPixels );  
  12.          
  13.        // calculate means of pixel    
  14.        int index = 0;    
  15.        double redSum = 0, greenSum = 0, blueSum = 0;    
  16.        double total = height * width;    
  17.        for(int row=0; row<height; row++) {    
  18.            int ta = 0, tr = 0, tg = 0, tb = 0;    
  19.            for(int col=0; col<width; col++) {    
  20.                index = row * width + col;    
  21.                ta = (inPixels[index] >> 24) & 0xff;    
  22.                tr = (inPixels[index] >> 16) & 0xff;    
  23.                tg = (inPixels[index] >> 8) & 0xff;    
  24.                tb = inPixels[index] & 0xff;    
  25.                redSum += tr;    
  26.                greenSum += tg;    
  27.                blueSum +=tb;    
  28.            }    
  29.        }  
  30.        int means = (int)(redSum / total);  
  31.        System.out.println(" threshold average value = " + means);  
  32.          
  33.        // dithering   
  34.        for(int row=0; row<height; row++) {  
  35.         int ta = 0, tr = 0, tg = 0, tb = 0;  
  36.         for(int col=0; col<width; col++) {  
  37.             index = row * width + col;  
  38.             ta = (inPixels[index] >> 24) & 0xff;  
  39.                tr = (inPixels[index] >> 16) & 0xff;  
  40.                tg = (inPixels[index] >> 8) & 0xff;  
  41.                tb = inPixels[index] & 0xff;  
  42.                if(tr >=means) {  
  43.                 tr = tg = tb = 255;  
  44.                } else {  
  45.                 tr = tg = tb = 0;  
  46.                }  
  47.                outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  48.                  
  49.         }  
  50.        }  
  51.        setRGB( dest, 00, width, height, outPixels );  
  52.        return dest;  
  53. }  

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

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

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

图像效果:

关键代码:

[java] view plaincopy
  1. @Override  
  2. public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  3.     int width = src.getWidth();  
  4.        int height = src.getHeight();  
  5.   
  6.        if ( dest == null )  
  7.         dest = createCompatibleDestImage( src, null );  
  8.        src = super.filter(src, dest);  
  9.   
  10.        int[] inPixels = new int[width*height];  
  11.        int[] outPixels = new int[width*height];  
  12.        getRGB( src, 00, width, height, inPixels );  
  13.        int index = 0;  
  14.        for(int row=0; row<height; row++) {  
  15.         for(int col=0; col<width; col++) {  
  16.             index = row * width + col;  
  17.                int r1 = (inPixels[index] >> 16) & 0xff;  
  18.                int g1 = (inPixels[index] >> 8) & 0xff;  
  19.                int b1 = inPixels[index] & 0xff;  
  20.                int cIndex = getCloseColor(r1, g1, b1);  
  21.                outPixels[index] = (255 << 24) | (COLOR_PALETTE[cIndex][0] << 16) | (COLOR_PALETTE[cIndex][1] << 8) | COLOR_PALETTE[cIndex][2];  
  22.                int er = r1 - COLOR_PALETTE[cIndex][0];  
  23.                int eg = g1 - COLOR_PALETTE[cIndex][1];  
  24.                int eb = b1 -  COLOR_PALETTE[cIndex][2];  
  25.                int k = 0;  
  26.                  
  27.                if(row + 1 < height && col - 1 > 0) {  
  28.                 k = (row + 1) * width + col - 1;  
  29.                    r1 = (inPixels[k] >> 16) & 0xff;  
  30.                    g1 = (inPixels[k] >> 8) & 0xff;  
  31.                    b1 = inPixels[k] & 0xff;  
  32.                    r1 += (int)(er * kernelData[0]);  
  33.                    g1 += (int)(eg * kernelData[0]);  
  34.                    b1 += (int)(eb * kernelData[0]);  
  35.                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);  
  36.                }  
  37.                  
  38.                if(col + 1 < width) {  
  39.                 k = row * width + col + 1;  
  40.                    r1 = (inPixels[k] >> 16) & 0xff;  
  41.                    g1 = (inPixels[k] >> 8) & 0xff;  
  42.                    b1 = inPixels[k] & 0xff;  
  43.                    r1 += (int)(er * kernelData[3]);  
  44.                    g1 += (int)(eg * kernelData[3]);  
  45.                    b1 += (int)(eb * kernelData[3]);  
  46.                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);  
  47.                }  
  48.                  
  49.                if(row + 1 < height) {  
  50.                 k = (row + 1) * width + col;  
  51.                    r1 = (inPixels[k] >> 16) & 0xff;  
  52.                    g1 = (inPixels[k] >> 8) & 0xff;  
  53.                    b1 = inPixels[k] & 0xff;  
  54.                    r1 += (int)(er * kernelData[1]);  
  55.                    g1 += (int)(eg * kernelData[1]);  
  56.                    b1 += (int)(eb * kernelData[1]);  
  57.                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);  
  58.                }  
  59.                  
  60.                if(row + 1 < height && col + 1 < width) {  
  61.                 k = (row + 1) * width + col + 1;  
  62.                    r1 = (inPixels[k] >> 16) & 0xff;  
  63.                    g1 = (inPixels[k] >> 8) & 0xff;  
  64.                    b1 = inPixels[k] & 0xff;  
  65.                    r1 += (int)(er * kernelData[2]);  
  66.                    g1 += (int)(eg * kernelData[2]);  
  67.                    b1 += (int)(eb * kernelData[2]);  
  68.                    inPixels[k] = (255 << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1);  
  69.                }  
  70.         }  
  71.        }  
  72.        setRGB( dest, 00, width, height, outPixels );  
  73.        return dest;  
  74. }  
3.       选择性灰度算法

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

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

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

原图:

处理以后

 关键代码:

[java] view plaincopy
  1. public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  2.     int width = src.getWidth();  
  3.        int height = src.getHeight();  
  4.   
  5.        if ( dest == null )  
  6.         dest = createCompatibleDestImage( src, null );  
  7.   
  8.        int[] inPixels = new int[width*height];  
  9.        int[] outPixels = new int[width*height];  
  10.        getRGB( src, 00, width, height, inPixels );  
  11.        int index = 0;  
  12.        for(int row=0; row<height; row++) {  
  13.         int ta = 0, tr = 0, tg = 0, tb = 0;  
  14.         for(int col=0; col<width; col++) {  
  15.             index = row * width + col;  
  16.             ta = (inPixels[index] >> 24) & 0xff;  
  17.                tr = (inPixels[index] >> 16) & 0xff;  
  18.                tg = (inPixels[index] >> 8) & 0xff;  
  19.                tb = inPixels[index] & 0xff;  
  20.                int gray = (int)(0.299 * (double)tr + 0.587 * (double)tg + 0.114 * (double)tb);  
  21.                double distance = getDistance(tr, tg, tb);  
  22.                if(distance < threshold) {  
  23.                 double k = distance / threshold;  
  24.                 int[] rgb = getAdjustableRGB(tr, tg, tb, gray, (float)k);  
  25.                 tr = rgb[0];  
  26.                 tg = rgb[1];  
  27.                 tb = rgb[2];  
  28.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  29.                } else {  
  30.                 outPixels[index] = (ta << 24) | (gray << 16) | (gray << 8) | gray;                      
  31.                }  
  32.                  
  33.         }  
  34.        }  
  35.        setRGB( dest, 00, width, height, outPixels );  
  36.        return dest;  
  37. }  

[java] view plaincopy
  1. 创建新的目标Image  
[java] view plaincopy
  1. public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {  
  2.     if ( dstCM == null )  
  3.         dstCM = src.getColorModel();  
  4.     return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);  
  5. }  

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)
项目实战:Qt+OpenCV图像处理与识别算法平台(持续更新,当前v1.7.0)
161 0
【Matlab】改进的灰度世界算法
水下图像改进的灰色世界算法,对红蓝通道的衰减进行了适当补偿
166 0
OpenCV3 自动白平衡:灰度世界和完美反射算法
最近加入了一个无人机团队,任务是参加第六届国际无人机飞行器创新大奖赛(UAVGP)。由于需要跑视觉算法,团队买了块英伟达的TX2(壕...)。我做的方案是用色域分割,但是室外环境变化可能会比较大(冷暖,亮暗),所以需要用到白平衡算法让图片直方图保持正常。
4635 0
Win8Metro(C#)数字图像处理--2.31灰度拉伸算法
原文:Win8Metro(C#)数字图像处理--2.31灰度拉伸算法  [函数名称] 灰度拉伸函数GrayStretchProcess(WriteableBitmap src) [算法说明]   直方图灰度拉伸也叫做对比度拉伸,是一种特殊的线性点运算,使用的是分段线性变换函数,它的主要思想是提高图像灰度级的动态范围;它的作用是扩展图像的直方图,使其充满整个灰度等级的范围内,从而改善输出图像。
1523 0
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法) 基本原理 均值法,选择的阈值是局部范围内像素的灰度均值(gray mean),该方法的一个变种是用常量C减去均值Mean,然后根据均值实现如下操作: pixel = (pixel > (mean - c)) ? object : background 其中默认情况下参数C取值为0。
1445 0
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
图像处理之积分图应用三(基于NCC快速相似度匹配算法) 基于Normalized cross correlation(NCC)用来比较两幅图像的相似程度已经是一个常见的图像处理手段。在工业生产环节检测、监控领域对对象检测与识别均有应用。
2595 0
图像处理之积分图应用一(半径无关的快速模糊算法)
图像处理之积分图像应用一(半径无关的快速模糊算法) 一:基本原理概述 传统的图像空间域卷积模糊算法,当窗口大小改变时卷积模糊时间也会变化,而且随着窗口尺寸越大计算量也越大,算法运行时间约越长。在很多时候无法满足实时性要求。
1361 0
图像处理之Zhang Suen细化算法
在二值图像处理特别是OCR识别与匹配中,都要通过对字符进行细化以便获得图像的骨架,通过zhang-suen细化算法获得图像,作为图像的特征之一,常用来作为识别或者模式匹配。 一:算法介绍 Zhang-Suen细化算法通常是一个迭代算法,整个迭代过程分为两步: Step One:循环所有前景像素点,对符合如下条件的像素点标记为删除: 1.
2138 0
图像处理之基于泛红算法的二值图像内部区域填充
图像处理之基于泛红算法的二值图像内部区域填充 一:基本原理 在二值图像处理中有个常用的操作叫做Hole Fill意思是填充所有封闭区域的内部,这种算法在二值图像基础上的对象识别与提取有很大作用。基于泛红填充算法实现二值图像内部区域填充是一直快速填充算法。
869 0
+关注
毛毛虫的爹
好好学习,天天向上
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
阿里技术参考图册-算法篇
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多