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

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

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


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

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

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

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

 

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

处理流程:

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

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

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

色)

图像效果:

1332663553_3036.png

关键代码:

  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

图像效果: 1332663651_6195.png

关键代码:

  @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)

原图:

image.png

处理以后

image.png

关键代码:

  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);
    }

目录
打赏
0
0
0
0
81
分享
相关文章
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
594 0
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
图像处理之积分图应用三(基于NCC快速相似度匹配算法)
110 0
图像处理之积分图应用二(快速边缘保留滤波算法)
图像处理之积分图应用二(快速边缘保留滤波算法)
52 0
图像处理之积分图应用一(半径无关的快速模糊算法)
图像处理之积分图应用一(半径无关的快速模糊算法)
68 0
图像处理之积分图算法
图像处理之积分图算法
96 2
图像处理之基于泛红算法的二值图像内部区域填充
图像处理之基于泛红算法的二值图像内部区域填充
65 0
基于Adaboost的数据分类算法matlab仿真
本程序基于Adaboost算法进行数据分类的Matlab仿真,对比线性与非线性分类效果。使用MATLAB2022A版本运行,展示完整无水印结果。AdaBoost通过迭代训练弱分类器并赋予错分样本更高权重,最终组合成强分类器,显著提升预测准确率。随着弱分类器数量增加,训练误差逐渐减小。核心代码实现详细,适合研究和教学使用。
基于PSO粒子群优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-LSTM-SAM网络时间序列预测算法。使用Matlab2022a开发,完整代码含中文注释及操作视频。算法结合卷积层提取局部特征、LSTM处理长期依赖、自注意力机制捕捉全局特征,通过粒子群优化提升预测精度。适用于金融市场、气象预报等领域,提供高效准确的预测结果。
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等