小波变换 C++ opencv 实现
2015-06-19 19:51
477 查看
小波变换C++opencv实现
小波简介:源码:
[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]
相关文章推荐
- Windows下,Netbeans使用C++的配置方法
- c++map的用法
- C语言回顾(二、顺序程序及大数相加)——iOS开发基础
- c++map的用法 分类: POJ 2015-06-19 18:36 11人阅读 评论(0) 收藏
- C++陪我走过的一年
- C++ 类的大小计算
- 在C#中使用C++编写的类
- C++笔记整理
- 在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)
- LeetCode 之 Largest Number — C++ 实现
- 两个基于C++-Qt的开源WEB框架
- C99 c语言特性 数组可以这样初使化
- C/C++&java communicate with each other 之 video file-streaming
- 【C++探索之旅】第一部分第二课:C++编程的必要软件
- C/C++&java communicate with each other 之 video snapshot
- C语言回顾(一、C简介及基础知识)——iOS开发基础
- Bjarne Stroustrup对C++程序员的忠告
- Bjarne Stroustrup对C++程序员的忠告
- LeetCode 之 Two Sum — C++ 实现
- C++初始化列表