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

时间:2023-03-09 15:30:39
基于opencv的小波变换代码和图像结果
 #include "stdafx.h"
#include "WaveTransform.h"
#include <math.h>
#include <imgproc/imgproc.hpp> Mat WaveTransform::WDT(const Mat &_src,const string _wname,const int _level)
{
Mat src=Mat_<float>(_src);
Mat dst=Mat::zeros(src.rows,src.cols,src.type());
int N=src.rows;
int D=src.cols;
//高通低通滤波器
Mat lowFilter;
Mat highFilter;
wavelet(_wname,lowFilter,highFilter);
//小波变换
int t=;
int row=N;
int col=D;
while (t<=_level)
{
//先进行 行小波变换
for (int i=;i<row;i++)
{
//取出src中要处理的数据的一行
Mat oneRow=Mat::zeros(,col,src.type());
for (int j=;j<col;j++)
{
oneRow.at<float>(,j)=src.at<float>(i,j);
}
oneRow=waveletDecompose(oneRow,lowFilter,highFilter);
for (int j=;j<col;j++)
{
dst.at<float>(i,j)=oneRow.at<float>(,j);
}
}
char s[];
itoa(t,s,);
imshow(s,dst);
waitKey();
#if 0
// normalize(dst,dst,0,255,NORM_MINMAX);
IplImage dstImg1=IplImage(dst);
cvSaveImage("dst1.jpg",&dstImg1);
#endif //小波列变换
for (int j=;j<col;j++)
{
Mat oneCol=Mat::zeros(row,,src.type());
for (int i=;i<row;i++)
{
oneCol.at<float>(i,)=dst.at<float>(i,j);//dst,not src
}
oneCol=(waveletDecompose(oneCol.t(),lowFilter,highFilter)).t();
for (int i=;i<row;i++)
{
dst.at<float>(i,j)=oneCol.at<float>(i,);
}
}
#if 0
// normalize(dst,dst,0,255,NORM_MINMAX);
IplImage dstImg2=IplImage(dst);
cvSaveImage("dst2.jpg",&dstImg2);
#endif
//更新
row/=;
col/=;
t++;
src=dst; }
return dst;
}

//生成不同类型的小波
void WaveTransform::wavelet( const string _wname, Mat &_lowFilter, Mat &_highFilter )
{ if (_wname=="haar" || _wname=="db1")
{
int N=;
_lowFilter=Mat::zeros(,N,CV_32F);
_highFilter=Mat::zeros(,N,CV_32F); _lowFilter.at<float>(,)=/sqrtf(N);
_lowFilter.at<float>(,)=/sqrtf(N); _highFilter.at<float>(,)=-/sqrtf(N);
_highFilter.at<float>(,)=/sqrtf(N);
}
if (_wname=="sym2")
{
int N=;
float h[]={-0.483, 0.836, -0.224, -0.129};
float l[]={-0.129, 0.224, 0.837, 0.483}; _lowFilter=Mat::zeros(,N,CV_32F);
_highFilter=Mat::zeros(,N,CV_32F); for (int i=;i<N;i++)
{
_lowFilter.at<float>(,i)=l[i];
_highFilter.at<float>(,i)=h[i];
}
} }

//小波分解
Mat WaveTransform::waveletDecompose( const Mat &_src, const Mat &_lowFilter, const Mat &_highFilter )
{
assert(_src.rows== && _lowFilter.rows== && _highFilter.rows ==);
assert(_src.cols>=_lowFilter.cols && _src.cols>=_highFilter.cols );
Mat &src=Mat_<float>(_src); int D=src.cols; Mat &lowFilter=Mat_<float>(_lowFilter);
Mat &highFilter=Mat_<float>(_highFilter); //频域滤波或时域卷积;ifft( fft(x) * fft(filter)) = cov(x,filter)
Mat dst1=Mat::zeros(,D,src.type());
Mat dst2=Mat::zeros(,D,src.type()); filter2D(src,dst1,-,lowFilter);
filter2D(src,dst2,-,highFilter); //下采样
Mat downDst1=Mat::zeros(,D/,src.type());
Mat downDst2=Mat::zeros(,D/,src.type()); resize(dst1,downDst1,downDst1.size());
resize(dst2,downDst2,downDst2.size()); //数据拼接
for (int i=;i<D/;i++)
{
src.at<float>(,i)=downDst1.at<float>(,i);
src.at<float>(,i+D/)=downDst2.at<float>(,i); }
return src;
}

用main函数调用WDT

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

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

原图:

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

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

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

下面逐一分析:

1 只做完小波行变换

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

2 行列变换

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

3 再次行变换

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

4 再次行列变换

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

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

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