图片消除锯齿和图片锐化

1 图片消除锯齿

图片在缩小过程中已办都会产生一定的锯齿感,最好在缩放的过程中设置一定的消除锯齿效果

// 消除锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

或

image = image.getScaledInstance(width,height,BufferedImage.SCALE_SMOOTH)
g.drawImage(image,x,y,observer);

在压缩过程中一般会有一些失真,需要的话可以加一点锐化,但是锐化算法运行的比较慢,相对于图片缩放的时间,所以看选择使用,如果对时间处理要求高,可以不加

2 图片锐化

锐化使用一阶微分梯度锐化或者拉普拉斯锐化都可以,具体代码看
java图像处理之拉普拉斯锐化和一阶微分梯度锐化

在调用锐化方法获取算好的锐化图像后,叠加到图片上最好使用0.2f的透明度覆盖,否则锐化程度很严重,看起来更加失真

    BufferedImage imageSharpen = ImageSharpen.lapLaceSharpDeal(destImage);
    //设置为透明覆盖
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.2f));
    //在背景图片上添加锐化的边缘
    g.drawImage(imageSharpen, 0, 0, imageSharpen.getWidth(), imageSharpen.getHeight(), null);
    // 释放对象 透明度设置结束
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

3 锐化工具类

public class ImageSharpen {

        /**
         * 图像锐化 二阶微分锐化,拉普拉斯算子 定义一个3*3滤波器,计算中心像素与上下左右四个像素差值
         *
         * @param image
         */
        public static BufferedImage lapLaceSharpDeal(BufferedImage image) {
            BufferedImage tempImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
//            Stream.iterate(1, item -> item+1).limit(image.getWidth()-2)
//                    .parallel().forEach( i -> {
            for (int i = 1; i < image.getWidth() - 1; i++) {
                for (int j = 1; j < image.getHeight() - 1; j++) {
                    int rgb = image.getRGB(i, j);
                    int rgb1 = image.getRGB(i - 1, j);
                    int rgb2 = image.getRGB(i + 1, j);
                    int rgb3 = image.getRGB(i, j - 1);
                    int rgb4 = image.getRGB(i, j + 1);
                    int[] R = new int[]{(rgb1 >> 16) & 0xff, (rgb2 >> 16) & 0xff, (rgb3 >> 16) & 0xff,
                            (rgb4 >> 16) & 0xff, (rgb >> 16) & 0xff};
                    int[] G = new int[]{(rgb1 >> 8) & 0xff, (rgb2 >> 8) & 0xff, (rgb3 >> 8) & 0xff, (rgb4 >> 8) & 0xff,
                            (rgb >> 8) & 0xff};
                    int[] B = new int[]{rgb1 & 0xff, rgb2 & 0xff, rgb3 & 0xff, rgb4 & 0xff, rgb & 0xff};
                    double dR = R[0] + R[1] + R[2] + R[3] - 4 * R[4];
                    double dG = G[0] + G[1] + G[2] + G[3] - 4 * G[4];
                    double dB = B[0] + B[1] + B[2] + B[3] - 4 * B[4];

                    double r = R[4] - dR;
                    double g = G[4] - dG;
                    double b = B[4] - dB;

                    rgb = (255 & 0xff) << 24 | (clamp((int) r) & 0xff) << 16 | (clamp((int) g) & 0xff) << 8
                            | (clamp((int) b) & 0xff);
                    tempImage.setRGB(i, j, rgb);
                }
            }
            return tempImage;
        }

        /**
         * 一阶微分梯度锐化
         */
        public static BufferedImage degreeSharpDeal(BufferedImage image) {
            BufferedImage tempImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
            for (int i = 1; i < image.getWidth() - 1; i++) {
                for (int j = 1; j < image.getHeight() - 1; j++) {
                    List<Integer> rList = new ArrayList<>();
                    List<Integer> gList = new ArrayList<>();
                    List<Integer> bList = new ArrayList<>();
                    for (int x = -1; x < 2; x++) {
                        for (int y = -1; y < 2; y++) {
                            int rgb = image.getRGB(i + x, j + y);
                            int R = (rgb >> 16) & 0xff;
                            int G = (rgb >> 8) & 0xff;
                            int B = rgb & 0xff;
                            rList.add(R);
                            gList.add(G);
                            bList.add(B);
                        }
                    }
                    int r = getResult(rList);
                    int g = getResult(gList);
                    int b = getResult(bList);
                    r = rList.get(4) + r / 4;
                    g = gList.get(4) + g / 4;
                    b = bList.get(4) + b / 4;
                    int rgb = (255 & 0xff) << 24 | (clamp(r) & 0xff) << 16 | (clamp(g) & 0xff) << 8 | (clamp(b) & 0xff);
                    tempImage.setRGB(i, j, rgb);
                }
            }
            return tempImage;
        }

        // 执行一阶微分计算
        private static int getResult(List<Integer> list) {
            int result = Math.abs(list.get(0) + list.get(3) + list.get(6) - list.get(2) - list.get(5) - list.get(8))
                    + Math.abs(list.get(0) + list.get(1) + list.get(2) - list.get(6) - list.get(7) - list.get(8));
            return result;
        }

        // 判断a,r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值
        private static int clamp(int rgb) {
            if (rgb > 255)
                return 255;
            if (rgb < 0)
                return 0;
            return rgb;
        }
    }

4 遗留问题:

ImageSharpen.lapLaceSharpDeal循环一次,取三个点进行计算拉普拉斯微分算子计算灰度突变区域,然后在记录灰度突变区域,本质上等于PS中的高反差保留。因为这个动作比较耗时,想使用多线程来增加处理速度,但是遗憾的是tempImage.setRGB(i, j, rgb)使用的synchronized修饰,所以单独使用多线程是没有用的,后面想到重写BufferedImage的setRGB方法,按照像素点 i和j来作为ConcurrentHashMap的key值,这样可以只锁相同的key,但是后面调试比不重写前耗时更多。各位同学如果有更好的方法可以发出来一起交流。

BufferedImage的setRGB方法源码:

public synchronized void setRGB(int x, int y, int rgb) {
   raster.setDataElements(x, y, colorModel.getDataElements(rgb, null));
}

参考:
基于Graphics2D drawImage图片失真的解决方案
MATLAB图像处理-图片的锐化增强(附代码)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值