數學基礎:
什麼是泊松噪聲,就是噪聲分布符合泊松分布模型。泊松分布(poisson di)的公
式如下:

關于高斯分布與高斯噪聲看這裡:
<a target="_blank" href="http://blog.csdn.net/jia20003/article/details/7181463">http://blog.csdn.net/jia20003/article/details/7181463</a>
二:程式實作
以前在圖像加噪博文中現實的加高斯噪聲,比較複雜。是自己完全實作了高斯随
機數的産生,這裡主要是利用java的随機數api提供的nextgaussion()方法來得
到高斯随機數。泊松噪聲為了簡化計算,google到一位神人完成的c++代碼于是
我翻譯成java的。
三:程式效果
濾鏡源代碼:
package com.gloomyfish.filter.study;
import java.awt.image.bufferedimage;
import java.util.random;
public class noiseadditionfilter extends abstractbufferedimageop {
public final static double mean_factor = 2.0;
public final static int poisson_noise_type = 2;
public final static int gaussion_noise_type = 1;
private double _mnoisefactor = 25;
private int _mnoisetype = poisson_noise_type;
public noiseadditionfilter() {
system.out.println("adding poisson/gaussion noise");
}
public void setnoise(double power) {
this._mnoisefactor = power;
public void setnoisetype(int type) {
this._mnoisetype = type;
@override
public bufferedimage filter(bufferedimage src, bufferedimage dest) {
int width = src.getwidth();
int height = src.getheight();
random random = new random();
if ( dest == null )
dest = createcompatibledestimage( src, null );
int[] inpixels = new int[width*height];
int[] outpixels = new int[width*height];
getrgb( src, 0, 0, width, height, inpixels );
int index = 0;
for(int row=0; row<height; row++) {
int ta = 0, tr = 0, tg = 0, tb = 0;
for(int col=0; col<width; col++) {
index = row * width + col;
ta = (inpixels[index] >> 24) & 0xff;
tr = (inpixels[index] >> 16) & 0xff;
tg = (inpixels[index] >> 8) & 0xff;
tb = inpixels[index] & 0xff;
if(_mnoisetype == poisson_noise_type) {
tr = clamp(addpnoise(tr, random));
tg = clamp(addpnoise(tg, random));
tb = clamp(addpnoise(tb, random));
} else if(_mnoisetype == gaussion_noise_type) {
tr = clamp(addgnoise(tr, random));
tg = clamp(addgnoise(tg, random));
tb = clamp(addgnoise(tb, random));
}
outpixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
}
}
setrgb( dest, 0, 0, width, height, outpixels );
return dest;
private int addgnoise(int tr, random random) {
int v, ran;
boolean inrange = false;
do {
ran = (int)math.round(random.nextgaussian()*_mnoisefactor);
v = tr + ran;
// check whether it is valid single channel value
inrange = (v>=0 && v<=255);
if (inrange) tr = v;
} while (!inrange);
return tr;
public static int clamp(int p) {
return p > 255 ? 255 : (p < 0 ? 0 : p);
private int addpnoise(int pixel, random random) {
// init:
double l = math.exp(-_mnoisefactor * mean_factor);
int k = 0;
double p = 1;
k++;
// generate uniform random number u in [0,1] and let p ← p × u.
p *= random.nextdouble();
} while (p >= l);
double retvalue = math.max((pixel + (k - 1) / mean_factor - _mnoisefactor), 0);
return (int)retvalue;
}