天天看點

圖像處理------添加高斯與泊松噪聲

數學基礎:

什麼是泊松噪聲,就是噪聲分布符合泊松分布模型。泊松分布(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&lt;height; row++) {  

            int ta = 0, tr = 0, tg = 0, tb = 0;  

            for(int col=0; col&lt;width; col++) {  

                index = row * width + col;  

                ta = (inpixels[index] &gt;&gt; 24) &amp; 0xff;  

                tr = (inpixels[index] &gt;&gt; 16) &amp; 0xff;  

                tg = (inpixels[index] &gt;&gt; 8) &amp; 0xff;  

                tb = inpixels[index] &amp; 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 &lt;&lt; 24) | (tr &lt;&lt; 16) | (tg &lt;&lt; 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&gt;=0 &amp;&amp; v&lt;=255);   

            if (inrange) tr = v;  

        } while (!inrange);  

        return tr;   

    public static int clamp(int p) {  

        return p &gt; 255 ? 255 : (p &lt; 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 &gt;= l);  

        double retvalue = math.max((pixel + (k - 1) / mean_factor - _mnoisefactor), 0);  

        return (int)retvalue;  

}