德国开元华人社区 开元周游
标题:
做实习遇到的问题
[打印本页]
作者:
loveless
时间:
10.6.2006 16:16
这次实习做的是关于用Wavelet变换来分析EMG的信号。观察Aktivitaet和它的关系。<br /><br />现在碰到个问题,对于已有的Wavelet的C的源代码如何变成Simulink里的S-Function<br /><br />呢?请懂的人说一下。十分感谢!
作者:
loveless
时间:
10.6.2006 16:38
那你能不能给我看看C的源代码?很难理解,看不懂。
作者:
loveless
时间:
11.6.2006 22:39
#define N0 128<br />#include "stdio.h"<br />#include "stdlib.h"<br />#include "math.h"<br />#include "string.h"<br />void db4(double *h,double *g,double *hh,double *gg);<br />void wd(int N,double *h,double *g,double *c0,double *c,double *d);<br />void wr(int N,double *h,double *g,double *c, double *d,double *cd);<br />void main()<br />{<br />double fk[N0],c0[N0],c[N0],d[N0];<br />double h[8],g[8],hh[8],gg[8];<br />float fk0[N0];<br />FILE *fp;<br />int i,k,j,n,l,N;<br />fp=fopen("wdata.dat","rt");<br />fscanf(fp,"%d",&N);<br />for(k=0;kfclose(fp);<br />db4(h,g,hh,gg);<br />for(k=0;kc0[k]=fk0[k];<br />c[k]=0;<br />d[k]=0;<br />}<br />wd(N,hh,gg,c0,c,d);<br />wr(N,hh,gg,c,d,c0);<br />for(k=0;kreturn;<br />}<br />void wd(int N,double *h,double *g,double *c0,double *c,double *d)<br />/* wavelet decomposition */<br />{<br />int k,n,k2,l;<br />double ck,dk;<br />for(k=0;kck=0.0;<br />dk=0.0;<br />for(l=0;l<8;l++) {<br />n=k+l;<br />ck+=c0[n%N]*h[l];<br />dk+=c0[n%N]*g[l];<br />}<br />c[k]=ck;<br />d[k]=dk;<br />}<br />for(k=0;kk2=2*k;<br />c0[k]=c[k2];<br />c0[N/2+k]=d[k2];<br />}<br />return;<br />}<br />void wr(int N,double *h,double *g,double *c,double *d,double *c0)<br />/* wavelet reconstruction */<br />{<br />int k,n,l,k2;<br />double ck,cn,dn;<br />for(k=0;kk2=2*k;<br />c[k2]=c0[k];<br />c[k2+1]=0;<br />d[k2]=c0[N/2+k];<br />d[k2+1]=0;<br />}<br />for(k=0;kfor(k=0;kck=0.0;<br />for(l=0;l<8;l++) {<br />n=k-l;<br />cn=c[(N+n)%N];<br />dn=d[(N+n)%N];<br />ck+=cn*h[l]+dn*g[l];<br />}<br />c0[k]=ck;<br />}<br />return;<br />}<br />void db4(double *h,double *g,double *hh,double *gg)<br />/* Daubechies 4 wavelet */<br />{<br />int k,isgn;<br />h[7]=-0.0105974017850890;<br />h[6]= 0.0328830116668852;<br />h[5]= 0.0308413818355607;<br />h[4]=-0.1870348117190931;<br />h[3]=-0.0279837694168599;<br />h[2]= 0.6308807679398597;<br />h[1]= 0.7148465705529154;<br />h[0]= 0.2303778133088964;<br />isgn=1;<br />for(k=0;k<8;k++) {<br />gg[k]=isgn*h[7-k];<br />isgn=-isgn;<br />}<br />for(k=0;k<8;k++) {<br />g[k]=gg[7-k];<br />hh[k]=h[7-k];<br />}<br />return;<br />}<br />float fun(float x)<br />{<br />float pi=3.1415926;<br />float yx=30*exp(-x/40)*sin(2*pi*x/40);<br />return(yx);<br />}<br /><br />这个用的是 DB4小波,周期延拓,可以实现精确重构的。
作者:
loveless
时间:
11.6.2006 22:40
谢谢你给我看看!
作者:
loveless
时间:
12.6.2006 22:02
谢谢阿,我再仔细看看。
作者:
loveless
时间:
13.6.2006 16:08
问下斑竹,这个就是所谓的短波变换吗?<br /><br />我现在做实习里面的前提就是先要用Simulink进行仿真。<br /><br />输入是时间和频率,或者只是频率。因为是离散的时间,时间间隔是常数。<br /><br />那么如果用以上的C源代码。怎么变成Simulink里的S函数呢?<br /><br />数据是从From Workspace输入,经过变换和Scope之后,还要回到Workspace。就是to Workspace。而我现在就是要通过这个变化得到那个Spektrogramm。
作者:
loveless
时间:
16.6.2006 13:46
的确是这样,现在就是这个S函数该怎么调整?能不能再说的详细一点啊?谢谢!
作者:
行走城市的猫
时间:
17.6.2006 08:43
eisenstange <br />好人加能人。<br />我文科生,一窍不懂得说。但是,非常欣赏这样相互帮助的态度。<br />
作者:
行走城市的猫
时间:
17.6.2006 10:59
<!--emo&
--><img src='style_emoticons/<#EMO_DIR#>/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif' /><!--endemo--> <!--QuoteBegin-eisenstange+17.06.2006, 09:07 --><div class='quotetop'>QUOTE(eisenstange @ 17.06.2006, 09:07 )</div><div class='quotemain'><!--QuoteEBegin-->万事开头难,每个人都有一开始的时候,作为过来人,因该尽可能的扶一下,谁叫现在企业对毕业生的要求都那么高呢,大家学的好,对个人和国家社会都有利。牺牲个把小时,值得。有时候自己也能从中学到一些东西。利己利人何乐而不为。<br />[right][snapback]1008611[/snapback][/right]<br /><!--QuoteEnd--></div><!--QuoteEEnd--><br />如果大家都能这么团结一致,共同研究,那么,我们中国学生勤奋好学,紧密联系会让周围的外国人敬佩的。<br />
作者:
loveless
时间:
17.6.2006 16:15
今天早上刚和一起做的人讨论好回来。就看到斑竹如此详细的解释。真是很感谢。马上试下。
作者:
loveless
时间:
17.6.2006 16:19
Mex-Setup是在命令行里输入吗?<br />
作者:
loveless
时间:
17.6.2006 16:19
>> Mex-Setup<br />Warning: Could not find an exact (case-sensitive) match for 'Mex'. C:\
rogram Files\MATLAB704\toolbox\matlab\general\mex.m is a case-insensitive match and will be used instead. You can improve the performance of your code by using exact name matches and we therefore recommend that you update your usage accordingly. Alternatively, you can disable this warning using warning('off','MATLAB:dispatcher:InexactMatch').<br /> <br />Select a compiler: <br />[1] Lcc C version 2.4 in C:\
ROGRAM FILES\MATLAB704\sys\lcc <br /> <br />[0] None <br /> <br />Compiler: 1<br /> <br />Try to update options file: C:\Documents and Settings\JuliusWoo\Application Data\MathWorks\MATLAB\R14\mexopts.bat <br />From template: C:\
ROGRAM FILES\MATLAB704\BIN\WIN32\mexopts\lccopts.bat <br /> <br />Done . . . <br /> <br /> Usage: <br /> MEX [option1 ... optionN] sourcefile1 [... sourcefileN] <br /> [objectfile1 ... objectfileN] [libraryfile1 ... libraryfileN] <br /> <br /> or (to build an Ada S-function): <br /> MEX [-v] [-g] -ada <sfcn>.ads <br /> <br /> Use the -help option for more information, or consult the MATLAB API Guide. <br /> <br /> <br /> C:\
ROGRAM FILES\MATLAB704\BIN\WIN32\MEX.PL: Error: No file names given. <br /> <br />??? Undefined function or variable 'Setup'.<br />
作者:
loveless
时间:
17.6.2006 16:23
<!--QuoteBegin-eisenstange+17.06.2006, 16:21 --><div class='quotetop'>QUOTE(eisenstange @ 17.06.2006, 16:21 )</div><div class='quotemain'><!--QuoteEBegin-->可能是你的C编译器没有装好,你的机器上用的是什么编译器? VC还是GCC?<br />[right][snapback]1008958[/snapback][/right]<br /><!--QuoteEnd--></div><!--QuoteEEnd--><br /><br /><br />我也不清楚,这个是怎么看?
作者:
loveless
时间:
17.6.2006 16:25
是不是直接把C代码,粘贴在下面。就是运行了Mex-Setup后的命令行下面?
作者:
loveless
时间:
17.6.2006 16:31
// Onur G. Guleryuz 1995, 1996, 1997,<br />// University of Illinois at Urbana-Champaign,<br />// Princeton University,<br />// Polytechnic University.<br /><br />#include <stdio.h><br />#include <stdlib.h><br />#include "wav_filters_extern.h"<br />#include "wav_gen.h"<br />#include "alloc.h"<br /><br />// Extend data by ofs pixels on both ends using periodic <br />// symmetry. data should be "pointing in" to allow up to data[-ofs]<br />// and data[N-1+ofs]. <br />// ofs>=N is handled.<br /><br />void extend_periodic(float *data,int N,int ofs)<br /><br />{<br /> int i,k;<br /><br /> k=N-1;<br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[N-i];<br /> data[k+i]=data[i-1];<br /> }<br />}<br /><br />// Extend data by ofs pixels on both ends using mirror <br />// symmetry. data should be "pointing in" to allow up to data[-ofs]<br />// and data[N-1+ofs]. <br />//<br />// There are two possible "mirrors", i.e., data[-1]=data[1] (mirror on 0) <br />// or data[-1]=data[0] (mirror "between" -1 and 0). phase is either 0, 1, or 2<br />// to select among these cases. See if(phase==... below. <br /> <br />void extend_mirror(float *data,int N,int ofs,int phase)<br /><br />{<br /> int i,k;<br /> int phase1,phase2;<br /><br /> if((phase<0)||(phase>2)) {<br /><br /> printf("extend_mirror: illegal phase\n");<br /> exit(1);<br /> }<br /><br /> if(phase==2){<br /> // At left boundary the mirror is on 0.<br /> phase1=0;<br /><br /> // At right boundary the mirror is on N-1.<br /> phase2=1;<br /> }<br /> else {<br /><br /> // phase==0, at left mirror on 0, and at right it's between.<br /> // phase==1, at left mirror between, and at right it's on N-1.<br /> phase1=phase2=phase;<br /> }<br /><br /> k=N-1;<br /> <br /> if(N==1) {<br /><br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[0];<br /> data[k+i]=data[0];<br /> }<br /> }<br /> else<br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[i-phase1];<br /> data[k+i]=data[N-phase2-i];<br /> }<br />}<br /><br />// This routine is used in evaluating forward wavelet transforms.<br />//<br />// data of dimension N contains the input.<br />// float *filter contains the Nf filter taps.<br />// ofs is the decimation factor.<br />//<br />// filtering starts at beg and continues until N+beg, yielding N/ofs samples. <br />// data needs to be padded suitably at both ends.<br />// This hoopla about the starting point is in place to ensure <br />// correct boundary processing when evaluating wavelet transforms.<br />//<br />// coef returns the result of the filtering and decimation.<br />// <br />// Viewed as a transform the basis function that generates the<br />// coefficient of index 0 is "<- fliplr(filter) -> (beg)", <br />// i.e., the scalar product obtained by positioning <br />// the flipped filter (formed into a row vector) <br />// with the right side positioned on top of sample beg in data.<br /><br />int filter_n_decimate(float *data,float *coef,int N,float *filter,<br /> int Nf,int beg,int ofs)<br /><br />{<br /> int i,j,k;<br /> float temp;<br /><br /> k=0;<br /> for(i=beg;i<N+beg;i+=ofs) {<br /><br /> temp=0;<br /> for(j=i;j>i-Nf;j--)<br /> temp+=data[j]*filter[i-j];<br /><br /> coef[k]=temp;<br /> k++;<br /> }<br /><br /> return(k);<br />}<br /><br />// This routine is used in evaluating inverse wavelet transforms.<br />//<br />// Upsample and filter to implement a synthesis filter bank.<br />// Basically the inverse of filter_n_decimate() above.<br />// No actual upsampling etc., to avoid zero multiplies.<br />//<br />// coef is the input and contains coefficients resulting from <br />// filtering and decimation by ofs. <br />//<br />// Because this routine is typically called twice for inverse wavelet<br />// transforms, once for the low band and once for high, data is incremented via +=.<br />// Hence data should initially be set to 0.<br />//<br />// Viewed as a transform, filter_n_decimate above starts by putting the <br />// "flipped" forward filter at begf, i.e., <- fliplr(ffilter) ->(begf)<br />// The resulting coefficient is at index 0.<br />// Here we are upsampling by ofs and filtering with the inv. filter<br />// time advanced by fbeg so the coefficient at index 0, multiplies the basis function<br />// (-fbeg)<-(ifilter)->(Nf-1-fbeg=beg).<br />// <br />// How is that for confusing? All of this makes sense,<br />// when you write it down carefully. But who has the time ...<!--emo&
--><img src='style_emoticons/<#EMO_DIR#>/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif' /><!--endemo--><br /><br />void upsample_n_filter(float *coef,float *data,int N,float *filter,<br /> int Nf,int beg,int ofs)<br /><br />{<br /> int i,j,l,n,p,fbeg;<br /> float temp;<br /><br /> fbeg=Nf-beg-1;<br /><br /> for(i=0;i<N;i++) {<br /><br /> l=0;<br /> n=(i+fbeg)%ofs;<br /> p=(i+fbeg)/ofs;<br /><br /> temp=0;<br /> for(j=n;j<Nf;j+=ofs) {<br /><br /> temp+=coef[p-l]*filter[j];<br /> l++;<br /> }<br /><br /> // += for successive calls for low and high bands. <br /> data
+=temp;<br /> }<br />}<br /><br />// Used in forward wavelet trf.<br />//<br />// All rows of the image are run through the dual filterbank<br />// given by lp and hp. Results are returned in image "in place".<br />// low freq. coefficients start at 0 and end at N/2, where high freq.<br />// info starts.<br />void filt_n_dec_all_rows(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh)<br /><br />{<br /> int i,j,ext,ofs;<br /> float *data;<br /><br /> ext=max(Nl,Nh);<br /> data=allocate_1d_float((Nj+2*ext),0);<br /> // Point in for required extensions.<br /> data+=ext;<br /><br /> // offset for the location where high band coefficients<br /> // should be copied.<br /> ofs=Nj>>1;<br /><br /> for(i=0;i<Ni;i++) {<br /> <br /> // Copy row.<br /> for(j=0;j<Nj;j++)<br /> data[j]=image
[j];<br /><br /> // Extend.<br /> if(PS)<br /> extend_periodic(data,Nj,ext);<br /> else {<br /> // Mirrors at end points.<br /> extend_mirror(data,Nj,ext,2);<br /> }<br /><br /> filter_n_decimate(data,image
,Nj,lp,Nl,begflp,2);<br /> filter_n_decimate(data,image
+ofs,Nj,hp,Nh,begfhp,2);<br /> }<br /><br /> data-=ext;<br /> free((void *)data);<br /> }<br /><br />// Used in forward wavelet trf.<br />//<br />// Index swapped version of filt_n_dec_all_rows.<br />void filt_n_dec_all_cols(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh)<br /><br />{<br /> int i,j,ext,ofs;<br /> float *data,*data2;<br /><br /> ext=max(Nl,Nh);<br /> data=allocate_1d_float((Ni+2*ext),0);<br /> // Point in for required extensions.<br /> data+=ext;<br /><br /> // Need second array since cannot access columns directly via pointers.<br /> data2=allocate_1d_float(Ni,0);<br /><br /> // offset for the location where high band coefficients<br /> // should be copied.<br /> ofs=Ni>>1;<br /><br /> for(j=0;j<Nj;j++) {<br /> <br /> // Copy column.<br /> for(i=0;i<Ni;i++)<br /> data
=image
[j];<br /><br /> // Extend.<br /> if(PS)<br /> extend_periodic(data,Ni,ext);<br /> else {<br /> // Mirrors at end points.<br /> extend_mirror(data,Ni,ext,2);<br /> }<br /><br /> filter_n_decimate(data,data2,Ni,lp,Nl,begflp,2);<br /> filter_n_decimate(data,data2+ofs,Ni,hp,Nh,begfhp,2);<br /><br /> for(i=0;i<Ni;i++)<br /> image
[j]=data2
;<br /> }<br /><br /> data-=ext;<br /> free((void *)data);<br /> free((void *)data2);<br /> }<br /><br />// Used in inverse wavelet trf.<br />//<br />// All rows of the image are run through the dual synthesis filterbank<br />// given by lp and hp having number of taps Nl and Nh respectively. <br />// Results are returned in image "in place".<br />//<br />// Here we actaully need to know the applied shift to the transform,<br />// hence the passed parameters lev and shift_arr.<br /><br />void ups_n_filt_all_rows(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh,int lev,int *shift_arr)<br /><br />{<br /> int i,j,k,ext,ofs;<br /> float *data1,*data2;<br /><br /> ext=max(Nl,Nh);<br /> ofs=Nj>>1;<br /><br /> data1=allocate_1d_float((ofs+2*ext),0);<br /> data2=allocate_1d_float((ofs+2*ext),0);<br /> data1+=ext;data2+=ext;<br /><br /> for(i=0;i<Ni;i++) { <br /><br /> for(j=0;j<ofs;j++) {<br /><br /> k=j+ofs;<br /> // low pass and high pass coefficients.<br /> data1[j]=image
[j];image
[j]=0;<br /> data2[j]=image
[k];image
[k]=0;<br /> }<br /><br /> // Take care of the extension at the boundaries.<br /> if(PS) {<br /><br /> extend_periodic(data1,ofs,ext); <br /> extend_periodic(data2,ofs,ext); <br /> }<br /> else {<br /><br /> // shift_arr[lev]=0 OR 1.<br /> // The symmetric banks used are positioned so that on the left side<br /> // the forward lowpass filter has its point of symmetry exactly on top of 0<br /> // and forward high pass filter has its point of symmetry exactly on top of 1. <br /> // This is coordinated by calling filter_n_decimate() with the proper value of beg.<br /> //<br /> // The above is reversed at the right side assuming decimation by 2. <br /> // Hence shift_arr[lev]==0 => at left boundary the mirror is at 0, <br /> // at right boundary it's between, see extend_mirror().<br /><br /> // If shift_arr[lev]==1 then the positions for the low and high are reversed<br /> // since the filters are shifted so if<br /> // shift_arr[lev]==1 => at left boundary the mirror is between, <br /> // at right boundary it's at 0.<br /> extend_mirror(data1,ofs,ext,shift_arr[lev]); <br /> extend_mirror(data2,ofs,ext,1-shift_arr[lev]); <br /> }<br /><br /> // invert low pass.<br /> upsample_n_filter(data1,image
,Nj,lp,Nl,begilp,2);<br /> // invert high pass.<br /> upsample_n_filter(data2,image
,Nj,hp,Nh,begihp,2);<br /> }<br /><br /> data1-=ext;data2-=ext;<br /> free((void *)data1);<br /> free((void *)data2);<br />}<br /><br />// Used in inverse wavelet trf.<br />//<br />// Index swapped version of ups_n_filt_all_rows.<br />void ups_n_filt_all_cols(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh,int lev,int *shift_arr)<br /><br />{<br /> int i,j,k,ext,ofs;<br /> float *data1,*data2,*data3;<br /><br /> ext=max(Nl,Nh);<br /> ofs=Ni>>1;<br /><br /> data1=allocate_1d_float((ofs+2*ext),0);<br /> data2=allocate_1d_float((ofs+2*ext),0);<br /> data1+=ext;data2+=ext;<br /><br /> // Need third array since cannot access columns directly via pointers.<br /> data3=allocate_1d_float(Ni,0);<br /><br /> for(j=0;j<Nj;j++) { <br /><br /> for(i=0;i<ofs;i++) {<br /><br /> k=i+ofs;<br /> // low pass and high pass coefficients.<br /> data1
=image
[j];<br /> data2
=image[k][j];<br /> data3
=data3[k]=0;<br /> }<br /><br /> if(PS) {<br /><br /> extend_periodic(data1,ofs,ext); <br /> extend_periodic(data2,ofs,ext); <br /> }<br /> else {<br /><br /> extend_mirror(data1,ofs,ext,shift_arr[lev]); <br /> extend_mirror(data2,ofs,ext,1-shift_arr[lev]); <br /> }<br /><br /> upsample_n_filter(data1,data3,Ni,lp,Nl,begilp,2);<br /> upsample_n_filter(data2,data3,Ni,hp,Nh,begihp,2);<br /><br /> for(i=0;i<Ni;i++)<br /> image
[j]=data3
;<br /> }<br /><br /> data1-=ext;data2-=ext;<br /> free((void *)data1);<br /> free((void *)data2);<br /> free((void *)data3);<br />}<br />
作者:
loveless
时间:
17.6.2006 16:33
以上的是Wavelet Basic的C代码。是不是把#Include <mex.h><br /><br />放在// Polytechnic University.<br /><br />#include <stdio.h> 之间?<br /><br />这个源代码本身已经包含了很多的Include,该怎么处理呢?<br />
作者:
loveless
时间:
17.6.2006 16:37
mex wav_basic.c<br />wav_basic.obj .text: undefined reference to '_allocate_1d_float' <br />wav_basic.obj .text: undefined reference to '_PS' <br />wav_basic.obj .text: undefined reference to '_begflp' <br />wav_basic.obj .text: undefined reference to '_begfhp' <br />wav_basic.obj .text: undefined reference to '_begilp' <br />wav_basic.obj .text: undefined reference to '_begihp' <br />Specified export _mexFunction is not defined <br />Missing exports. Aborting <br /> <br /> C:\
ROGRAM FILES\MATLAB704\BIN\WIN32\MEX.PL: Error: Link of 'wav_basic.dll' failed. <br /> <br />??? Error using ==> mex<br />Unable to complete successfully<br />
作者:
loveless
时间:
17.6.2006 16:38
<!--QuoteBegin-loveless+17.06.2006, 16:31 --><div class='quotetop'>QUOTE(loveless @ 17.06.2006, 16:31 )</div><div class='quotemain'><!--QuoteEBegin-->// Onur G. Guleryuz 1995, 1996, 1997,<br />// University of Illinois at Urbana-Champaign,<br />// Princeton University,<br />// Polytechnic University.<br /><br />#include <stdio.h><br />#include <stdlib.h><br />#include "wav_filters_extern.h"<br />#include "wav_gen.h"<br />#include "alloc.h"<br /><br />// Extend data by ofs pixels on both ends using periodic <br />// symmetry. data should be "pointing in" to allow up to data[-ofs]<br />// and data[N-1+ofs]. <br />// ofs>=N is handled.<br /><br />void extend_periodic(float *data,int N,int ofs)<br /><br />{<br /> int i,k;<br /><br /> k=N-1;<br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[N-i];<br /> data[k+i]=data[i-1];<br /> }<br />}<br /><br />// Extend data by ofs pixels on both ends using mirror <br />// symmetry. data should be "pointing in" to allow up to data[-ofs]<br />// and data[N-1+ofs]. <br />//<br />// There are two possible "mirrors", i.e., data[-1]=data[1] (mirror on 0) <br />// or data[-1]=data[0] (mirror "between" -1 and 0). phase is either 0, 1, or 2<br />// to select among these cases. See if(phase==... below. <br /> <br />void extend_mirror(float *data,int N,int ofs,int phase)<br /><br />{<br /> int i,k;<br /> int phase1,phase2;<br /><br /> if((phase<0)||(phase>2)) {<br /><br /> printf("extend_mirror: illegal phase\n");<br /> exit(1);<br /> }<br /><br /> if(phase==2){<br /> // At left boundary the mirror is on 0.<br /> phase1=0;<br /><br /> // At right boundary the mirror is on N-1.<br /> phase2=1;<br /> }<br /> else {<br /><br /> // phase==0, at left mirror on 0, and at right it's between.<br /> // phase==1, at left mirror between, and at right it's on N-1.<br /> phase1=phase2=phase;<br /> }<br /><br /> k=N-1;<br /> <br /> if(N==1) {<br /><br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[0];<br /> data[k+i]=data[0];<br /> }<br /> }<br /> else<br /> for(i=1;i<=ofs;i++) {<br /><br /> data[-i]=data[i-phase1];<br /> data[k+i]=data[N-phase2-i];<br /> }<br />}<br /><br />// This routine is used in evaluating forward wavelet transforms.<br />//<br />// data of dimension N contains the input.<br />// float *filter contains the Nf filter taps.<br />// ofs is the decimation factor.<br />//<br />// filtering starts at beg and continues until N+beg, yielding N/ofs samples. <br />// data needs to be padded suitably at both ends.<br />// This hoopla about the starting point is in place to ensure <br />// correct boundary processing when evaluating wavelet transforms.<br />//<br />// coef returns the result of the filtering and decimation.<br />// <br />// Viewed as a transform the basis function that generates the<br />// coefficient of index 0 is "<- fliplr(filter) -> (beg)", <br />// i.e., the scalar product obtained by positioning <br />// the flipped filter (formed into a row vector) <br />// with the right side positioned on top of sample beg in data.<br /><br />int filter_n_decimate(float *data,float *coef,int N,float *filter,<br /> int Nf,int beg,int ofs)<br /><br />{<br /> int i,j,k;<br /> float temp;<br /><br /> k=0;<br /> for(i=beg;i<N+beg;i+=ofs) {<br /><br /> temp=0;<br /> for(j=i;j>i-Nf;j--)<br /> temp+=data[j]*filter[i-j];<br /><br /> coef[k]=temp;<br /> k++;<br /> }<br /><br /> return(k);<br />}<br /><br />// This routine is used in evaluating inverse wavelet transforms.<br />//<br />// Upsample and filter to implement a synthesis filter bank.<br />// Basically the inverse of filter_n_decimate() above.<br />// No actual upsampling etc., to avoid zero multiplies.<br />//<br />// coef is the input and contains coefficients resulting from <br />// filtering and decimation by ofs. <br />//<br />// Because this routine is typically called twice for inverse wavelet<br />// transforms, once for the low band and once for high, data is incremented via +=.<br />// Hence data should initially be set to 0.<br />//<br />// Viewed as a transform, filter_n_decimate above starts by putting the <br />// "flipped" forward filter at begf, i.e., <- fliplr(ffilter) ->(begf)<br />// The resulting coefficient is at index 0.<br />// Here we are upsampling by ofs and filtering with the inv. filter<br />// time advanced by fbeg so the coefficient at index 0, multiplies the basis function<br />// (-fbeg)<-(ifilter)->(Nf-1-fbeg=beg).<br />// <br />// How is that for confusing? All of this makes sense,<br />// when you write it down carefully. But who has the time ...<!--emo&
--><img src='style_emoticons/<#EMO_DIR#>/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif' /><!--endemo--><br /><br />void upsample_n_filter(float *coef,float *data,int N,float *filter,<br /> int Nf,int beg,int ofs)<br /><br />{<br /> int i,j,l,n,p,fbeg;<br /> float temp;<br /><br /> fbeg=Nf-beg-1;<br /><br /> for(i=0;i<N;i++) {<br /><br /> l=0;<br /> n=(i+fbeg)%ofs;<br /> p=(i+fbeg)/ofs;<br /><br /> temp=0;<br /> for(j=n;j<Nf;j+=ofs) {<br /><br /> temp+=coef[p-l]*filter[j];<br /> l++;<br /> }<br /><br /> // += for successive calls for low and high bands. <br /> data
+=temp;<br /> }<br />}<br /><br />// Used in forward wavelet trf.<br />//<br />// All rows of the image are run through the dual filterbank<br />// given by lp and hp. Results are returned in image "in place".<br />// low freq. coefficients start at 0 and end at N/2, where high freq.<br />// info starts.<br />void filt_n_dec_all_rows(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh)<br /><br />{<br /> int i,j,ext,ofs;<br /> float *data;<br /><br /> ext=max(Nl,Nh);<br /> data=allocate_1d_float((Nj+2*ext),0);<br /> // Point in for required extensions.<br /> data+=ext;<br /><br /> // offset for the location where high band coefficients<br /> // should be copied.<br /> ofs=Nj>>1;<br /><br /> for(i=0;i<Ni;i++) {<br /> <br /> // Copy row.<br /> for(j=0;j<Nj;j++)<br /> data[j]=image
[j];<br /><br /> // Extend.<br /> if(PS)<br /> extend_periodic(data,Nj,ext);<br /> else {<br /> // Mirrors at end points.<br /> extend_mirror(data,Nj,ext,2);<br /> }<br /><br /> filter_n_decimate(data,image
,Nj,lp,Nl,begflp,2);<br /> filter_n_decimate(data,image
+ofs,Nj,hp,Nh,begfhp,2);<br /> }<br /><br /> data-=ext;<br /> free((void *)data);<br /> }<br /><br />// Used in forward wavelet trf.<br />//<br />// Index swapped version of filt_n_dec_all_rows.<br />void filt_n_dec_all_cols(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh)<br /><br />{<br /> int i,j,ext,ofs;<br /> float *data,*data2;<br /><br /> ext=max(Nl,Nh);<br /> data=allocate_1d_float((Ni+2*ext),0);<br /> // Point in for required extensions.<br /> data+=ext;<br /><br /> // Need second array since cannot access columns directly via pointers.<br /> data2=allocate_1d_float(Ni,0);<br /><br /> // offset for the location where high band coefficients<br /> // should be copied.<br /> ofs=Ni>>1;<br /><br /> for(j=0;j<Nj;j++) {<br /> <br /> // Copy column.<br /> for(i=0;i<Ni;i++)<br /> data
=image
[j];<br /><br /> // Extend.<br /> if(PS)<br /> extend_periodic(data,Ni,ext);<br /> else {<br /> // Mirrors at end points.<br /> extend_mirror(data,Ni,ext,2);<br /> }<br /><br /> filter_n_decimate(data,data2,Ni,lp,Nl,begflp,2);<br /> filter_n_decimate(data,data2+ofs,Ni,hp,Nh,begfhp,2);<br /><br /> for(i=0;i<Ni;i++)<br /> image
[j]=data2
;<br /> }<br /><br /> data-=ext;<br /> free((void *)data);<br /> free((void *)data2);<br /> }<br /><br />// Used in inverse wavelet trf.<br />//<br />// All rows of the image are run through the dual synthesis filterbank<br />// given by lp and hp having number of taps Nl and Nh respectively. <br />// Results are returned in image "in place".<br />//<br />// Here we actaully need to know the applied shift to the transform,<br />// hence the passed parameters lev and shift_arr.<br /><br />void ups_n_filt_all_rows(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh,int lev,int *shift_arr)<br /><br />{<br /> int i,j,k,ext,ofs;<br /> float *data1,*data2;<br /><br /> ext=max(Nl,Nh);<br /> ofs=Nj>>1;<br /><br /> data1=allocate_1d_float((ofs+2*ext),0);<br /> data2=allocate_1d_float((ofs+2*ext),0);<br /> data1+=ext;data2+=ext;<br /><br /> for(i=0;i<Ni;i++) { <br /><br /> for(j=0;j<ofs;j++) {<br /><br /> k=j+ofs;<br /> // low pass and high pass coefficients.<br /> data1[j]=image
[j];image
[j]=0;<br /> data2[j]=image
[k];image
[k]=0;<br /> }<br /><br /> // Take care of the extension at the boundaries.<br /> if(PS) {<br /><br /> extend_periodic(data1,ofs,ext); <br /> extend_periodic(data2,ofs,ext); <br /> }<br /> else {<br /><br /> // shift_arr[lev]=0 OR 1.<br /> // The symmetric banks used are positioned so that on the left side<br /> // the forward lowpass filter has its point of symmetry exactly on top of 0<br /> // and forward high pass filter has its point of symmetry exactly on top of 1. <br /> // This is coordinated by calling filter_n_decimate() with the proper value of beg.<br /> //<br /> // The above is reversed at the right side assuming decimation by 2. <br /> // Hence shift_arr[lev]==0 => at left boundary the mirror is at 0, <br /> // at right boundary it's between, see extend_mirror().<br /><br /> // If shift_arr[lev]==1 then the positions for the low and high are reversed<br /> // since the filters are shifted so if<br /> // shift_arr[lev]==1 => at left boundary the mirror is between, <br /> // at right boundary it's at 0.<br /> extend_mirror(data1,ofs,ext,shift_arr[lev]); <br /> extend_mirror(data2,ofs,ext,1-shift_arr[lev]); <br /> }<br /><br /> // invert low pass.<br /> upsample_n_filter(data1,image
,Nj,lp,Nl,begilp,2);<br /> // invert high pass.<br /> upsample_n_filter(data2,image
,Nj,hp,Nh,begihp,2);<br /> }<br /><br /> data1-=ext;data2-=ext;<br /> free((void *)data1);<br /> free((void *)data2);<br />}<br /><br />// Used in inverse wavelet trf.<br />//<br />// Index swapped version of ups_n_filt_all_rows.<br />void ups_n_filt_all_cols(float **image,int Ni,int Nj,float *lp,int Nl,<br /> float *hp,int Nh,int lev,int *shift_arr)<br /><br />{<br /> int i,j,k,ext,ofs;<br /> float *data1,*data2,*data3;<br /><br /> ext=max(Nl,Nh);<br /> ofs=Ni>>1;<br /><br /> data1=allocate_1d_float((ofs+2*ext),0);<br /> data2=allocate_1d_float((ofs+2*ext),0);<br /> data1+=ext;data2+=ext;<br /><br /> // Need third array since cannot access columns directly via pointers.<br /> data3=allocate_1d_float(Ni,0);<br /><br /> for(j=0;j<Nj;j++) { <br /><br /> for(i=0;i<ofs;i++) {<br /><br /> k=i+ofs;<br /> // low pass and high pass coefficients.<br /> data1
=image
[j];<br /> data2
=image[k][j];<br /> data3
=data3[k]=0;<br /> }<br /><br /> if(PS) {<br /><br /> extend_periodic(data1,ofs,ext); <br /> extend_periodic(data2,ofs,ext); <br /> }<br /> else {<br /><br /> extend_mirror(data1,ofs,ext,shift_arr[lev]); <br /> extend_mirror(data2,ofs,ext,1-shift_arr[lev]); <br /> }<br /><br /> upsample_n_filter(data1,data3,Ni,lp,Nl,begilp,2);<br /> upsample_n_filter(data2,data3,Ni,hp,Nh,begihp,2);<br /><br /> for(i=0;i<Ni;i++)<br /> image
[j]=data3
;<br /> }<br /><br /> data1-=ext;data2-=ext;<br /> free((void *)data1);<br /> free((void *)data2);<br /> free((void *)data3);<br />}<br />[right][snapback]1008971[/snapback][/right]<br /><!--QuoteEnd--></div><!--QuoteEEnd--><br /><br />我其实只需要Wavelet变换的代码。以上的是不是太多了?<br />
作者:
loveless
时间:
17.6.2006 17:09
那我该怎么办啊?我把东西都给你,你给我看看行吗?
作者:
loveless
时间:
17.6.2006 17:31
好的,我再看下。
作者:
loveless
时间:
17.6.2006 22:22
// Onur G. Guleryuz 1995, 1996, 1997,<br />// University of Illinois at Urbana-Champaign,<br />// Princeton University,<br />// Polytechnic University.<br /><br />#include "wav_basic.h"<br />#include "wav_filters_extern.h"<br />#include "alloc.h"<br />#include "wav_gen.h"<br /><br />// Macro that sets filter parameters.<br />// Called via choose_filter().<br />#define set_filter_param(fname) \<br />{ \<br /> MFLP= fname ## _FLP; \<br /> MFHP= fname ## _FHP; \<br /> MILP= fname ## _ILP; \<br /> MIHP= fname ## _IHP; \<br /> \<br /> /* Filter size. */ \<br /> Nflp= fname ## _Nflp; \<br /> Nfhp= fname ## _Nfhp; \<br /> Nilp= fname ## _Nilp; \<br /> Nihp= fname ## _Nihp; \<br /> \<br /> /* Filter symmetry */ \<br /> PS= fname ## _PS; \<br /> \<br /> /* Filter starting points. */ \<br /> begflp=mfl= fname ## _begflp; \<br /> begfhp=mfh= fname ## _begfhp; \<br /> begilp=mil= fname ## _begilp; \<br /> begihp=mih= fname ## _begihp; \<br />}<br /><br />// Set wavelet filter parameters depending on name<br />// and tap. See wav_filters.h and wav_filters_extern.h <br />// This routine must be called before doing any transforms<br />// to select which wavelet bank to use.<br />void choose_filter(char name,int tap)<br /><br />{<br /> switch (name) {<br /> case 'A':<br /> switch (tap) {<br /> default:<br /> set_filter_param(Antonini);<br /> }<br /> break;<br /><br /> case 'H':<br /> switch (tap) {<br /> default:<br /> set_filter_param(Haar);<br /> }<br /> break;<br /><br /> case 'N':<br /> switch (tap) {<br /> case -1:<br /> set_filter_param(Nick_flip);<br /> break;<br /><br /> default:<br /> set_filter_param(Nick);<br /> }<br /> break;<br /><br /> default:<br /> switch (tap) {<br /> case 9:<br /> set_filter_param(D79);<br /> break;<br /><br /> default:<br /> set_filter_param(D8);<br /> }<br /> }<br />}<br /><br />// 2D "in place" wavelet transform. Input data is in<br />// float **image and output is returned inside image.<br />//<br />// levs>=1 is the number of wavelet levels.<br />//<br />// Ni and Nj are the dimensions of the image.<br />// Ni and Nj should be divisible by 2^levs.<br />//<br />// shift_arr_row and shift_arr_col (each of dimension levs)<br />// contain the amount of shift (0 or 1)<br />// that should be applied to filters in each level for transforms over rows and columns.<br />// The use of shift_arr_row and shift_arr_col is mainly intended for <br />// overcomplete filtering/transforms.<br />//<br />// forw != 0 for a forward transform (inverse is calculated otherwise).<br />//<br />// float *lp of dimension Nl contains the low pass wavelet filter.<br />// float *hp of dimension Nh contains the high pass wavelet filter.<br />//<br />void wav2d_inpl(float **image,int Ni,int Nj,int levs,float *lp,int Nl,<br /> float *hp,int Nh,char forw,int *shift_arr_row,int *shift_arr_col)<br /><br />{<br /> int i,dimi,dimj;<br /><br /> dimi=(forw)?Ni
Ni>>(levs-1));<br /> dimj=(forw)?Nj
Nj>>(levs-1));<br /><br /> for(i=0;i<levs;i++) {<br /><br /> if(forw) {<br /><br /> // Do the rows.<br /><br /> // Adjust filter parameters for overcomplete filtering.<br /> begflp=mfl+shift_arr_row
; <br /> begfhp=mfh-shift_arr_row
;<br /><br /> filt_n_dec_all_rows(image,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Now the columns.<br /><br /> begflp=mfl+shift_arr_col
; <br /> begfhp=mfh-shift_arr_col
;<br /><br /> filt_n_dec_all_cols(image,dimi,dimj,lp,Nl,hp,Nh);<br /> }<br /> else {<br /><br /> // Rows.<br /> begilp=mil+shift_arr_row[levs-1-i];<br /> begihp=mih-shift_arr_row[levs-1-i];<br /><br /> ups_n_filt_all_rows(image,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_row);<br /><br /> // Columns.<br /> begilp=mil+shift_arr_col[levs-1-i];<br /> begihp=mih-shift_arr_col[levs-1-i];<br /><br /> ups_n_filt_all_cols(image,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_col);<br /> }<br /><br /> dimi=(forw)?(dimi>>1)
dimi<<1);<br /> dimj=(forw)?(dimj>>1)
dimj<<1);<br /> }<br />}<br /><br /><br /><br />// 2-D "in place" wavelet packet transform.<br />// See wav2d_inpl() for an explanation of parameters.<br />//<br />// This routine will grow a full packet tree for levels upto LL_ONLY_AFTER_LEV <br />// and just a wavelet tree afterward, i.e., if levs>LL_ONLY_AFTER_LEV<br />// we grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br />// LL_ONLY_AFTER_LEV is set in wav_gen.h Just set it to some large number<br />// if you want packets all the way.<br />// <br />// Ni and Nj should be divisible by 2^levs.<br />// shift_arr_row and shift_arr_col contain the amount of shift (0 or 1)<br />// that should be applied to filters in each level.<br />// This is mainly intended for overcomplete filtering.<br />// See wav2d_inpl() comments.<br />//<br />void wavpack2d_inpl(float **image,int Ni,int Nj,int levs,float *lp,int Nl,<br /> float *hp,int Nh,char forw,int *shift_arr_row,int *shift_arr_col)<br /><br />{<br /> int i,k,l,dimi,dimj;<br /> int p,q,rcnt,ccnt;<br /> float **buffer;<br /><br /> buffer=allocate_2d_float(Ni,Nj,0);<br /><br /> dimi=(forw)?Ni
Ni>>(levs-1));<br /> dimj=(forw)?Nj:(Nj>>(levs-1));<br /><br /> for(i=0;i<levs;i++) {<br /><br /> // Number of row bands.<br /> rcnt=Ni/dimi;<br /><br /> // Number of column bands.<br /> ccnt=Nj/dimj;<br /><br /> if(forw&&(i>=LL_ONLY_AFTER_LEV)) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /> else if((!forw)&&(levs-1-i>=LL_ONLY_AFTER_LEV)) {<br /> // Inverse wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /><br /> // Do the next level of the wavelet tree over all of<br /> // the bands we are supposed to grow on.<br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=image[p*dimi+k][q*dimj+l];<br /><br /> if(forw) {<br /><br /> // Do the rows.<br /><br /> // Adjust filter parameters for overcomplete filtering.<br /> begflp=mfl+shift_arr_row
; <br /> begfhp=mfh-shift_arr_row
;<br /><br /> filt_n_dec_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Now the columns.<br /> begflp=mfl+shift_arr_col
; <br /> begfhp=mfh-shift_arr_col
;<br /><br /> filt_n_dec_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /> }<br /> else {<br /><br /> // Rows.<br /> begilp=mil+shift_arr_row[levs-1-i];<br /> begihp=mih-shift_arr_row[levs-1-i];<br /><br /> ups_n_filt_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_row);<br /><br /> // Columns.<br /> begilp=mil+shift_arr_col[levs-1-i];<br /> begihp=mih-shift_arr_col[levs-1-i];<br /><br /> ups_n_filt_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_col);<br /> }<br /><br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> image[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /><br /> dimi=(forw)?(dimi>>1):(dimi<<1);<br /> dimj=(forw)?(dimj>>1):(dimj<<1);<br /> }<br /><br /> free_2d_float(buffer,Ni);<br />}<br /><br />// Forward complex wavelet transform using Kingsbury's paper.<br />// Please check with Nick Kingsbury's paper to confirm that<br />// I am doing things correctly here.<br />//<br />// Input is in float **im, and the results are returned in 4<br />// **float's, trf[0],...,trf[3].<br />//<br />// Ni, Nj multiples of 2^levs.<br />// levs>=1.<br />// See wav2d_inpl() for an explanation of parameters.<br />//<br />void complex_wav_forw(float **im,float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // First level, fully overcomplete resulting 4x redundancy.<br /> // Results are in trf
.<br /> for(i=0;i<4;i++) {<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> trf
[k][l]=im[k][l];<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Transform.<br /> wav2d_inpl(trf
,Ni,Nj,1,lp,Nl,hp,Nh,1,shift_arr_r,shift_arr_c);<br /> }<br /><br /> // Now grow complex wavelets over the LL band<br /> // using Kingsbury's orthogonal bank.<br /> if(levs>1) {<br /><br /> for(i=0;i<4;i++) {<br /><br /> dimi=Ni/2;<br /> dimj=Nj/2;<br /> for(j=1;j<levs;j++) {<br /> <br /> if(i/2==0) {<br /> // Regular orth. bank.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped orth. bank (see Kingsbury).<br /> // Flipped is same as inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over rows.<br /> filt_n_dec_all_rows(trf
,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> if(i%2==0) {<br /> // Regular.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over columns.<br /> filt_n_dec_all_cols(trf
,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> dimi>>=1;<br /> dimj>>=1;<br /> <br /> }<br /> }<br /> }<br /><br /> // Generate the complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // After this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=trf[0][k][l]+trf[3][k][l];<br /> trf[3][k][l]=trf[0][k][l]-trf[3][k][l];<br /> trf[0][k][l]=tmp;<br /><br /> tmp=trf[1][k][l]+trf[2][k][l];<br /> // It is possible that the below is 2 - 1.<br /> trf[2][k][l]=trf[1][k][l]-trf[2][k][l];<br /> trf[1][k][l]=tmp;<br /> }<br />}<br /><br />// Inverse complex wavelet transform.<br />// trf is modified in intermediate computations.<br />// Ni, Nj multiples of 2^levs<br />// levs>=1.<br />//<br />// See complex_wav_forw() comments.<br />//<br />float **complex_wav_inv(float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /> float **im;<br /><br /><br /> // Clean the filter shift arrays.<br /> for(i=0;i<1<<levs;i++)<br /> shift_arr_r
=shift_arr_c
=0;<br /><br /> // Get back the intermediate wavelet coefficients from the<br /> // complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // Prior to this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=(trf[0][k][l]+trf[3][k][l])/2;<br /> trf[3][k][l]=(trf[0][k][l]-trf[3][k][l])/2;<br /> trf[0][k][l]=tmp;<br /><br /> tmp=(trf[1][k][l]+trf[2][k][l])/2;<br /> trf[2][k][l]=(trf[1][k][l]-trf[2][k][l])/2;<br /> trf[1][k][l]=tmp;<br /> }<br /><br /> if(levs>1) {<br /><br /> for(i=0;i<4;i++) {<br /> <br /> dimi=Ni>>(levs-1);<br /> dimj=Nj>>(levs-1);<br /> <br /> <br /> for(j=1;j<levs;j++) {<br /> <br /> if(i/2==0) {<br /> // Regular inverse, it just happens that orth. inverses are flipped.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over rows.<br /> ups_n_filt_all_rows(trf
,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_r);<br /> <br /> <br /> if(i%2==0) {<br /> // Regular inverse.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over columns.<br /> ups_n_filt_all_cols(trf
,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_c);<br /> <br /> dimi<<=1;<br /> dimj<<=1;<br /> }<br /> }<br /> }<br /><br /> // Initialize final result with zeros.<br /> im=allocate_2d_float(Ni,Nj,1);<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Now the first level.<br /> for(i=0;i<4;i++) {<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Inverse transform.<br /> wav2d_inpl(trf
,Ni,Nj,1,lp,Nl,hp,Nh,0,shift_arr_r,shift_arr_c);<br /><br /> // Accumulate the results of 4x redundancy.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]+=trf
[k][l];<br /><br /> }<br /><br /> // Normalize results by 4 to account for 4x redundancy accumulation.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]/=4;<br /><br /> return(im);<br />}<br /><br /><br />// Forward complex wavelet packet transform.<br />// Ni, Nj multiples of 2^levs.<br />// levs>=1.<br />//<br />// See complex_wav_forw() comments.<br />// See wavpack2d_inpl() comments for LL_ONLY_AFTER_LEV.<br />//<br />// Not fully tested. Please check with literature.<br />//<br />void complex_wav_pack_forw(float **im,float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp,**buffer;<br /> int p,q,rcnt,ccnt;<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // First level, fully overcomplete resulting 4x redundancy.<br /> // Results are in trf
.<br /> for(i=0;i<4;i++) {<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> trf
[k][l]=im[k][l];<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Transform.<br /> wav2d_inpl(trf
,Ni,Nj,1,lp,Nl,hp,Nh,1,shift_arr_r,shift_arr_c);<br /> }<br /><br /> // Now grow using Kingsbury's orthogonal bank.<br /> if(levs>1) {<br /><br /> buffer=allocate_2d_float(Ni/2,Nj/2,0);<br /><br /> for(i=0;i<4;i++) {<br /><br /> dimi=Ni/2;<br /> dimj=Nj/2;<br /> for(j=1;j<levs;j++) {<br /><br /> // Number of row/column bands.<br /> rcnt=Ni/dimi;<br /> ccnt=Nj/dimj;<br /><br /> if(j>=LL_ONLY_AFTER_LEV) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /> <br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> // Copy data to buffer.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=trf
[p*dimi+k][q*dimj+l];<br /> <br /> if(i/2==0) {<br /> // Regular orth. bank.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped orth. bank (see Kingsbury).<br /> // Flipped is same as inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over rows.<br /> filt_n_dec_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> if(i%2==0) {<br /> // Regular.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over columns.<br /> filt_n_dec_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Copy results to trf
.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> trf
[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /> <br /> dimi>>=1;<br /> dimj>>=1;<br /> <br /> }<br /> }<br /> free_2d_float(buffer,Ni/2);<br /> }<br /><br /> // Generate the complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // After this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=trf[0][k][l]+trf[3][k][l];<br /> trf[3][k][l]=trf[0][k][l]-trf[3][k][l];<br /> trf[0][k][l]=tmp;<br /><br /> tmp=trf[1][k][l]+trf[2][k][l];<br /> trf[2][k][l]=trf[1][k][l]-trf[2][k][l];<br /> trf[1][k][l]=tmp;<br /> }<br />}<br /><br />// Inverse complex wavelet packet transform.<br />// trf is modified in intermediate computations.<br />// Ni, Nj multiples of 2^levs<br />// levs>=1.<br />//<br />// See complex_wav_pack_forw() comments.<br />//<br />float **complex_wav_pack_inv(float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /> float **im,**buffer;<br /> int p,q,rcnt,ccnt;<br /><br /><br /> // Clean the filter shift arrays.<br /> for(i=0;i<1<<levs;i++)<br /> shift_arr_r
=shift_arr_c
=0;<br /><br /> // Get back the intermediate wavelet coefficients from the<br /> // complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // Prior to this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=(trf[0][k][l]+trf[3][k][l])/2;<br /> trf[3][k][l]=(trf[0][k][l]-trf[3][k][l])/2;<br /> trf[0][k][l]=tmp;<br /><br /> tmp=(trf[1][k][l]+trf[2][k][l])/2;<br /> trf[2][k][l]=(trf[1][k][l]-trf[2][k][l])/2;<br /> trf[1][k][l]=tmp;<br /> }<br /><br /> if(levs>1) {<br /><br /> buffer=allocate_2d_float(Ni/2,Nj/2,0);<br /> for(i=0;i<4;i++) {<br /> <br /> dimi=Ni>>(levs-1);<br /> dimj=Nj>>(levs-1);<br /> <br /> <br /> for(j=1;j<levs;j++) {<br /> <br /> // Number of row/column bands.<br /> rcnt=Ni/dimi;<br /> ccnt=Nj/dimj;<br /><br /> if(j>=LL_ONLY_AFTER_LEV) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /><br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> // Copy data to buffer.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=trf
[p*dimi+k][q*dimj+l];<br /><br /> if(i/2==0) {<br /> // Regular inverse, it just happens that orth. inverses are flipped.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over rows.<br /> ups_n_filt_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_r);<br /> <br /> <br /> if(i%2==0) {<br /> // Regular inverse.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over columns.<br /> ups_n_filt_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_c);<br /><br /> // Copy results to trf
.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> trf
[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /> <br /> dimi<<=1;<br /> dimj<<=1;<br /> }<br /> }<br /><br /> free_2d_float(buffer,Ni/2);<br /> }<br /><br /> // Initialize final result with zeros.<br /> im=allocate_2d_float(Ni,Nj,1);<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Now the first level.<br /> for(i=0;i<4;i++) {<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Inverse transform.<br /> wav2d_inpl(trf
,Ni,Nj,1,lp,Nl,hp,Nh,0,shift_arr_r,shift_arr_c);<br /><br /> // Accumulate the results of 4x redundancy.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]+=trf
[k][l];<br /><br /> }<br /><br /> // Normalize results by 4 to account for 4x redundancy accumulation.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]/=4;<br /><br /> return(im);<br />}
作者:
loveless
时间:
17.6.2006 22:25
我实在看得不行了,这个是不是正宗的Wavelet Transformation?<br /><br />那个很多的,是不是很多多余的?
欢迎光临 德国开元华人社区 开元周游 (https://forum.kaiyuan.cn/)
Powered by Discuz! X3.2