图像抖动(加入随机噪声+矩阵有序抖动)Java实现,不使用OpenCV 按照课堂中讲的两种抖动(Dithering)方法,自己编程实现(编程语言不限)。实现方法一:以加入随机噪声的方式保留信息
这2个程序我都是在idea上运行的,在Eclipse上运行不知道会不会出问题,对于学生来说是可以免费使用idea的,可以参考这篇。那么我们可以把图像看作一个函数,那么带有噪声的图像,就可以看作是原始图像函数与噪声函数相加的和。,但如果不是学生的话,如果用eclipse出问题,只能查问题原因或者用idea。当文件夹下面有该图片时,则可以执行程序了,顺利执行完之后就会新生成一个。//这里的noise在
下面这个题我做了好久,老师说用不到OpenCV,所以我觉得应该用编程读取文件的操作,但我又不知道用C++或者Java如何读取图片文件,所以这里对于我来说是一个问题,当我发现读取文件之后,我又不知道怎么对图片的像素进行处理,这又是一个新的问题,所以,经过这2个问题,接触到了自己的知识盲区,也就是我需要掌握的知识,这给我的学习带来了极大的帮助,问题的原因吸引着我,让我有继续学下去的动力,所以大家一定要找到自己热爱的事物,因为你对它有兴趣,你才会主动探索他,这样你也就会越走越远,达到新的高度,从而成为自己心目中的英雄。
方法一:加入随机噪声
加入随机噪声的方法可以这样理解:
如果你把图像看作信号,那么噪声就是干扰信号。我们在采集图像时可能因为各种各样的干扰而引入图像噪声。
那么我们可以把图像看作一个函数,那么带有噪声的图像,就可以看作是原始图像函数与噪声函数相加的和。
f(x,y) = I(x,y)+noise
~~~~
//这里的noise在程序中可以看做是一个没有参数的函数
import java.io.*;
import java.util.*;
import java.security.cert.PolicyNode;
import java.lang.StringBuffer;
import java.util.HashMap;
import java.util.Map.Entry;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Main {
private BufferedImage original;
private void readOriginal() {
File f=new File("original.jpg");//这里新创建了一个对象叫 original.jpg 的文件
try{//读取图片
original=ImageIO.read(f);//然后来到当前目录下面去找是否有这个文件,所以要先在当前文件夹中复制一个名为 original.jpg 的文件,这样才可以找到
} catch (IOException e) {//如果找不到这个图片则抛出异常
e.printStackTrace();
}
}
private double randomNoise(){//产生随机噪声
return (Math.random()-0.5)*3;//返回从-0.5到0.5的一个随机值
}
private void dither(){
BufferedImage imRes=new BufferedImage(original.getWidth(),
original.getHeight(),BufferedImage.TYPE_INT_RGB);
int n=original.getWidth();//图像的宽度
int m=original.getHeight();//长度
for(int i=0;i<n;++i){
for(int j=0;j<m;++j)
imRes.setRGB(i,j,original.getRGB(i,j)+(int)(randomNoise()));//这里就是上面文字的解释,在原像素值的基础上加入一些随机值,即加入随机噪声
}
try{//如果成功实现抖动,就保存图片到当前文件夹下
ImageIO.write(imRes,"PNG",new File("result.jpg"));//保存该文件,类型为jpg
}
catch(IOException e){//否则抛出异常
e.printStackTrace();
}
}
public static void main(String[] args) {
Main d=new Main();
d.readOriginal();
d.dither();
}
}
下面主要讲解一下文件是保存在什么位置:
首先在程序执行之前,应该在当前文件夹下有一个名为 original.jpg 的文件,当然文件类型肯定是jpg了。
比如说一开始我放的原灰度图像是这个,也就是 original.jpg
当文件夹下面有该图片时,则可以执行程序了,顺利执行完之后就会新生成一个 result.jpg 的文件,这样即使添加完随机噪声之后的图片,如下:
这样添加随机噪声的方式实现抖动就可以了。
方法二:有序抖动
有序抖动的文件读写和加入随机噪声相似,所以这里不需要重点介绍,需要说的就是实现有序抖动的原理:
import java.io.*;
import java.util.*;
import java.security.cert.PolicyNode;
import java.util.Scanner;//输入头文件
import java.util.Arrays;//引入数组类
import java.lang.StringBuffer;
import java.util.HashMap;
import java.util.Map.Entry;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Main {
private BufferedImage original;
//4*4抖动矩阵
private double mat[][]={{0,8,2,10},{12,4,14,6},{3,11,1,9},{15,7,13,5}};
private void readOriginal() {
File f=new File("original.jpg");
try{//读取图片
original=ImageIO.read(f);
} catch (IOException e) {//如果找不到这个图片则抛出异常
e.printStackTrace();
}
}
private void dither() {
BufferedImage imRes=new BufferedImage(original.getWidth(),
original.getHeight(),BufferedImage.TYPE_INT_RGB);
int n=original.getWidth();//图像的宽度
int m=original.getHeight();//长度
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
int color=original.getRGB(i,j);
int red=(color>>>16)&0xFF;
int green=(color>>>8)&0xFF;
int blue=(color>>>0)&0xFF;
double lum=(red+green+blue)/255;
if(lum>mat[i%4][j%4])
imRes.setRGB(i,j,0xFFFFFF);
else
imRes.setRGB(i,j,0x000000);
}
}
try{//如果成功实现抖动,就保存图片到当前文件夹下
ImageIO.write(imRes,"PNG",new File("result.png"));//最后保存图片类型为png
}
catch(IOException e){//否则抛出异常
e.printStackTrace();
}
}
public static void main(String[] args) {
Main d=new Main();
d.readOriginal();
d.dither();
}
}
有序抖动中我们还是以这张图片作为原灰度图像
在程序执行之后,得到的有序抖动之后的图像为
简单说明:
这2个程序我都是在idea上运行的,在Eclipse上运行不知道会不会出问题,对于学生来说是可以免费使用idea的,可以参考这篇 https://blog.csdn.net/xiatutut/article/details/126632928 ,但如果不是学生的话,如果用eclipse出问题,只能查问题原因或者用idea。
更多推荐
所有评论(0)