天天看點

圖像處理------圖像加噪

圖像噪聲源于現實世界中數字信号總會受到各種各樣的幹擾,最終接受的圖像和源于的數字信号之間總

是存在一定的差異,對于圖像噪聲,使用均值濾波和中值濾波來消除圖像噪聲的做法已經是很常見的圖

像消噪手段。

一:圖像加噪原理

1.     椒鹽噪聲(salt and pepper noise)

椒鹽噪聲是一種因為信号脈沖強度引起的噪聲,信噪比(signal noiserate)是衡量圖像噪聲的一個數字名額。

給一副數字圖像加上椒鹽噪聲的處理順序應該如下:

指定信噪比 snr 其取值範圍在[0, 1]之間

計算總像素數目 sp, 得到要加噪的像素數目 np = sp * (1-snr)

随機擷取要加噪的每個像素位置p(i, j)

指定像素值為255或者0。

重複c, d兩個步驟完成所有像素的np個像素

輸出加噪以後的圖像

2.     高斯噪聲(gaussian noise)

高斯噪聲的密度取決于公式g(x, sigma) 其中x是代表平均值,sigma代表的标準方差,每個輸入像素 pin, 

一個正常的高斯采樣分布公式g(d), 得到輸出像素pout.

       pout = pin + xmeans + sigma *g(d)

其中d為一個線性的随機數,g(d)是随機數的高斯分布随機值。

給一副數字圖像加上高斯噪聲的處理順序如下:

a.      輸入參數sigam 和 x mean

b.      以系統時間為種子産生一個僞随機數

c.      将僞随機數帶入g(d)得到高斯随機數

d.      根據輸入像素計算出輸出像素

e.      重新将像素值防縮在[0 ~ 255]之間

f.       循環所有像素

g.      輸出圖像

二:關鍵程式解析

1.     椒鹽噪聲

根據信噪比,擷取要加入椒鹽噪聲的像素數目

int size= (int)(inpixels.length * (1-snr));

随機得到像素,完成椒鹽噪聲的加入

for(int i=0; i<size; i++) {

int row = (int)(math.random()* (double)height);

int col = (int)(math.random()* (double)width);

index= row * width + col;

inpixels[index]= (255 << 24) | (255 << 16) | (255 << 8) | 255;

}

2.     高斯噪聲

根據标準方差,和僞随機數的範圍,首先計算出一個僞随機數d ,根據d得到高斯分布的随機數值,整個代碼如下:

    float d = (float)math.random()*random_scope - random_scope/2;

    float sigma2 = sigma*sigma*2;

    float pi2 = (float)math.pi * 2;

    float sigmapi2 = (float)math.sqrt(pi2*sigma);

    float result = (float)math.exp(-d/sigma2)/sigmapi2;

僞随機數的範圍為[-127~ 127]之間。

擷取高斯噪聲的像素代碼如下:

tr = (int)((float)tr + getgaussianvalue() + this.means);

tg = (int)((float)tg + getgaussianvalue() + this.means);

tb = (int)((float)tb + getgaussianvalue() + this.means);

mean是的值為0.

三:程式效果如下

加入白色椒鹽噪聲的圖檔

圖像處理------圖像加噪

加入高斯噪聲的圖檔

圖像處理------圖像加噪

椒鹽噪聲的代碼如下:

private bufferedimage addsaltandpeppernoise(bufferedimage src, bufferedimage dst) {  

    int width = src.getwidth();  

       int height = src.getheight();  

       if ( dst == null )  

           dst = createcompatibledestimage( src, null );  

       int[] inpixels = new int[width*height];  

       getrgb( src, 0, 0, width, height, inpixels );  

       int index = 0;  

       int size = (int)(inpixels.length * (1-snr));  

       for(int i=0; i<size; i++) {  

        int row = (int)(math.random() * (double)height);  

        int col = (int)(math.random() * (double)width);  

        index = row * width + col;  

        inpixels[index] = (255 << 24) | (255 << 16) | (255 << 8) | 255;  

       }  

       setrgb( dst, 0, 0, width, height, inpixels );  

       return dst;  

}  

高斯噪聲的代碼如下:

private bufferedimage gaussiannoise(bufferedimage src, bufferedimage dst) {  

        int width = src.getwidth();  

        int height = src.getheight();  

        if ( dst == null )  

            dst = createcompatibledestimage( src, null );  

        int[] inpixels = new int[width*height];  

        int[][][] temppixels = new int[height][width][4];   

        int[] outpixels = new int[width*height];  

        getrgb( src, 0, 0, width, height, inpixels );  

        int index = 0;  

        float inmax = 0;  

        float outmax = 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(inmax < tr) {  

                    inmax = tr;  

                }  

                if(inmax < tg) {  

                    inmax = tg;  

                if(inmax < tb) {  

                    inmax = tb;  

                tr = (int)((float)tr + getgaussianvalue() + this.means);  

                tg = (int)((float)tg + getgaussianvalue() + this.means);  

                tb = (int)((float)tb + getgaussianvalue() + this.means);  

                if(outmax < tr) {  

                    outmax = tr;  

                if(outmax < tg) {  

                    outmax = tg;  

                if(outmax < tb) {  

                    outmax = tb;  

                temppixels[row][col][0] = ta;  

                temppixels[row][col][1] = tr;  

                temppixels[row][col][2] = tg;  

                temppixels[row][col][3] = tb;  

            }  

        }  

        // normalization  

        index = 0;  

        float rate = inmax/outmax;  

                ta = temppixels[row][col][0];  

                tr = temppixels[row][col][1];  

                tg = temppixels[row][col][2];  

                tb = temppixels[row][col][3];  

                tr = (int)((float)tr * rate);  

                tg = (int)((float)tg * rate);  

                tb = (int)((float)tb * rate);  

                outpixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  

        setrgb( dst, 0, 0, width, height, outpixels );  

        return dst;  

    }