您的位置:首页 > 编程语言 > C语言/C++

小波变换 C++ opencv 实现

2015-06-19 19:51 477 查看

小波变换C++opencv实现

小波简介:http://www.blogbus.com/shijuanfeng-logs/221293135.html

源码:


[code]///小波变换
MatWDT(constMat&_src,conststring_wname,constint_level)const

{
intreValue=THID_ERR_NONE;
Matsrc=Mat_<float>(_src);
Matdst=Mat::zeros(src.rows,src.cols,src.type());
intN=src.rows;
intD=src.cols;
///高通低通滤波器
MatlowFilter;
MathighFilter;
wavelet(_wname,lowFilter,highFilter);
///小波变换
intt=1;
introw=N;
intcol=D;
while(t<=_level)
{
///先进行行小波变换
for(inti=0;i<row;i++)
{
///取出src中要处理的数据的一行
MatoneRow=Mat::zeros(1,col,src.type());
for(intj=0;j<col;j++)
{
oneRow.at<float>(0,j)=src.at<float>(i,j);
}
oneRow=waveletDecompose(oneRow,lowFilter,highFilter);
///将src这一行置为oneRow中的数据
for(intj=0;j<col;j++)
{
dst.at<float>(i,j)=oneRow.at<float>(0,j);
}
}

#if0
//normalize(dst,dst,0,255,NORM_MINMAX);
IplImagedstImg1=IplImage(dst);
cvSaveImage("dst.jpg",&dstImg1);

#endif
///小波列变换
for(intj=0;j<col;j++)
{
///取出src数据的一行输入
MatoneCol=Mat::zeros(row,1,src.type());
for(inti=0;i<row;i++)
{
oneCol.at<float>(i,0)=dst.at<float>(i,j);
}
oneCol=(waveletDecompose(oneCol.t(),lowFilter,highFilter)).t();
for(inti=0;i<row;i++)
{
dst.at<float>(i,j)=oneCol.at<float>(i,0);
}
}

#if0
//normalize(dst,dst,0,255,NORM_MINMAX);
IplImagedstImg2=IplImage(dst);
cvSaveImage("dst.jpg",&dstImg2);

#endif
///更新
row/=2;
col/=2;
t++;
src=dst;
}
returndst;

}

///小波逆变换

MatIWDT(constMat&_src,conststring_wname,constint_level)const

{
intreValue=THID_ERR_NONE;
Matsrc=Mat_<float>(_src);
Matdst=Mat::zeros(src.rows,src.cols,src.type());
intN=src.rows;
intD=src.cols;
///高通低通滤波器
MatlowFilter;
MathighFilter;
wavelet(_wname,lowFilter,highFilter);
///小波变换
intt=1;
introw=N/std::pow(2.,_level-1);
intcol=D/std::pow(2.,_level-1);
while(row<=N&&col<=D)
{
///小波列逆变换
for(intj=0;j<col;j++)
{
///取出src数据的一行输入
MatoneCol=Mat::zeros(row,1,src.type());
for(inti=0;i<row;i++)
{
oneCol.at<float>(i,0)=src.at<float>(i,j);
}
oneCol=(waveletReconstruct(oneCol.t(),lowFilter,highFilter)).t();
for(inti=0;i<row;i++)
{
dst.at<float>(i,j)=oneCol.at<float>(i,0);
}
}

#if0
//normalize(dst,dst,0,255,NORM_MINMAX);
IplImagedstImg2=IplImage(dst);
cvSaveImage("dst.jpg",&dstImg2);

#endif
///行小波逆变换
for(inti=0;i<row;i++)
{
///取出src中要处理的数据的一行
MatoneRow=Mat::zeros(1,col,src.type());
for(intj=0;j<col;j++)
{
oneRow.at<float>(0,j)=dst.at<float>(i,j);
}
oneRow=waveletReconstruct(oneRow,lowFilter,highFilter);
///将src这一行置为oneRow中的数据
for(intj=0;j<col;j++)
{
dst.at<float>(i,j)=oneRow.at<float>(0,j);
}
}

#if0
//normalize(dst,dst,0,255,NORM_MINMAX);
IplImagedstImg1=IplImage(dst);
cvSaveImage("dst.jpg",&dstImg1);

#endif
row*=2;
col*=2;
src=dst;
}
returndst;

}

////////////////////////////////////////////////////////////////////////////////////////////

///调用函数

///生成不同类型的小波,现在只有haar,sym2

voidwavelet(conststring_wname,Mat&_lowFilter,Mat&_highFilter)const

{
if(_wname=="haar"||_wname=="db1")
{
intN=2;
_lowFilter=Mat::zeros(1,N,CV_32F);
_highFilter=Mat::zeros(1,N,CV_32F);
_lowFilter.at<float>(0,0)=1/sqrtf(N);
_lowFilter.at<float>(0,1)=1/sqrtf(N);
_highFilter.at<float>(0,0)=-1/sqrtf(N);
_highFilter.at<float>(0,1)=1/sqrtf(N);
}
if(_wname=="sym2")
{
intN=4;
floath[]={-0.483,0.836,-0.224,-0.129};
floatl[]={-0.129,0.224,0.837,0.483};
_lowFilter=Mat::zeros(1,N,CV_32F);
_highFilter=Mat::zeros(1,N,CV_32F);
for(inti=0;i<N;i++)
{
_lowFilter.at<float>(0,i)=l[i];
_highFilter.at<float>(0,i)=h[i];
}
}

}

///小波分解

MatwaveletDecompose(constMat&_src,constMat&_lowFilter,constMat&_highFilter)const

{
assert(_src.rows==1&&_lowFilter.rows==1&&_highFilter.rows==1);
assert(_src.cols>=_lowFilter.cols&&_src.cols>=_highFilter.cols);
Mat&src=Mat_<float>(_src);
intD=src.cols;
Mat&lowFilter=Mat_<float>(_lowFilter);
Mat&highFilter=Mat_<float>(_highFilter);
///频域滤波,或时域卷积;ifft(fft(x)*fft(filter))=cov(x,filter)
Matdst1=Mat::zeros(1,D,src.type());
Matdst2=Mat::zeros(1,D,src.type());
filter2D(src,dst1,-1,lowFilter);
filter2D(src,dst2,-1,highFilter);
///下采样
MatdownDst1=Mat::zeros(1,D/2,src.type());
MatdownDst2=Mat::zeros(1,D/2,src.type());
resize(dst1,downDst1,downDst1.size());
resize(dst2,downDst2,downDst2.size());
///数据拼接
for(inti=0;i<D/2;i++)
{
src.at<float>(0,i)=downDst1.at<float>(0,i);
src.at<float>(0,i+D/2)=downDst2.at<float>(0,i);
}
returnsrc;

}

///小波重建

MatwaveletReconstruct(constMat&_src,constMat&_lowFilter,constMat&_highFilter)const

{
assert(_src.rows==1&&_lowFilter.rows==1&&_highFilter.rows==1);
assert(_src.cols>=_lowFilter.cols&&_src.cols>=_highFilter.cols);
Mat&src=Mat_<float>(_src);
intD=src.cols;
Mat&lowFilter=Mat_<float>(_lowFilter);
Mat&highFilter=Mat_<float>(_highFilter);
///插值;
MatUp1=Mat::zeros(1,D,src.type());
MatUp2=Mat::zeros(1,D,src.type());
///插值为0
//for(inti=0,cnt=1;i<D/2;i++,cnt+=2)
//{
//Up1.at<float>(0,cnt)=src.at<float>(0,i);///<前一半
//Up2.at<float>(0,cnt)=src.at<float>(0,i+D/2);///<后一半
//}
///线性插值
Matroi1(src,Rect(0,0,D/2,1));
Matroi2(src,Rect(D/2,0,D/2,1));
resize(roi1,Up1,Up1.size(),0,0,INTER_CUBIC);
resize(roi2,Up2,Up2.size(),0,0,INTER_CUBIC);
///前一半低通,后一半高通
Matdst1=Mat::zeros(1,D,src.type());
Matdst2=Mat::zeros(1,D,src.type());
filter2D(Up1,dst1,-1,lowFilter);
filter2D(Up2,dst2,-1,highFilter);
///结果相加
dst1=dst1+dst2;
returndst1;

}

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: