基于opencv的小波变换代码和图像结果

时间:2024-03-06 22:39:07
  1 #include "stdafx.h"
  2 #include "WaveTransform.h"
  3 #include <math.h>
  4 #include <imgproc/imgproc.hpp>

5 Mat WaveTransform::WDT(const Mat &_src,const string _wname,const int _level) 6 { 7 Mat src=Mat_<float>(_src); 8 Mat dst=Mat::zeros(src.rows,src.cols,src.type()); 9 int N=src.rows; 10 int D=src.cols; 11 //高通低通滤波器 12 Mat lowFilter; 13 Mat highFilter; 14 wavelet(_wname,lowFilter,highFilter); 15 //小波变换 16 int t=1; 17 int row=N; 18 int col=D; 19 while (t<=_level) 20 { 21 //先进行 行小波变换 22 for (int i=0;i<row;i++) 23 { 24 //取出src中要处理的数据的一行 25 Mat oneRow=Mat::zeros(1,col,src.type()); 26 for (int j=0;j<col;j++) 27 { 28 oneRow.at<float>(0,j)=src.at<float>(i,j); 29 } 30 oneRow=waveletDecompose(oneRow,lowFilter,highFilter); 31 for (int j=0;j<col;j++) 32 { 33 dst.at<float>(i,j)=oneRow.at<float>(0,j); 34 } 35 } 36 char s[10]; 37 itoa(t,s,10); 38 imshow(s,dst); 39 waitKey(); 40 #if 0 41 // normalize(dst,dst,0,255,NORM_MINMAX); 42 IplImage dstImg1=IplImage(dst); 43 cvSaveImage("dst1.jpg",&dstImg1); 44 #endif 45 46 //小波列变换 47 for (int j=0;j<col;j++) 48 { 49 Mat oneCol=Mat::zeros(row,1,src.type()); 50 for (int i=0;i<row;i++) 51 { 52 oneCol.at<float>(i,0)=dst.at<float>(i,j);//dst,not src 53 } 54 oneCol=(waveletDecompose(oneCol.t(),lowFilter,highFilter)).t(); 55 for (int i=0;i<row;i++) 56 { 57 dst.at<float>(i,j)=oneCol.at<float>(i,0); 58 } 59 } 60 #if 0 61 // normalize(dst,dst,0,255,NORM_MINMAX); 62 IplImage dstImg2=IplImage(dst); 63 cvSaveImage("dst2.jpg",&dstImg2); 64 #endif 65 //更新 66 row/=2; 67 col/=2; 68 t++; 69 src=dst; 70 71 } 72 return dst; 73 } 74
75 //生成不同类型的小波 76 void WaveTransform::wavelet( const string _wname, Mat &_lowFilter, Mat &_highFilter ) 77 { 78 79 if (_wname=="haar" || _wname=="db1") 80 { 81 int N=2; 82 _lowFilter=Mat::zeros(1,N,CV_32F); 83 _highFilter=Mat::zeros(1,N,CV_32F); 84 85 _lowFilter.at<float>(0,0)=1/sqrtf(N); 86 _lowFilter.at<float>(0,1)=1/sqrtf(N); 87 88 _highFilter.at<float>(0,0)=-1/sqrtf(N); 89 _highFilter.at<float>(0,1)=1/sqrtf(N); 90 } 91 if (_wname=="sym2") 92 { 93 int N=4; 94 float h[]={-0.483, 0.836, -0.224, -0.129}; 95 float l[]={-0.129, 0.224, 0.837, 0.483}; 96 97 _lowFilter=Mat::zeros(1,N,CV_32F); 98 _highFilter=Mat::zeros(1,N,CV_32F); 99 100 for (int i=0;i<N;i++) 101 { 102 _lowFilter.at<float>(0,i)=l[i]; 103 _highFilter.at<float>(0,i)=h[i]; 104 } 105 } 106 107 } 108
109 //小波分解 110 Mat WaveTransform::waveletDecompose( const Mat &_src, const Mat &_lowFilter, const Mat &_highFilter ) 111 { 112 assert(_src.rows==1 && _lowFilter.rows==1 && _highFilter.rows ==1); 113 assert(_src.cols>=_lowFilter.cols && _src.cols>=_highFilter.cols ); 114 Mat &src=Mat_<float>(_src); 115 116 int D=src.cols; 117 118 Mat &lowFilter=Mat_<float>(_lowFilter); 119 Mat &highFilter=Mat_<float>(_highFilter); 120 121 //频域滤波或时域卷积;ifft( fft(x) * fft(filter)) = cov(x,filter) 122 Mat dst1=Mat::zeros(1,D,src.type()); 123 Mat dst2=Mat::zeros(1,D,src.type()); 124 125 filter2D(src,dst1,-1,lowFilter); 126 filter2D(src,dst2,-1,highFilter); 127 128 //下采样 129 Mat downDst1=Mat::zeros(1,D/2,src.type()); 130 Mat downDst2=Mat::zeros(1,D/2,src.type()); 131 132 resize(dst1,downDst1,downDst1.size()); 133 resize(dst2,downDst2,downDst2.size()); 134 135 //数据拼接 136 for (int i=0;i<D/2;i++) 137 { 138 src.at<float>(0,i)=downDst1.at<float>(0,i); 139 src.at<float>(0,i+D/2)=downDst2.at<float>(0,i); 140 141 } 142 return src; 143 }

用main函数调用WDT

Mat imgWave=m_waveTransform.WDT(src,"haar",3);
imshow("img",Mat_<uchar>(imgWave));
waitKey();

用一张考拉图来分析小波变换过程:

原图:

3层小波变换结果图(图片有压缩):

下面逐一分析:

1 只做完小波行变换

2 行列变换

3 再次行变换

4 再次行列变换

三次之后到最后的分解图。

代码来自:http://shijuanfeng.blogbus.com/logs/221385402.html