python实现小波变换_小波分解,去噪,重构

在此稍微说一下小波阈值去噪。手写程序,不调用函数。目的是用来解决各个学校的大作业问题。不用来解决任何实际问题。

首先要了解一下小波变换从老根上讲就是做卷积。一个信号,或者一个图片,与小波的高通部分做卷积,得出的系数是高频系数,与小波的低通部分做卷积得出低频系数。

以一张图片小波阈值去噪为例,讲一下整个编程过程。

第一是准备阶段:一张图片是三种数据:高度、宽度和色彩度。编程以经典的二维小波变换为例,所以要去掉图片的色彩度(命令自己搜,这里建议用Matlab,Matlab软件天下第一,垃圾C++,垃圾python)。对图片加入噪声,可以选择高斯噪声或者椒盐噪声,以高斯噪声为例,选好合适的噪声方差和均值。到此准备阶段结束。

第二是小波分解过程:读取加入噪声后的图片后,数据即是高度*宽度个数据点。对此矩阵数据要做二维离散小波分解,二维小波变换和一维小波变换的区别从原理上来说就是一和二的关系。首先对数据做行分解,写入循环,有多少行就做多少次小波分解。对于每一行的数据来说,做小波分解就是一维的,而一维小波分解就是咱们要写的程序中的基石。选择小波,以Haar小波为例,也叫db1,用函数调用此小波,将咱们的数据(就是之前的行数据)先与高通做卷积得出高频系数,这里建议卷积过程别手写,计算太慢了,计算函数直接调用即可。然后使用下采样得出高频系数cD,再与低通做卷积加下采样得出低频系数cA。这里说明一下由于是下采样,所以得到的每个系数矩阵是原矩阵的一半大小。最后将低频系数cA和高频系数cD组成系数矩阵。这是一次小波分解,如果需要二次小波分解,则是按照小波分解定义,将第一次小波分解的低频系数cA作为第二次分解的输入重复卷积和采样操作,再得出新的cA、cD,编程写循环即可。回到咱们每一行都做一维小波分解,将做完行分解后得到的新矩阵再对每一列进行列分解,按照同样的道理将系数组合起来得到最终的矩阵(这里注意一下行分解的矩阵和列分解的矩阵在组合系数时的行列转换问题)。最终的矩阵分为四块,左上角是低频系数cA,其余三块分别是高频系数cH、cV、cD,具体形式是[cA,cH;cV,cD]。别忘了一维小波分解咱们能做好几次,二维也是,用同样的道理,低频系数cA进入下一层,还是先做行分解再做列分解然后出结果,也是写循环解决。到此小波分解结束。

第三是小波阈值降噪过程:不进行任何理论讲解。直接说明阈值降噪分为两种,一种是硬阈值降噪,一种是软阈值降噪。根据本人学习来看,理论上对最后一次小波分解降噪就行,不用每层都降噪。但是如果选择每层都降噪,出来的结果只有稍稍多了一些平滑效果,感觉并没有太多变化。无所谓了,不管了。不管哪种降噪都要先计算阈值,以固定阈值为例,固定阈值计算方式为:当前小波系数绝对值的中间值【sigma*(2ln(N))^1/2】/0.6745。如果每层都想做降噪就用每层的小波系数把每层的阈值都计算出来。(这里说一下N是数据长度,如果是二维就是矩阵元素的个数行*列)。现在先说硬阈值降噪,硬阈值降噪是将高频的每个系数都与阈值作比较,如果大于等于阈值就不做变化,如果小于阈值就让数剧等于零。同理如果每层都做降噪,就将每层的高频系数矩阵都与该层的阈值作比较。再说软阈值降噪,也是将高频的每个系数都与阈值作比较,如果大于等于阈值就领其减去阈值,如果小于阈值就让数据等于零。如果每层都做还是老方法。这里说一下注意情况,为了后续手写程序方便,建议高频系数降噪时讲cV、cD、cH分开,到时候好重组。

第四就是最后的小波重构过程:小波重构过程与小波分解过程整个是相反的。同样二维重构要用到一维重构,但从数学角度讲,虽然逻辑相同但是相对复杂一些。对于降噪后的矩阵重新组合成[rcA,rcH;rcV,rcD]形式(其中rcA是低频系数就是原来最后一层的cA)。先进行列重构,由矩阵形式可知,对于每一列,从行来看上面一半行数是低频系数,后面一半行数是高频系数,所以分开,然后使用一维重构函数进行行重构。一维重构函数与一维分解函数相反,先对低频系数上采样(因为分解咱们每次都是分解低频系数,所以重构也是搞低频),采样过程中缺的地方补0。然后与小波重构做低通卷积,从重构出的结果先找出cD中的高频系数,大小与cA相同。然后对找到的高频系数cD进行上抽样,然后做高通卷积。与分解同理,反推,新cA应该等于高频加低频系数,新cA进行下一层重构。重新回到列重构,每一列都做列重构,做完之后变为新矩阵,然后对新矩阵再做行重构,与分解函数相同,这里重构函数也是对上个矩阵再进行变化。同理将输出矩阵 y 的每一行,分开成左右两半,分开的两部分分别作为高频和低频系数,同理重构序列。分解几层就重构几层,最后重构出的低频系数cA就是咱们的最终结果。其实最后一次重构出的新cA,不应该叫低频系数,因为没有下一层重构了,这个结果就是咱们想要的图片数据。

最后输出这个cA就行,与MATLAB自带的分解去噪和重构函数效果相比,手写函数计算效果会差很多,因为在分解系数矩阵时,有的时候无法做到二等分,会舍弃点,而且采样过程写的也不好,而且二维分解重构嵌套一维分解重构函数写的也不是太好。所以效果不尽如人意。但终归能用。

你可能感兴趣的:(python实现小波变换)