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

基于opencv的小波变换的实现代码

2017-12-19 23:22 435 查看
本文主要是实现的是harr,symlet小波的多层分解,分解之后可以取HL,LH分量。实现代码如下:

#include <iostream>

#include "wavedec1.h"

#include <math.h>

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <string>

#include <vector>

//#include <stadio.h>

using namespace std;

using namespace cv;

Mat WDT(Mat & _src,string _wname,int _level)

{
Mat src;
_src.convertTo(src,CV_32F);
Mat dst = Mat::zeros(src.rows,src.cols,src.type());
int N =src.rows;
int D =src.cols;
Mat lowFilter, highFilter;
wavelet(_wname,lowFilter,highFilter);
int t=1 ;
int row=N;
int col=D;
while(t<=_level)
{
for (int i=0;i<row;i++)
{
Mat oneRow = Mat::zeros(1,col,src.type());
for (int j=0;j<col;j++)
{
oneRow.at<float>(0,j) =src.at<float>(i,j);
}
oneRow=waveletDecompose(oneRow,lowFilter,highFilter);
for (int j=0;j<col;j++)
{
dst.at<float>(i,j)=oneRow.at<float>(0,j);
}
}

#if 0
char s[10];
itoa(t,s,10);
imshow(s,dst);
waitKey();

#endif
for (int j=0;j<col;j++)
{
Mat oneCol =Mat::zeros(row,1,src.type());
for(int i=0;i<row;i++)
{
oneCol.at<float>(i,0)=dst.at<float>(i,j);
}
Mat m;
m=oneCol.t();
Mat l=waveletDecompose(m,lowFilter,highFilter);
l=l.t();
oneCol =l;
for (int i=0;i<row;i++)
{
dst.at<float>(i,j)=oneCol.at<float>(i,0);
}
}
row/=2;
col/=2;
t++;
src=dst;
}

        return dst;

}

void wavelet(string _wname,Mat &_lowFilter, Mat &_highFilter)

{
if(_wname=="haar" || _wname=="db1")
{
int N =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")
{
int N =4;
float h[]={-0.483,0.836,-0.224,-0.129};
float l[]={-0.129,0.224,0.837,0.483};
_lowFilter=Mat::zeros(1,N,CV_32F);
_highFilter=Mat::zeros(1,N,CV_32F);
for (int i=0;i<N;i++)
{
_lowFilter.at<float>(0,i)=l[i];
_highFilter.at<float>(0,i)=h[i];
}
}

}

Mat waveletDecompose(Mat &_src , Mat &_lowFilter ,Mat &_highFilter)

{
assert(_src.rows==1 && _lowFilter.rows==1 && _highFilter.rows==1);
assert(_src.cols>=_lowFilter.cols && _src.cols>=_highFilter.cols);
Mat src ;
_src.convertTo(src,CV_32F);
int D =src.cols;
Mat lowFilter,highFilter;
_lowFilter.convertTo(lowFilter,CV_32F);
_highFilter.convertTo(highFilter,CV_32F);
Mat dst1=Mat::zeros(1,D,src.type());
Mat dst2=Mat::zeros(1,D,src.type());

filter2D(src,dst1,-1,lowFilter);
filter2D(src,dst2,-1,highFilter);

//下采样
Mat downDst1=Mat::zeros(1,D/2,src.type());
Mat downDst2=Mat::zeros(2,D/2,src.type());

resize(dst1,downDst1,downDst1.size(),downDst1.type());
resize(dst2,downDst2,downDst2.size(),downDst2.type());

//数据拼接
for (int i=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);
}
return src;

}

Mat   wavedcomponent(Mat src , string com,int level)

{
Mat dst;
int row =src.rows;
int col =src.cols;
int m = floor(row/(pow(2,level)));
int n = floor(col/(pow(2,level)));
if(com=="HL")
{
dst=src(Rect(n,0,n,m));
}
if(com=="LH")
{
dst=src(Rect(0,m,n,m));
}
return dst;

}

直接调用WDT可以产生一下结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv 小波变换