Java 图像处理(线性滤波)

原理简介

        在图像处理中,线性滤波是一种比较基本的处理方式。在进行滤波处理之前,我们首先需要一个滤波矩阵,改矩阵称为卷积核,通常情况下为 3×3、5×5、7×7... 大小的矩阵,这样该卷积核的最中心会有一个元素。

在简单的图像处理中,其一般的处理方式就是对某一个像素及其周围的像素的RGB值与卷积核对应的元素相乘后相加,最后将该值取代原来的像素值RGB值。

        假设左边的矩阵代表着某一张图片,其元素表示的是其对应像素的RGB值,而右边的矩阵则是我们的卷积核。其处理过程就是针对某一像素及其周围像素,例如我们取绿色方框里的像素,然后向其周围取一个大小与卷积核相同的像素矩阵,即红色方框表示的矩阵。用该矩阵与卷积核对应的元素相乘之后求和,最后用该值作为绿色方框位置的像素的RGB值。再重复计算其他像素的RGB值即可。

        可以看出用 3×3 的卷积核滤波之后,原来图片的最外围一圈的像素并没有计算到,但是对于一整张图片来说可以忽略不计。

        还有一点就是在Java中,RGB值是作为一个整体用一个 int 类型的数据进行存储的,所以在进行计算时,要分别对 R、G、B 进行卷积运算,最后将计算后的 R、G、B 值作为对应位置的RGB值。此外还要判断计算过后的 R、G、B 值是否超过了 0 ~ 255 的范围。

示例代码

        在示例中,我们以常见的锐化处理卷积核为例:

 其他类型的卷积核大家可以去查阅相关资料,相关的实例代码如下:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class TextFilter {

    public static void main(String[] args) {

        JFrame jf = new JFrame();   // 创建显示窗体
        jf.setSize(800,800);    // 设置窗体大小
        jf.setLocationRelativeTo(null); // 窗体居中
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置退出进程
        jf.setVisible(true);    // 设置窗体可见

        File file = new File("兵长.jpg"); // 建立图片文件对象
        // 建立缓冲图片
        BufferedImage image = null;
        try {
            image = ImageIO.read(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (image != null){
            sharpen(jf.getGraphics(), image);   // 调用锐化函数并绘出
        }
    }

    // 锐化函数
    public static void sharpen (Graphics g, BufferedImage image){
        BufferedImage sharpenImage = new BufferedImage(image.getWidth(),image.getHeight(),image.getType()); // 建立新的缓冲图片用于保存
        int[][] kernel = {{-1, -1, -1},{-1, 9, -1},{-1, -1, -1}};   // 建立卷积核
        // 循环卷积计算
        for (int i = 0; i < image.getWidth() - kernel.length + 1; i++){
            for (int j = 0; j < image.getHeight() - kernel.length + 1; j++) {
                int red = 0, green = 0, blue = 0;
                for (int m = 0; m < kernel.length; m++) {
                    for (int n = 0; n < kernel.length; n++) {
                        red += (image.getRGB(i + m, j + n) >> 16 & 0xFF) * kernel[m][n];
                        green += (image.getRGB(i + m, j + n) >> 8 & 0xFF) * kernel[m][n];
                        blue += (image.getRGB(i + m, j + n) & 0xFF) * kernel[m][n];
                    }
                }
                // 判断 R、G、B 是否在 0 ~ 255 范围内
                red = red > 255 ? 255 : Math.max(red, 0);
                green = green > 255 ? 255 : Math.max(green, 0);
                blue = blue > 255 ? 255 : Math.max(blue, 0);
                int color = (255 << 24) + (red << 16) + (green << 8) + blue;
                sharpenImage.setRGB(i+kernel.length/2, j+kernel.length/2, color);   // 将计算后的RGB值保存到新图片中
            }
        }
        g.drawImage(sharpenImage, 50, 50, null);    // 绘制新图片
    }

}

锐化效果如下:

原图

锐化处理后 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值