java的图像处理
在java的学习中有一块非常重要的知识点,就是图像的处理。本篇主要介绍几种滤镜,卷积的是使用以及简单的二维码制作过程。
1滤镜
1.1素描
读取图片的rgb值放在二维数组中,分别获取红绿蓝的值将其平均所展示出来的图像即为灰度图像
BufferedImage buffimgs = new BufferedImage(imgdata.length,imgdata[0].length, BufferedImage.TYPE_INT_ARGB);
Graphics bgs = buffimgs.getGraphics();
for (int i = 0;i<imgdata.length;i++){
for(int j = 0 ;j<imgdata[i].length;j++){
int rgbvalue = imgdata[i][j];
int red = rgbvalue >> 16 & 0xFF;
int green = rgbvalue >> 8 & 0xFF;
int blue = rgbvalue >> 0 & 0xFF;
int gray = (int) ((red+ green + blue)/3);
Color c = new Color(gray,gray,gray);
bgs.setColor(c);
bgs.fillRect(i,j,1,1);
}
}
list.add(buffimgs);
g.drawImage(buffimgs,0,100,null);
1.2马赛克
读取图片时每隔5个像素点取一个,画图时画长宽为5像素点的矩形,所展示出来的图片。(像素间隔可自行取,间隔越大马赛克越重)
BufferedImage buffimgm = new BufferedImage(imgdata.length, imgdata[0].length, BufferedImage.TYPE_INT_ARGB);
Graphics bgm = buffimgm.getGraphics();
for (int i = 0;i<imgdata.length;i+=5){
for(int j = 0 ;j<imgdata[i].length;j+=5){
int rgbvalue = imgdata[i][j];
//buffimg.setRGB(i, j, rgbvalue);
int red = rgbvalue >> 16 & 0xFF;
int green = rgbvalue >> 8 & 0xFF;
int blue = rgbvalue >> 0 & 0xFF;
Color c = new Color(red,green,blue);
bgm.setColor(c);
bgm.fillRect(i,j,5,5);
}
}
list.add(buffimgm);
g.drawImage(buffimgm,0,100,null);
1.3二值化
取红绿蓝三个的平均值,判断该值是否大于135,如果是画白色,如果不是画黑色。所展示出来的效果就是二值化效果。
BufferedImage buffimge = new BufferedImage(imgdata.length, imgdata[0].
Graphics bge = buffimge.getGraphics();
for (int i = 0;i<imgdata.length;i++){
for(int j = 0 ;j<imgdata[i].length;j++){
int rgbvalue = imgdata[i][j];
//buffimg.setRGB(i, j, rgbvalue);
int red = rgbvalue >> 16 & 0xFF;
int green = rgbvalue >> 8 & 0xFF;
int blue = rgbvalue >> 0 & 0xFF;
int gray = (red+green+blue)/3;
if(gray<135){
bge.setColor(Color.black);
}
else{
bge.setColor(Color.white);
}
bge.fillRect(i,j,1,1);
}
}
list.add(buffimge);
g.drawImage(buffimge,0,100,null);
2卷积
卷积是分析数学中一种重要的运算。对于图像的卷积简单理解就是讲图像离散成一个二维数组,使用相应的卷积核通过该二维数组的没有个点,卷积核与卷积核大小的数组的数组一一相乘在一起累加,形成的新的二维数组。
具体卷积代码如下
public ArrayList<int[][]> getRes(int[][] arrImage){
int[][] arrRed = new int[arrImage.length][arrImage[0].length];
int[][] arrGreen = new int[arrImage.length][arrImage[0].length];
int[][] arrBlue = new int[arrImage.length][arrImage[0].length];
for (int i = 0; i < arrImage.length; i++) {
for (int j = 0; j < arrImage[0].length; j++) {
int rgbValue = arrImage[i][j];
int red = rgbValue >> 16 & 0xFF;
int green = rgbValue >> 8 & 0xFF;
int blue = rgbValue >>0 & 0xFF;
arrRed[i][j]=red;
arrGreen[i][j]=green;
arrBlue[i][j]=blue;
}
}
ArrayList<int[][]> list = new ArrayList<>();
list.add(convolusion(arrRed));
list.add(convolusion(arrGreen));
list.add(convolusion(arrBlue));
return list;
}
int[][] jj = {{-1,-1,-1},{-1,9,-1},{-1,-1,-1}};
public int[][] convolusion(int[][] arr){
int[][] dj= new int[arr.length-2][arr[0].length-2];
for (int i = 1; i < arr.length-1; i++) {
for (int j = 1; j < arr[0].length-1; j++) {
int[][] temp = {{arr[i-1][j-1],arr[i-1][j],arr[i-1][j+1]},{arr[i][j-1],arr[i][j],arr[i][j+1]},{arr[i+1][j-1],arr[i+1][j],arr[i+1][j+1]}};
int m=0;
for (int k = 0; k < jj.length; k++) {
for (int l = 0; l < jj[0].length; l++) {
m+=temp[k][l]*jj[k][l];
}
}
if(m>255) m=255;
if(m<0)m=0;
dj[i-1][j-1]=m;
}
}
return dj;
}
将图像的二维数组分成红蓝绿三原色进行分别卷积再以集合的形式返回。
简单二维码的制作与读取
每一个char类型占两个字节,每个字节占8比特,也就是说一个char类型占16比特。基于上述理论,我们可以将字符串转化为char类型的数组,再将char类型转换为01的二进制类型。0画白格1画黑格,这样就可以模拟出简单的二维码。
制作:
public static int[][] makeQR(String word){
char[] chr = word.toCharArray();
int[][] binarr = new int[chr.length][16];
for(int i = 0;i<chr.length;i++){
String binstr = Integer.toBinaryString(chr[i]);
int leng = binstr.length();
while(leng<16){
binstr="0"+binstr;
leng++;
}
for(int j = 0;j<16;j++){
binarr[i][j]=binstr.charAt(j);
}
}
return binarr;
}
读取:
等间隔读取二维码并判断,如果是白色记为0,如果是黑色记为1返回一个二维数组
public static int[][] getQRImg(String path){
File file = new File(path);
BufferedImage bi = null;
try {
bi= ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
int w = bi.getWidth()/10;
int h =bi.getHeight()/10;
int[][] buffimg = new int[h][w];
for (int i = 0; i < buffimg.length; i++) {
for (int j = 0; j < buffimg[i].length; j++) {
buffimg[i][j]=bi.getRGB(j*10+5,i*10+5);
}
}
return buffimg;
}
public static char[][] getWord(int[][] binarr){
char[][] chr =new char[binarr.length][binarr[0].length];
for (int i = 0; i < binarr.length; i++) {
for (int j = 0; j < binarr[0].length; j++) {
int rgbvalue = binarr[i][j];
int red = rgbvalue >> 16 & 0xFF;
if(red>200){
chr[i][j]=48;
}
else{
chr[i][j]=49;
}
}
}
return chr;
int[][] img = GetImg.getQRImg("C:\\Users\\dell\\Desktop\\121.png");
char[][] chr = ReQRcode.getWord(img);
String word = ReQRcode.getString(chr);
System.out.println(word);