图像是由一个个像素点组合而成,图像处理本身实际上是遍历图像的像素点,对像素点的RGB值进行更改,以达到图像处理的目的。
接下来,我们主要介绍一下图片转化为二维像素点数组的方法以及部分图像处理如灰度、二值化、浮雕、去色的实现。
将图片转化为一个二维像素点数组
定义一个方法用来通过图片路径获得图片,并将其拆分为一个二维像素点数组,方便后续对像素点进行处理:
public int[][] getImagepix(String Path){
File file = new File(Path);
BufferedImage Buffimg = null;
try {
Buffimg=ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Buffimg.getHeight();
Buffimg.getWidth();
int num =Math.max(Buffimg.getWidth(), Buffimg.getHeight());
int[][] imgdata = new int[num][num];
for(int i=0;i<num;i++) {
for(int j=0;j<num;j++) {
if(i<Buffimg.getWidth()&&j<Buffimg.getHeight())
imgdata[i][j]=Buffimg.getRGB(i, j);
else imgdata[i][j]=0;
}
}
return imgdata;
}
灰度
灰度处理是通过转灰度的算法改变像素点的RGB值后进行绘制。
这里使用的RGB转灰度算法为Gray = R0.299 + G0.587 + B*0.114。
Graphics bg = buffimg.getGraphics();
int[][] imgdata= getImagepix(Path);
for(int i=0;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
int gray = (int) (0.299 * red + 0.587 * green + 0.114 * blue);
Color newcolor = new Color(gray,gray,gray);
bg.setColor(newcolor);
bg.drawLine(i,j,i,j);
}
}
bg.drawImage(buffimg,0,0,null);
马赛克
通俗来说,实现马赛克的方法就是如何将图像的一个像素点变成一个像素块,即将像素矩阵中的全部像素值统一修改为这个像素点矩阵中任意一个像素点值。本例中,我们将像素矩阵长度与宽度均设置为10,选取像素矩阵左上角的像素点值。
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=0;i<imgdata.length;i=i+10) {
for(int j=0;j<imgdata[i].length;j=j+10) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
Color newcolor = new Color(red,green,blue);
bg.setColor(newcolor);
bg.fillRect(i,j,10,10);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
bg.drawImage(buffimg,0,0,null);
油画
如果是马赛克是利用“画方块”的形式来绘制图像,那么油画就是通过“画圆”的方式。在进行油画处理的时候应该注意的是,“画圆”的半径一定要小于选取的像素矩阵的长度和宽度,否则绘制出来的图像会留白。
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=1;i<imgdata.length;i=i+4) {
for(int j=0;j<imgdata[i].length;j=j+4) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
Color newcolor = new Color(red,green,blue);
bg.setColor(newcolor);
bg.fillOval(i, j, 5, 5);
}
}
bg.drawImage(buffimg,0,0,null);
二值化
顾名思义,二值化就是将图像的全部RGB值转化为两种。对图像进行灰度处理后,我们可以设置一个比较值,区别大于或小于比较值的RGB值。为如本例中将该比较值设置为170,当RGB大于170时赋值255,否则赋值0。
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=1;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
int gray = (int) (0.299 * red + 0.587 * green + 0.114 * blue);
if(gray>170) gray=255;
else gray=0;
Color newcolor = new Color(gray,gray,gray);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
bg.drawImage(buffimg,0,0,null);
浮雕
浮雕是利用卷积过滤器进行图像处理的实现类型之一。
在这里,我们选择的浮雕矩阵为{{-1,-1,0},{-1,0,1},{0,1,1}}。
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
int finalred=0;
int finalblue=0;
int finalgreen=0;
Color[][] colors = new Color[imgdata.length][imgdata.length];
int[][] red = new int[imgdata.length][imgdata.length];
int[][] green = new int[imgdata.length][imgdata.length];
int[][] blue = new int[imgdata.length][imgdata.length];
for(int i=1;i<imgdata.length-1;i++) {
for(int j=1;j<imgdata[i].length-1;j++) {
colors[i-1][j-1] = new Color(imgdata[i-1][j-1]);
colors[i-1][j] = new Color(imgdata[i-1][j]);
colors[i-1][j+1] = new Color(imgdata[i-1][j+1]);
colors[i][j-1] = new Color(imgdata[i][j-1]);
colors[i][j] = new Color(imgdata[i][j]);
colors[i][j+1] = new Color(imgdata[i][j+1]);
colors[i+1][j-1] = new Color(imgdata[i+1][j-1]);
colors[i+1][j] = new Color(imgdata[i+1][j]);
colors[i+1][j+1] = new Color(imgdata[i+1][j+1]);
for(int m=i-1;m<i+2;m++) {
for(int n = j-1;n<j+2;n++) {
red[m][n] = colors[m][n].getRed();
green[m][n] = colors[m][n].getGreen();
blue[m][n] = colors[m][n].getBlue();
}
}
//浮雕矩阵
int [][] maxtrix= {{-1,-1,0},{-1,0,1},{0,1,1}};
for(int k=i-1;k<i+2;k++) {
for(int l=j-1;l<j+2;l++) {
finalred+=red[k][l]*maxtrix[k-(i-1)][l-(j-1)];
finalblue+=red[k][l]*maxtrix[k-(i-1)][l-(j-1)];
finalgreen+=red[k][l]*maxtrix[k-(i-1)][l-(j-1)];
}
}
if(finalred<0) finalred=0;
if(finalred>255) finalred=255;
if(finalblue<0) finalblue=0;
if(finalblue>255) finalblue=255;
if(finalgreen<0) finalgreen=0;
if(finalgreen>255) finalgreen=255;
Color newcolor=new Color(finalred,finalgreen,finalblue);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
bg.drawImage(buffimg,0,0,null);
反向
对图像的RGB值进行反向处理,如
int red = 255-color.getRed();
int blue = 255-color.getBlue();
int green = 255-color.getGreen();
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=0;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
Color color = new Color(imgdata[i][j]);
## 标题 int red = 255-color.getRed();
int blue = 255-color.getBlue();
int green = 255-color.getGreen();
Color newcolor = new Color(red,green,blue);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
去色
将像素点的RGB值统一设置为其中的最大值
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=1;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
int avg = (Math.max(Math.max(red, blue),green)+Math.max(Math.min(red, blue),green))/2;
Color newcolor = new Color(avg,avg,avg);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
bg.drawImage(buffimg,0,0,null);
怀旧
利用怀旧滤镜公式实现图像处理
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
for(int i=1;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
Color color = new Color(imgdata[i][j]);
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
int[] rgb = new int[3];
rgb[0]=(int) (0.393*red+0.769*green+0.189*blue);
rgb[1] = (int) (0.349*red+0.686*green+0.168*blue);
rgb[2] = (int) (0.272*red+0.534*green+0.131*blue);
for(int m=0;m<3;m++) {
if(rgb[m]<0)
rgb[m]=0;
else if(rgb[m]>255)
rgb[m]=255;
}
Color newcolor = new Color(rgb[0],rgb[1],rgb[2]);
buffimg.setRGB(i, j, newcolor.getRGB());
}
}
bg.drawImage(buffimg,0,0,null);
放大镜
将“小圆”变成“大圆”,将某一像素点的圆形范围内的像素点扩大,实现放大效果
Graphics bg = buffimg.getGraphics();
int[][] imgdata = getImagepix(Path);
int[][] newimg = new int[imgdata.length][imgdata.length];
int distance;
int radius=50;
int m=2;
for(int i=0;i<imgdata.length;i++) {
for(int j=0;j<imgdata[i].length;j++) {
distance=(int) Math.sqrt(Math.pow(i-cenx, 2)+Math.pow(j-ceny, 2));
if(distance<radius)
newimg[i][j]=imgdata[(int)(i+cenx)/m][(int)(j+ceny)/m];
else newimg[i][j]=imgdata[i][j];
}
}
for(int i=0;i<newimg.length;i++) {
for(int j=0;j<newimg[i].length;j++) {
Color newcolor = new Color(newimg[i][j]);
buffimg.setRGB(i, j, newcolor.getRGB());
bg.drwaImage(buffimg,0,0,null);