小波總結

小波學習

小波去噪

方法一

原理:因爲噪聲通常位於圖像的高頻部分,去除圖像的高頻部分,使用低頻部分恢復圖像。
方法:對圖像進行多級小波分解,捨去圖像的水平細節子帶,垂直細節子帶,和對角線細節子帶,只使用圖像的近似子帶去重構圖像。
缺點:因爲捨棄了細節子帶的一些信息,也容易引起圖像的模糊。

代碼

%裝載原始圖像信號並圖示 
X = imread('7.png') ;
subplot(2,2,1); 
image(mat2gray(X)); 
title('原始圖像'); 
axis square; 
%============================== 
%生成含噪圖像並圖示 
init=2055615866; 
rand('seed',init); 
noise = 12*randn(size(X));
XX=uint8(double(X)+noise);
subplot(2,2,2); 
image(mat2gray(XX)); 
title('含噪圖像'); 
axis square; 
%============================== 
%首先用sym4小波函數對XX進行2層分解 
[c,l]=wavedec2(XX,2,'sym4'); 
%實現低通濾波消噪 
a1=wrcoef2('a',c,l,'sym4',1); 
%再次實現低通濾波消噪 
a2=wrcoef2('a',c,l,'sym4',2); 
%============================== 
%圖示消噪處理後的結果 
subplot(2,2,3); 
image(mat2gray(a1)); 
title('第一次消噪圖像'); 
axis square; 
subplot(2,2,4); 
image(a2); 
title('第二次消噪圖像'); 
axis square;

這裏寫圖片描述

方法二

原理:因爲噪聲的集中在高頻階段,對高頻部分進行閾值處理,使用wthcoef2函數。
方法:對圖像進行多級小波分解,對每級的細節進行閾值處理。
缺點:閾值的設置需要人手動調節,往往是經驗值,或者選取高頻部分的幅值的百分比進行裁剪。

代碼

load gatlin2; 
subplot(2,2,1); 
image(X); 
colormap(map); 
title('原始圖像'); 
axis square; 
%生成含噪圖像並圖示 
init=2055615866; 
randn('seed',init); 
XX=X+8*randn(size(X)); 
subplot(2,2,2); 
image(XX); 
colormap(map); 
title('含噪圖像'); 
axis square; 

%對圖像進行消噪處理 
%用小波函數coif2對圖像XX進行2層分解 
[c,l]=wavedec2(XX,2,'coif2'); 
n=[1,2];%設置尺度向量 
p=[10.28,24.08];%設置閾值向量 
%對三個高頻係數進行閾值處理 
nc=wthcoef2('h',c,l,n,p,'s'); 
nc=wthcoef2('v',nc,l,n,p,'s'); 
nc=wthcoef2('d',nc,l,n,p,'s'); 
X1=waverec2(nc,l,'coif2'); 
subplot(2,2,3); 
image(X1); 
colormap(map); 
title('第一次消噪後的圖像'); 
axis square; 
%再次對三個高頻係數進行閾值處理 
nc=wthcoef2('h',nc,l,n,p,'s'); 
nc=wthcoef2('v',nc,l,n,p,'s'); 
nc=wthcoef2('d',nc,l,n,p,'s'); 
%對更新後的小波分解結構進行重構並圖示結果 
X2=waverec2(nc,l,'coif2'); 
subplot(2,2,4); 
image(X2); 
colormap(map); 
title('第二次消噪後的圖像'); 
axis square;

這裏寫圖片描述

方法三

盲去噪,使用默認值進行圖像去噪或壓縮,函數ddencmp(Default values for denoising or compression)
語法:[THR,SORH,KEEPAPP,CRIT] = ddencmp(IN1,IN2,X)
當IN1是‘den’該函數式去噪,當‘cmp’該函數是壓縮。IN2是‘wv’和‘wp’是小波包,x是數據。THR是閾值,SORH是軟或硬閾值方法。KEEPAPP是允許保留的近似係數。
小波和小波包的區別
這裏寫圖片描述
軟閾值和硬閾值方法
matlab中有wthresh(Soft or hard thresholding)的方法,
語法如下:Y = wthresh(X,SORH,T)

Y = wthresh(X,SORH,T) returns the soft (if SORH = ‘s’) or hard (if
SORH = ‘h’) thresholding of the input vector or matrix X. T is the
threshold value.
Y = wthresh(X,’s’,T) returns , soft thresholding is wavelet shrinkage ( (x)+ = 0 if x < 0; (x)+ = x, if x ≥ 0 ).
Y = wthresh(X,’h’,T) returns , hard thresholding is cruder.
這裏寫圖片描述

代碼

%裝載原始圖像 
img=imread('11.png'); 
x  = img ;
%x包含原始圖像 

%產生噪聲圖像 
init=2055615866; 
rand('seed',init); 
noise = 12*randn(size(x));
x=uint8(double(x)+noise);

subplot(1,3,1),image(mat2gray(x)); 
title('含噪圖像'); 

%使用wdencmp進行圖像去噪 
%得到x的小波分解結構 
n=2; 
w='db5'; 
[c,l]=wavedec2(x,n,w); 
%小波係數的閾值處理 
[thr,sorh,keepapp]=ddencmp('den','wv',x); 
[xd,cxd,lxd,perf0,perfl2]=wdencmp('gbl',c,l,w,n,thr,'s',l); 
%畫出去噪後的圖象 
subplot(1,3,2),image(mat2gray(xd));
title('去噪後的圖像');

這裏寫圖片描述

小波增強

思想:

Make the small coefficients very small and the large coefficients very
large. Apply a nonlinear mapping function to the coefficients.
這應該是一篇論文的效果,但是我還沒看到論文,是在密歇根大學的關於小波PPT上面找到的:
這裏寫圖片描述
這裏寫圖片描述

小波圖像去霧

這是看到一些中文文章給出的一些小波增強的方法,但試了效果不好,雖然可以消除一些噪聲,但會引起圖像模糊。(囧,暫時不方便傳代碼)

效果

這裏寫圖片描述

附哈爾小波的C語言實現

#include <iostream>
#include <cmath>
using namespace std;


/** The 1D Haar Transform **/
void haar1d(float *vec, int n)
{
    int i=0;
    int w=n;
    float *vecp = new float[n];
    for(i=0;i<n;i++)
        vecp[i] = 0;

    while(w>1)
    {
        w/=2;
        for(i=0;i<w;i++)
        {
            vecp[i] = (vec[2*i] + vec[2*i+1])/sqrt(2.0);
            vecp[i+w] = (vec[2*i] - vec[2*i+1])/sqrt(2.0);
        }

        for(i=0;i<(w*2);i++)
            vec[i] = vecp[i]; 
    }

    delete [] vecp;
}


/** A Modified version of 1D Haar Transform, used by the 2D Haar Transform function **/
void haar1(float *vec, int n, int w)
{
    int i=0;
    float *vecp = new float[n];
    for(i=0;i<n;i++)
        vecp[i] = 0;

        w/=2;
        for(i=0;i<w;i++)
        {
            vecp[i] = (vec[2*i] + vec[2*i+1])/sqrt(2.0);
            vecp[i+w] = (vec[2*i] - vec[2*i+1])/sqrt(2.0);
        }

        for(i=0;i<(w*2);i++)
            vec[i] = vecp[i];

        delete [] vecp;
}


/** The 2D Haar Transform **/
void haar2(float **matrix, int rows, int cols)
{
    float *temp_row = new float[cols];
    float *temp_col = new float[rows];

    int i=0,j=0;
    int w = cols, h=rows;
    while(w>1 || h>1)
    {
        if(w>1)
        {
            for(i=0;i<h;i++)
            {
                for(j=0;j<cols;j++)
                    temp_row[j] = matrix[i][j];

                haar1(temp_row,cols,w);

                for(j=0;j<cols;j++)
                    matrix[i][j] = temp_row[j];
            }
        }

        if(h>1)
        {
            for(i=0;i<w;i++)
            {
                for(j=0;j<rows;j++)
                    temp_col[j] = matrix[j][i];
                haar1(temp_col, rows, h);
                for(j=0;j<rows;j++)
                    matrix[j][i] = temp_col[j];
            }
        }

        if(w>1)
            w/=2;
        if(h>1)
            h/=2;
    }

    delete [] temp_row;
    delete [] temp_col;
}

/** Here's an example on how to use these functions **/
int main(int argc, char **argv)
{
    int i=0;
    float vec3[4] = {4,2,5,5};

    haar1d(vec3,4);

    cout << "The 1D Haar Transform: " << endl;
    for(i=0;i<4;i++)
        cout << vec3[i] << " ";
    cout << endl;

    cout << "\n\nThe 2D Haar Transform: " << endl;
    float **mat = new float*[4];
    for(int m=0;m<4;m++)
        mat[m] = new float[4];
    mat[0][0] = 5; mat[0][1] = 6; mat[0][2] = 1; mat[0][3] = 2;
    mat[1][0] = 4; mat[1][1] = 2; mat[1][2] = 5; mat[1][3] = 5;
    mat[2][0] = 3; mat[2][1] = 1; mat[2][2] = 7; mat[2][3] = 1;
    mat[3][0] = 6; mat[3][1] = 3; mat[3][2] = 5; mat[3][3] = 1;


    haar2(mat,4,4);
    for(i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
            cout << mat[i][j] << " ";
        cout << endl;
    }

    cout << endl;
    return 0;
}

參考資料

關於小波,我這裏有一個多倫多大學的PPT講義,以哈爾小波爲例,講的十分通俗易懂。點此下載
An Introduction to Wavelets and the Haar Transform by Musawir Ali

轉載保留聲明

作者 日期 聯繫方式
風吹夏天 2015年7月31日 [email protected]
發佈了50 篇原創文章 · 獲贊 76 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章