本文是通过滤波器组实现的harr小波变换(还没写反变换)
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat wavelet(Mat srcImage,Mat* A1,Mat* D1,Mat* D2,Mat* D3);
Mat wavelet(Mat srcImage);
Mat InverseWavelet(Mat srcImage);
float convolution(float* arr0,int length0,float* arr1,int length,float* result);//实现序列卷积
int main()
{
Mat srcImage= imread("F:/低剂量CT图.bmp",0);
//Mat srcImage=imread("F:/位图资源/图片(jpg)/2.jpg",0);
//Mat srcImage= imread("F:/lena.bmp",0);
if(!srcImage.data)
return -1;
Mat A1,D1,D2,D3;
Mat result=wavelet(srcImage);
imshow("result",result);
Mat dst=wavelet(srcImage,&A1,&D1,&D2,&D3);
Mat A11,D11,D21,D31;
Mat dst1=wavelet(A1,&A11,&D11,&D21,&D31);
Mat A111,D111,D211,D311;
Mat dst2=wavelet(A11,&A111,&D111,&D211,&D311);
imshow("dst2",dst2);
imshow("dst1",dst1);
imshow("A1",A1);
imshow("srcImage",srcImage);
imshow("dst",dst);
waitKey(0);
return 1;
}
/*
小波变换函数一
*/
Mat wavelet(Mat srcImage)
{
Mat tempImage=srcImage.clone();
tempImage.convertTo(tempImage,CV_32FC1);
int nCols=tempImage.cols;
int nRows=tempImage.rows;//hang
//定义低通和高通滤波器
float kernelH_[2]={0.707,0.707};
float kernelG_[2]={0.707,-0.707};
float kernelH[2]={0.707,0.707};
float kernelG[2]={-0.707,0.707};
int M=2+nCols-1;
int N=2+nRows-1;
//临时存储对行列都卷积后的Mat
Mat tempMat=Mat::zeros(N,M,CV_32FC1);
Mat tempMatH_,tempMatG_,tempMatH,tempMatG;
tempMatH=Mat::zeros(N,M,CV_32FC1);
tempMatH_=Mat::zeros(N,M,CV_32FC1);
tempMatG=Mat::zeros(N,M,CV_32FC1);
tempMatG_=Mat::zeros(N,M,CV_32FC1);
float *result=new float[M];
float* Carr=new float[M];
float* tempArr=new float[nRows];
Mat a1,d1,d2,d3;
a1=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d1=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d2=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d3=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
/*---------------------求a1和d1-------------------------------------*/
//对图像每一列做卷积
for(int j=0;j<nCols;j++)
{
for(int i=0;i<nRows;i++)
{
tempArr[i]=tempImage.at<float>(i,j);
}
convolution(tempArr,nRows,kernelH_,2,Carr);
for(int i=0;i<nRows;i++)
{
tempMat.at<float>(i,j)=*(Carr+i);
}
}
//对上面结果每一行再做卷积
for(int i=0;i<N;i++)
{
float* p=tempMat.ptr<float>(i);
convolution(p,nCols,kernelH_,2,Carr);//用H_卷积
convolution(p,nCols,kernelG_,2,result);//用G_卷积
for(int j=0;j<M;j++)
{
tempMatH_.at<float>(i,j)=*(Carr+j);
tempMatG_.at<float>(i,j)=*(result+j);
}
}
for(int i=0;i<nRows/2;i++)
{
for(int j=0;j<nCols/2;j++)
{
a1.at<float>(i,j)=tempMatH_.at<float>(2*i+1,2*j+1);
d1.at<float>(i,j)=tempMatG_.at<float>(2*i+1,2*j+1);
}
}
/*--------------求d2,d3--------------------------*/
//对图像每一列做卷积
for(int j=0;j<nCols;j++)
{
for(int i=0;i<nRows;i++)
{
tempArr[i]=tempImage.at<float>(i,j);
}
convolution(tempArr,nRows,kernelG_,2,Carr);
for(int i=0;i<nRows;i++)
{
tempMat.at<float>(i,j)=*(Carr+i);
}
}
//对上面结果每一行再做卷积
for(int i=0;i<N;i++)
{
float* p=tempMat.ptr<float>(i);
convolution(p,nCols,kernelH_,2,Carr);//用H_卷积
convolution(p,nCols,kernelG_,2,result);//用G_卷积
for(int j=0;j<M;j++)
{
tempMatH.at<float>(i,j)=*(Carr+j);
tempMatG.at<float>(i,j)=*(result+j);
}
}
for(int i=0;i<nRows/2;i++)
{
for(int j=0;j<nCols/2;j++)
{
d2.at<float>(i,j)=tempMatH.at<float>(2*i+1,2*j+1);
d3.at<float>(i,j)=tempMatG.at<float>(2*i+1,2*j+1);
}
}
a1.copyTo(tempImage(Range(0,tempImage.rows/2),Range(0,tempImage.cols/2)));//Range函数是包含头,不包含尾
d1.copyTo(tempImage(Range(0,tempImage.rows/2),Range(tempImage.cols/2,tempImage.cols)));
d2.copyTo(tempImage(Range(tempImage.rows/2,tempImage.rows),Range(0,tempImage.cols/2)));
d3.copyTo(tempImage(Range(tempImage.rows/2,tempImage.rows),Range(tempImage.cols/2,tempImage.cols)));
tempImage.convertTo(tempImage,CV_8UC1);
return tempImage;
}
/*
小波变换函数二
*/
Mat wavelet(Mat srcImage,Mat* A1,Mat* D1,Mat* D2,Mat* D3)
{
Mat tempImage=srcImage.clone();
tempImage.convertTo(tempImage,CV_32FC1);
int nCols=tempImage.cols;
int nRows=tempImage.rows;//hang
//定义低通和高通滤波器
float kernelH_[2]={0.707,0.707};
float kernelG_[2]={0.707,-0.707};
float kernelH[2]={0.707,0.707};
float kernelG[2]={-0.707,0.707};
int M=2+nCols-1;
int N=2+nRows-1;
//临时存储对行列都卷积后的Mat
Mat tempMat=Mat::zeros(N,M,CV_32FC1);
Mat tempMatH_,tempMatG_,tempMatH,tempMatG;
tempMatH=Mat::zeros(N,M,CV_32FC1);
tempMatH_=Mat::zeros(N,M,CV_32FC1);
tempMatG=Mat::zeros(N,M,CV_32FC1);
tempMatG_=Mat::zeros(N,M,CV_32FC1);
float *result=new float[M];
float* Carr=new float[M];
float* tempArr=new float[nRows];
Mat a1,d1,d2,d3;
a1=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d1=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d2=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
d3=Mat::zeros(nRows/2,nCols/2,CV_32FC1);
/*---------------------求a1和d1-------------------------------------*/
//对图像每一列做卷积
for(int j=0;j<nCols;j++)
{
for(int i=0;i<nRows;i++)
{
tempArr[i]=tempImage.at<float>(i,j);
}
convolution(tempArr,nRows,kernelH_,2,Carr);
for(int i=0;i<nRows;i++)
{
tempMat.at<float>(i,j)=*(Carr+i);
}
}
//对上面结果每一行再做卷积
for(int i=0;i<N;i++)
{
float* p=tempMat.ptr<float>(i);
convolution(p,nCols,kernelH_,2,Carr);//用H_卷积
convolution(p,nCols,kernelG_,2,result);//用G_卷积
for(int j=0;j<M;j++)
{
tempMatH_.at<float>(i,j)=*(Carr+j);
tempMatG_.at<float>(i,j)=*(result+j);
}
}
for(int i=0;i<nRows/2;i++)
{
for(int j=0;j<nCols/2;j++)
{
a1.at<float>(i,j)=tempMatH_.at<float>(2*i+1,2*j+1);
d1.at<float>(i,j)=tempMatG_.at<float>(2*i+1,2*j+1);
}
}
/*--------------求d2,d3--------------------------*/
//对图像每一列做卷积
for(int j=0;j<nCols;j++)
{
for(int i=0;i<nRows;i++)
{
tempArr[i]=tempImage.at<float>(i,j);
}
convolution(tempArr,nRows,kernelG_,2,Carr);
for(int i=0;i<nRows;i++)
{
tempMat.at<float>(i,j)=*(Carr+i);
}
}
//对上面结果每一行再做卷积
for(int i=0;i<N;i++)
{
float* p=tempMat.ptr<float>(i);
convolution(p,nCols,kernelH_,2,Carr);//用H_卷积
convolution(p,nCols,kernelG_,2,result);//用G_卷积
for(int j=0;j<M;j++)
{
tempMatH.at<float>(i,j)=*(Carr+j);
tempMatG.at<float>(i,j)=*(result+j);
}
}
for(int i=0;i<nRows/2;i++)
{
for(int j=0;j<nCols/2;j++)
{
d2.at<float>(i,j)=tempMatH.at<float>(2*i+1,2*j+1);
d3.at<float>(i,j)=tempMatG.at<float>(2*i+1,2*j+1);
}
}
a1.copyTo(tempImage(Range(0,tempImage.rows/2),Range(0,tempImage.cols/2)));//Range函数是包含头,不包含尾
d1.copyTo(tempImage(Range(0,tempImage.rows/2),Range(tempImage.cols/2,tempImage.cols)));
d2.copyTo(tempImage(Range(tempImage.rows/2,tempImage.rows),Range(0,tempImage.cols/2)));
d3.copyTo(tempImage(Range(tempImage.rows/2,tempImage.rows),Range(tempImage.cols/2,tempImage.cols)));
d1.convertTo(d1,CV_8UC1);
d2.convertTo(d2,CV_8UC1);
d3.convertTo(d3,CV_8UC1);
a1.convertTo(a1,CV_8UC1);
/*
imshow("a1",a1);
imshow("d1",d1);
imshow("d2",d2);
imshow("d3",d3);
*/
*A1=a1;
*D1=d1;
*D2=d2;
*D3=d3;
tempImage.convertTo(tempImage,CV_8UC1);
return tempImage;
}
/*
序列卷积
*/
float convolution(float* arr0,int length0,float* arr1,int length1,float* result)
{
int N=length0+length1-1;
float* res=new float[N];
for(int n=0;n<N;n++)
{
*(res+n)=0;
for(int m=0;m<=n;m++)
{
if(m<length0&&(n-m)<length1)
{
*(res+n) +=arr0[m]*arr1[n-m];
}else
{
continue;
}
}
}
for(int i=0;i<N;i++)
{
*(result+i)=*(res+i);
}
return N;
}