赞
踩
小波学习
小波去噪
方法一
原理:因为噪声通常位于图像的高频部分,去除图像的高频部分,使用低频部分恢复图像。
方法:对图像进行多级小波分解,舍去图像的水平细节子带,垂直细节子带,和对角线细节子带,只使用图像的近似子带去重构图像。
缺点:因为舍弃了细节子带的一些信息,也容易引起图像的模糊。
代码
%装载原始图像信号并图示
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
#include
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
vecp[i] = 0;
while(w>1)
{
w/=2;
for(i=0;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
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
vecp[i] = 0;
w/=2;
for(i=0;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
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
{
for(j=0;j
temp_row[j] = matrix[i][j];
haar1(temp_row,cols,w);
for(j=0;j
matrix[i][j] = temp_row[j];
}
}
if(h>1)
{
for(i=0;i
{
for(j=0;j
temp_col[j] = matrix[j][i];
haar1(temp_col, rows, h);
for(j=0;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日
wincoder@qq.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。