Java中图像锐化操作的方法详解

 更新时间:2020年11月09日 11:02:52   作者:feng之锋  
这篇文章主要给大家介绍了关于Java中图像锐化操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、该图像锐化的思想:

本文的图像锐化是将图像中的R,G,B的值分别从原图像中提出,然后将分别将这三个R,G,B的值分别与卷积核进行卷积,最终再将最后的三个卷积的结果合成为一个像素值,从而实现图像的锐化效果。

二、整体的图像锐化的代码为:

package com.yf1105;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class ImageTest extends JFrame{
	
	public static void main(String[] args) {
		new ImageTest();
	}
	public ImageTest() {
		
		setSize(1000,700);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		int[][] rgbOfImg = getImagePixel("image/3.jpg");
		test(g, "锐化",rgbOfImg.length, rgbOfImg[0].length, rgbOfImg);
//		g.drawImage(new ImageIcon("img/hk.jpg").getImage(), 0, 0, null);
	}
	
	
	public void test(Graphics graphics,String text,int width,int height,int[][] rgbOfImg) {
		int[][] R ,G ,B;
		int size=3;
		//对于不同的功能设置不同大小的矩阵
//		if(text.equals("锐化")){size = 5;}	
		//锐化卷积核
		double[][] sharpening = {{-1,-1,-1},{-1,9,-1},{-1,-1,-1}};
//		float[][] sharpening = { { -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1 }, { -1, -1, 25, -1, -1 },
//				{ -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1 } };
		//下面开始搞卷积算法
		//初始化rgb数组
		R = new int[size][size];
		G = new int[size][size];
		B = new int[size][size];
		//对应3*3的像素格子进行卷积计算
		for(int x = 0;x < width-size+1;x++){
			for(int y = 0;y < height-size+1;y++){
			//设置三个值分别存储r,g,b的特征值,一定要在循环内部进行初始化0,这样才能每次有不同的值
				int resultOfR = 0;
				int resultOfG = 0;
				int resultOfB = 0;
				//将格子的rgb值都取出,便于之后的卷积操作
				for(int j = 0;j <size;j++){
					for(int i = 0;i < size;i++){
						//将该点的RGB信息取出,放到变量中待操作
						int argb = rgbOfImg[x][y];
						
						//分段获取其R,G,B信息
						//int变量共4位32字节,0位对应透明度(A),1位对应R值,2位对应G值,3位对应B值
						//>>操作:将二进制代码向右移动,左边空位根据符号补充,正号为0,负号为1,右边超过范围的全部舍弃
						//&:二进制位与运算符,只有两个变量对应值均为1时该位才返回1,0xff表示全为1的十六进制数(11111111),因此任何与0xff进行位与的结果均为其本身
						//先移位后取位与可以将不同值对应的位信息取出,位与的意义是只取32字节的后8字节
						R[i][j] = argb>>16 & 0xff;
						G[i][j] = argb>>8 & 0xff;
						B[i][j] = argb  & 0xff;
					}
				}
				if(text.equals("锐化")){
					//分别对R,G,B进行卷积操作,对应相乘后加起来
					for(int j = 0;j < size;j++){
						for(int i = 0;i < size;i++){
							resultOfR += (int)(sharpening[i][j]*R[i][j]);
						}	
					}
					for(int i = 0;i < size;i++){
						for(int j = 0;j < size;j++){
							resultOfG += (int)(sharpening[i][j]*G[i][j]);
		
						}
					}				
					for(int i = 0;i < size;i++){
						for(int j = 0;j < size;j++){
							resultOfB += (int)(sharpening[i][j]*B[i][j]);
						}
					}
				}
				//如果超过了rgb的界限(0-255),将其按照最大值或最小值处理
				if(resultOfR > 255)resultOfR = 255;
				if(resultOfR < 0)resultOfR = 0;
				if(resultOfG > 255)resultOfG = 255;
				if(resultOfG < 0)resultOfG = 0;
				if(resultOfB > 255)resultOfB = 255;
				if(resultOfB < 0)resultOfB = 0;
				//根据该rgb值创建颜色对象
				Color color = new Color(resultOfR, resultOfG, resultOfB);
				//设置颜色,其中graphics是图像的画布(见BufferedImage类与Graphics类)
				graphics.setColor(color);
				//画像素点(drawline用来画线,这里的起始与终点都是同一点,因此可以用来画像素点)
				//size/2用来将像素点赋到中心元上
				graphics.drawLine(x+size/2, y+size/2, x+size/2, y+size/2);
				}
		}

	}
	
	// 将图片数据 读到数组中
		public int[][] getImagePixel(String image) {
			BufferedImage bi = null;
			File file = new File(image);

			try {
				bi = ImageIO.read(file);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			int w = bi.getWidth();
			int h = bi.getHeight();
			int imgindex[][] = new int[w][h];

			for (int i = 0; i < w; i++) {
				for (int j = 0; j < h; j++) {
					int rgb = bi.getRGB(i, j);
					imgindex[i][j] = rgb;
					System.out.print(" " + rgb);
				}
				System.out.println();
			}
			return imgindex;

		}
}

输出结果:

虽然这个与原图的差别并不大,可能由于卷积核选择的原因。

三、关键代码的解读

该段代码主要是要去取出RGB图像的R,G,B值,然后分别对其R,G,B值分别进行卷积操作,然后将卷积后的结果再重新整合成一个int的像素值,从而就实现了图像的锐化处理。

当时看这段代码的时候,发现这部分不是很懂,代码如下:

R[i][j] = argb>>16 & 0xff;
G[i][j] = argb>>8 & 0xff;
B[i][j] = argb  & 0xff;

不过仔细分析了一下位运算和与运算,我发现这段代码就是在分别取出R,G,B的值,因为int类的像素值中是包括了a,r,g,b四个值,int是32位的,则这四个数按顺序存在int中,每个数占8位。所以r对应得二进制需要去移动16位才能与oxff(即1111 1111)进行与运算,b对应得二进制需要去移动8位才能与oxff(即1111 1111)进行与运算,g就直接与oxff(即1111 1111)做与运算即可,虽然这样表达有点难理解,那就看下面的示意图吧:

总结

到此这篇关于Java中图像锐化操作的文章就介绍到这了,更多相关Java图像锐化操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot之bootstrap和application的区别解读

    SpringBoot之bootstrap和application的区别解读

    这篇文章主要介绍了SpringBoot之bootstrap和application的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java线程中断的本质深入理解

    Java线程中断的本质深入理解

    Java的中断是一种协作机制。也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己,本文将详细介绍,需要了解的朋友可以参考下
    2012-12-12
  • Java定时器Timer与TimerTask的使用详解

    Java定时器Timer与TimerTask的使用详解

    这篇文章主要介绍了Java定时器Timer与TimerTask的使用详解,在JDK类库中Timer主要负责计划任务的功能,也就是在指定时间执行某一任务,执行时候会在主线程之外起一个单独的线程执行指定的任务,该类主要是设置任务计划,但封装的类是TimerTask类,需要的朋友可以参考下
    2023-10-10
  • Java面向对象之包装类的用途与实际使用

    Java面向对象之包装类的用途与实际使用

    所谓包装类,就是能够直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类,本文我们来深入探索一下Java包装类的相关内容,需要的朋友可以参考下
    2022-03-03
  • 新手学习JQuery基本操作和使用案例解析

    新手学习JQuery基本操作和使用案例解析

    这篇文章主要介绍了新手学习JQuery基本操作和使用案例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java Mybatis使用resultMap时,属性赋值顺序错误的巨坑

    Java Mybatis使用resultMap时,属性赋值顺序错误的巨坑

    这篇文章主要介绍了Java Mybatis使用resultMap时,属性赋值顺序错误的巨坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • springboot项目以jar包运行的操作方法

    springboot项目以jar包运行的操作方法

    公司一个springboot项目本来是打war包的,突然要改为打jar包,不知所措了,纠结该如何操作呢,折腾半天终于搞定了,下面把解决方案分享给大家,对springboot打jar包方式感兴趣的朋友一起看看吧
    2021-06-06
  • springboot过滤器执行两次的解决及跨域过滤器问题

    springboot过滤器执行两次的解决及跨域过滤器问题

    这篇文章主要介绍了springboot过滤器执行两次的解决及跨域过滤器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • SpringBoot整合Redis实现缓存分页数据查询功能

    SpringBoot整合Redis实现缓存分页数据查询功能

    类似淘宝首页,这些商品是从数据库中查出来的吗,答案肯定不是,本文我们就通过一个案例实操一下,首页热点数据怎么放到Redis中去查询,感兴趣的同学可以参考一下
    2023-06-06
  • 聊聊Spring AOP @Before @Around @After等advice的执行顺序

    聊聊Spring AOP @Before @Around @After等advice的执行顺序

    这篇文章主要介绍了聊聊Spring AOP @Before @Around @After等advice的执行顺序,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论