小波 mallat 算法
算法要求:输入序列是大于滤波器长度的偶数列
确实可以通过编程的手段使算法适合所有的情况,但本文章的目的是展示mallat算法的过程,所以就一切从简了
// Mallat.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
/*mallat算法 分解
* dSIn 输入的序列s,dH0尺度函数展开系数,dH1小波函数展开系数,dSOut输出低频部分,dDOut输出高频部分,
* nSIn_Len 输入序列的长度,nH_Len 滤波器的长度。
*/
int DwtFun(double *pdSIn,double *pdH0,double *pdH1,double *pdSOut,double *pdDOut,int nSIn_Len,int nH_Len)
{
int i,j,k;
//延拓后的Len是一个本体长度加一个滤波器长度
int nLen=nSIn_Len+2*nH_Len;
//建立滤波前的序列pdSArray,滤波后的序列pdSAOut低频部分,pdDAOut高频部分
double *pdSArray=new double[nLen];
double *pdSAOut=new double[nLen];
double *pdDAOut=new double[nLen];
//对称延拓
for(i=0;i<nLen;i++)
{
if(i<nH_Len)
{
pdSArray[i]=pdSIn[nH_Len-i-1];
}
else if(i>=nH_Len+nSIn_Len)
{
pdSArray[i]=pdSIn[nH_Len+2*nSIn_Len-1-i];
}
else
{
pdSArray[i]=pdSIn[i-nH_Len];
}
}
//求输出序列低频部分dSOut,高频部分dDOut.i->nLen,k->nH_Len
double dSTemp,dDTemp;
for(i=0;i<nLen;i++)
{
dSTemp=0.0;
dDTemp=0.0;
for(k=0;k<nH_Len;k++)
{
if((i-k)<0)
continue;
else
{
//低频部分
dSTemp+=pdH0[nH_Len-k-1]*pdSArray[i-k];
//高频部分
dDTemp+=pdH1[nH_Len-k-1]*pdSArray[i-k];
}
}
pdSAOut[i]=dSTemp;
pdDAOut[i]=dDTemp;
}
//二抽取.先将pdSAOut前nH_Len长的一段舍弃,抽取偶数列
for(i=nH_Len,j=0;i<nLen;i+=2,j++)
{
pdSOut[j]=pdSAOut[i+1];
pdDOut[j]=pdDAOut[i+1];
}
//返回输出序列的长度
return j;
delete pdSArray;
pdSArray=NULL;
delete pdSAOut;
pdSAOut=NULL;
delete pdDAOut;
pdDAOut=NULL;
}
/*mallat 算法 重构
* psSIn 输入的低频序列,pdDIn输入的高频序列,g0,g1重构滤波器,pdOut输出序列,nSInLen输入序列的长度
* nG_Len 滤波器长度
*/
int IDwtFun(double *pdSIn,double *pdDIn,double *pdG0,double *pdG1,double *pdOut,int nSInLen,int nG_Len)
{
int i,j,k;
//建立一个数列存放插入后的数列
int nTemp=2*nSInLen;
double *pdInSertS=new double[nTemp];
double *pdInSertD=new double[nTemp];
//二插入
j=0;
for(i=0;i<nTemp;i++)
{
if(i%2==0)
{
pdInSertS[i]=0;
pdInSertD[i]=0;
}
else
{
pdInSertS[i]=pdSIn[j];
pdInSertD[i]=pdDIn[j];
j++;
}
}
//对称拓延
//创建一个nTemp+nG_Len长的数列
int nLen=nTemp+2*nG_Len;
double *pdSAIn=new double[nLen];
double *pdDAIn=new double[nLen];
for(i=0;i<nLen;i++)
{
if(i<nG_Len)
{
pdSAIn[i]=pdInSertS[nG_Len-i-1];
pdDAIn[i]=pdInSertD[nG_Len-i-1];
}
else if(i==nTemp+nG_Len)
{
pdSAIn[i]=0.0;
pdDAIn[i]=0.0;
}
else if(i>nTemp+nG_Len)
{
pdSAIn[i]=pdInSertS[nG_Len+2*nTemp-i-1];
pdDAIn[i]=pdInSertD[nG_Len+2*nTemp-i-1];
}
else
{
pdSAIn[i]=pdInSertS[i-nG_Len];
pdDAIn[i]=pdInSertD[i-nG_Len];
}
}
//用滤波器G0和G1对数列进行滤波
double *pdSAOut=new double[nLen];
double *pdDAOut=new double[nLen];
double dSTemp,dDTemp;
for(i=0;i<nLen;i++)
{
dSTemp=0.0;
dDTemp=0.0;
for(k=0;k<nG_Len;k++)
{
if((i-k)<0)
continue;
else
{
//低频部分
dSTemp+=pdG0[nG_Len-k-1]*pdSAIn[i-k];
//高频部分
dDTemp+=pdG1[nG_Len-k-1]*pdDAIn[i-k];
}
}
pdSAOut[i]=dSTemp;
pdDAOut[i]=dDTemp;
}
//合并低频,高频
for(i=2*nG_Len-1,j=0;i<nLen;i++,j++)
{
pdOut[j]=pdSAOut[i]+pdDAOut[i];
}
return j;
delete pdInSertS;
pdInSertS=NULL;
delete pdInSertD;
pdInSertD=NULL;
delete pdSAIn;
pdSAIn=NULL;
delete pdDAIn;
pdDAIn=NULL;
delete pdSAOut;
pdSAOut=NULL;
delete pdDAOut;
pdDAOut=NULL;
}
int main(int argc, char* argv[])
{
int i;
//db4小波,已经取反 h0,h1是分解滤波器,g0,g1是重构滤波器
double dDb4h0[] = { 0.2303778133088964, 0.7148465705529154,
0.6308807679398587, -0.0279837694168599,
-0.1870348117190931, 0.0308413818355607,
0.0328830116668852, -0.0105974017850690 };
double dDb4h1[] = { -0.0105974017850690 , -0.0328830116668852,
0.0308413818355607 , 0.1870348117190931,
-0.0279837694168599 , -0.6308807679398587,
0.7148465705529154 , -0.2303778133088964};
double dDb4g0[] = { -0.0105974017850690 , 0.0328830116668852,
0.0308413818355607 , -0.1870348117190931,
-0.0279837694168599 , 0.6308807679398587,
0.7148465705529154 , 0.2303778133088964};
double dDb4g1[] = { -0.2303778133088964 , 0.7148465705529154,
-0.6308807679398587 , -0.0279837694168599,
0.1870348117190931 , 0.0308413818355607,
-0.0328830116668852 , -0.0105974017850690};
//生成一个数列,本算法要求输入的数列是比滤波器长的偶数列
double a[]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0};
//double a[]={1.0,4.0,5.5,8.2,2.7,5.2,2.0,2.0,2.0,3.0,3.0,4.0,4.0,14.0,17.0,11.0};
//输出
double *pdS=new double[100];
double *pdD=new double[100];
double *pdOut=new double[100];
int l=DwtFun(a,dDb4h0,dDb4h1,pdS,pdD,16,8);
for(i=0;i<l-1;i++)
{
printf("%f\t",pdS[i]);
printf("\n");
}
printf("*********************\n");
for(i=0;i<l-1;i++)
{
printf("%f\t",pdD[i]);
printf("\n");
}
printf("*********************\n");
int v=IDwtFun(pdS,pdD,dDb4g0,dDb4g1,pdOut,11,8);
//i<v-nG_Len+1
for(i=0;i<v-7;i++)
{
printf("%f\t",pdOut[i]);
printf("\n");
}
delete []pdS;
pdS=NULL;
delete []pdD;
pdD=NULL;
delete []pdOut;
pdOut=NULL;
return 0;
}
小波 mallat 算法的更多相关文章
- 小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)--转载
小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化) 在上回<小波学习之一>中,已经详细介绍了Mallat算法C++实现,效果还可以,但也存在一些问题,比如,代码 ...
- 小波学习之一(单层一维离散小波变换DWT的Mallat算法C++和MATLAB实现) ---转载
1 Mallat算法 离散序列的Mallat算法分解公式如下: 其中,H(n).G(n)分别表示所选取的小波函数对应的低通和高通滤波器的抽头系数序列. 从Mallat算法的分解原理可知,分解后的序 ...
- 基于python的小波阈值去噪算法
https://blog.csdn.net/alwaystry/article/details/52756051 发表于 2018-01-10 16:32:17 嵌入式设计应用 +关注 小波图像去噪原 ...
- dennis gabor 从傅里叶(Fourier)变换到伽柏(Gabor)变换再到小波(Wavelet)变换(转载)
dennis gabor 题目:从傅里叶(Fourier)变换到伽柏(Gabor)变换再到小波(Wavelet)变换 本文是边学习边总结和摘抄各参考文献内容而成的,是一篇综述性入门文档,重点在于梳理傅 ...
- 完全搞懂傅里叶变换和小波(1)——总纲<转载>
无论是学习信号处理,还是做图像.音视频处理方面的研究,你永远避不开的一个内容,就是傅里叶变换和小波.但是这两个东西其实并不容易弄懂,或者说其实是非常抽象和晦涩的! 完全搞懂傅里叶变换和小波,你至少需要 ...
- 小波神经网络(WNN)
人工神经网络(ANN) 是对人脑若干基本特性通过数学方法进行的抽象和模拟,是一种模仿人脑结构及其功能的非线性信息处理系统. 具有较强的非线性逼近功能和自学习.自适应.并行处理的特点,具有良好的容错能力 ...
- 系统学习机器学习之神经网络(三)--GA神经网络与小波神经网络WNN
系统学习机器学习之神经网络(三)--GA神经网络与小波神经网络WNN 2017年01月09日 09:45:26 Eason.wxd 阅读数 14135更多 分类专栏: 机器学习 1 遗传算法1.1 ...
- 图像算法五:【图像小波变换】多分辨率重构、Gabor滤波器、Haar小波
原 https://blog.csdn.net/alwaystry/article/details/52756051 图像算法五:[图像小波变换]多分辨率重构.Gabor滤波器.Haar小波 2018 ...
- CSS3 波浪简单模拟--我是波浪,我有起伏,有大波与小波(坏笑中...)
我是波浪,我有起伏,我有大波与小波(坏笑中...) 最近改版网站,一般也不会去写动画,但是有些网站还是需要的,故拿出一个较简单的动画出来分享,很简单很简单. 原理简单阐述 其实很简单,使用一张美工做好 ...
随机推荐
- java学习面向对象之设计模式之单例模式
就像上一节当中我们讲到的数组工具集一样,如果我们把他看作一个类,来应用,不阻止他new函数的话,这个类我们在整个过程当中我们只是用他来当一个工具.假如每次用都要new一下产生一个新对象的话,就会显得整 ...
- 账户管理groupadd groupmod groupdel usermod usermod userdel
http://www.cnblogs.com/ggjucheng/archive/2012/08/21/2648380.html http://blog.csdn.net/qq1603013767/a ...
- open和fopen的区别(转)
转载自:http://www.cnblogs.com/joeblackzqq/archive/2011/04/11/2013010.html open和fopen的区别: 1.缓冲文件系统缓 冲文件系 ...
- COJ 0346 WZJ的旅行(二)更新动态树分治版本
WZJ的旅行(二) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 时隔多日,WZJ又来到了幻想国旅行.幻想国由N个城市组成,由 ...
- POJ 2762 Going from u to v or from v to u?(强联通 + TopSort)
题目大意: 为了锻炼自己的儿子 Jiajia 和Wind 把自己的儿子带入到一个洞穴内,洞穴有n个房间,洞穴的道路是单向的. 每一次Wind 选择两个房间 x 和 y, 让他的儿子从一个房间走到 ...
- 数据结构(线段树):SPOJ GSS3 - Can you answer these queries III
GSS3 - Can you answer these queries III You are given a sequence A of N (N <= 50000) integers bet ...
- 转:给C++初学者的50个忠告
转:给C++初学者的50个忠告 1.把C++当成一门新的语言学习(和C没啥关系!真的.): ...
- lightoj 1005 组合数学
题目链接:http://lightoj.com/volume_showproblem.php?problem=1005 #include <cstdio> #include <cst ...
- poj 3084 最小割
题目链接:http://poj.org/problem?id=3084 本题主要在构图上,我采用的是把要保护的房间与源点相连,有intruder的与汇点相连,相对麻烦. #include <cs ...
- 60秒找到最对的size?为服饰电商提供尺寸匹配解决方案的True Fit获1500万美元融资 | 36氪
60秒找到最对的size?为服饰电商提供尺寸匹配解决方案的True Fit获1500万美元融资 | 36氪 60秒找到最对的size?为服饰电商提供尺寸匹配解决方案的True Fit获1500万美元融 ...