哈尔尺度函数_哈尔小波变换的原理及其实现(Haar)

本文详细介绍了哈尔小波变换的基本原理,包括一维和二维的实现,以及在图像处理中的应用。通过示例展示了如何对一维和二维数据进行小波变换,包括均值计算、差值计算和细节系数存储。还提供了C++代码实现,包括一维和二维的哈尔小波变换。此外,文章讨论了小波变换在图像压缩中的作用,指出哈尔小波变换的高效性和压缩效果。
摘要由CSDN通过智能技术生成

另外参见俄罗斯写的http://www.codeproject.com/Articles/22243/Real-Time-Object-Tracker-in-C

Haar小波在图像处理和数字水印等方面应用较多,这里简单的介绍一下哈尔小波的基本原理以及其实现情况。

一、Haar小波的基本原理

数学理论方面的东西我也不是很熟悉,这边主要用简单的例子来介绍下Haar小波的使用情况。

例如:有a=[8,7,6,9]四个数,并使用b[4]数组来保存结果.

则一级Haar小波变换的结果为:

b[0]=(a[0]+a[1])/2,                       b[2]=(a[0]-a[1])/2

b[1]=(a[2]+a[3])/2,                       b[3]=(a[2]-a[3])/2

即依次从数组中取两个数字,计算它们的和以及差,并将和一半和差的一半依次保存在数组的前半部分和后半部分。

例如:有a[8],要进行一维Haar小波变换,结果保存在b[8]中

则一级Haar小波变换的结果为:

b[0]=(a[0]+a[1])/2,                        b[4]=(a[0]-a[1])/2

b[1]=(a[2]+a[3])/2,                        b[5]=(a[2]-a[3])/2

b[2]=(a[4]+a[5])/2,                        b[6]=(a[4-a[5]])/2

b[3]=(a[6]+a[7])/2,                        b[7]=(a[6]-a[7])/2

如果需要进行二级Haar小波变换的时候,只需要对b[0]-b[3]进行Haar小波变换.

对于二维的矩阵来讲,每一级Haar小波变换需要先后进行水平方向和竖直方向上的两次一维小波变换,行和列的先后次序对结果不影响。

二、Haar小波的实现

使用opencv来读取图片及像素,对图像的第一个8*8的矩阵做了一级小波变换

#include

#include

#include

using namespace std;

int main(){

IplImage* srcImg;

double  imgData[8][8];

int i,j;

srcImg=cvLoadImage("lena.bmp",0);

cout<

for( i=0;i<8;i++)

{

for( j=0;j<8;j++)

{

imgData[i][j]=cvGetReal2D(srcImg,i+256,j+16);

cout<

}

cout<

}

double tempData[8];

//行小波分解

for( i=0;i<8;i++)

{

for( j=0;j<4;j++)

{

double temp1=imgData[i][2*j];

double temp2=imgData[i][2*j+1];

tempData[j]=(temp1+temp2)/2;

tempData[j+4]=(temp1-temp2)/2;

}

for( j=0;j<8;j++)

imgData[i][j]=tempData[j];

}

//列小波分解

for( i=0;i<8;i++)

{

for( j=0;j<4;j++)

{

double temp1=imgData[2*j][i];

double temp2=imgData[2*j+1][i];

tempData[j]=(temp1+temp2)/2;

tempData[j+4]=(temp1-temp2)/2;

}

for( j=0;j<8;j++)

imgData[j][i]=tempData[j];

}

cout<

for( i=0;i<8;i++)

{

for( j=0;j<8;j++)

{

cout<

}

cout<

}

//列小波逆分解

for( i=0;i<8;i++)

{

for( j=0;j<4;j++)

{

double temp1=imgData[j][i];

double temp2=imgData[j+4][i];

tempData[2*j]=temp1+temp2;

tempData[2*j+1]=temp1-temp2;

}

for( j=0;j<8;j++)

{

imgData[j][i]=tempData[j];

}

}

//行小波逆分解

for( i=0;i<8;i++)

{

for( j=0;j<4;j++)

{

double temp1=imgData[i][j];

double temp2=imgData[i][j+4];

tempData[2*j]=temp1+temp2;

tempData[2*j+1]=temp1-temp2;

}

for( j=0;j<2*4;j++)

{

imgData[i][j]=tempData[j];

}

}

cout<

for( i=0;i<8;i++)

{

for( j=0;j<8;j++)

{

cout<

}

cout<

}

return 0;

}

===========================================================================

/// 小波变换Mat WDT( const Mat &_src, const string _wname, const int _level )const{int reValue = THID_ERR_NONE;Mat src = Mat_(_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=1;int row = N;int col = D;while( t<=_level ){///先进行行小波变换for( int i=0; i(0,j) = src.at(i,j);}oneRow = waveletDecompose( oneRow, lowFilter, highFilter );/// 将src这一行置为oneRow中的数据for ( int j=0; j(i,j) = oneRow.at(0,j);}}#if 0//normalize( dst, dst, 0, 255, NORM_MINMAX );IplImage dstImg1 = IplImage(dst);cvSaveImage( "dst.jpg", &dstImg1 );#endif/// 小波列变换for ( int j=0; j(i,0) = dst.at(i,j);}oneCol = ( waveletDecompose( oneCol.t(), lowFilter, highFilter ) ).t();for ( int i=0; i(i,j) = oneCol.at(i,0);}}#if 0//normalize( dst, dst, 0, 255, NORM_MINMAX );IplImage dstImg2 = IplImage(dst);cvSaveImage( "dst.jpg", &dstImg2 );#endif/// 更新row /= 2;col /=2;t++;src = dst;}return dst;}/// 小波逆变换Mat IWDT( const Mat &_src, const string _wname, const int _level )const{int reValue = THID_ERR_NONE;Mat src = Mat_(_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=1;int row = N/std::pow( 2., _level-1);int col = D/std::pow(2., _level-1);while ( row<=N && col<=D ){/// 小波列逆变换for ( int j=0; j(i,0) = src.at(i,j);}oneCol = ( waveletReconstruct( oneCol.t(), lowFilter, highFilter ) ).t();for ( int i=0; i(i,j) = oneCol.at(i,0);}}#if 0//normalize( dst, dst, 0, 255, NORM_MINMAX );IplImage dstImg2 = IplImage(dst);cvSaveImage( "dst.jpg", &dstImg2 );#endif///行小波逆变换for( int i=0; i(0,j) = dst.at(i,j);}oneRow = waveletReconstruct( oneRow, lowFilter, highFilter );/// 将src这一行置为oneRow中的数据for ( int j=0; j(i,j) = oneRow.at(0,j);}}#if 0//normalize( dst, dst, 0, 255, NORM_MINMAX );IplImage dstImg1 = IplImage(dst);cvSaveImage( "dst.jpg", &dstImg1 );#endifrow *= 2;col *= 2;src = dst;}return dst;}/// 调用函数/// 生成不同类型的小波,现在只有haar,sym2void wavelet( const string _wname, Mat &_lowFilter, Mat &_highFilter )const{if ( _wname=="haar" || _wname=="db1" ){int N = 2;_lowFilter = Mat::zeros( 1, N, CV_32F );_highFilter = Mat::zeros( 1, N, CV_32F );_lowFilter.at(0, 0) = 1/sqrtf(N);_lowFilter.at(0, 1) = 1/sqrtf(N);_highFilter.at(0, 0) = -1/sqrtf(N);_highFilter.at(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(0, i) = l[i];_highFilter.at(0, i) = h[i];}}}/// 小波分解Mat waveletDecompose( const Mat &_src, const Mat &_lowFilter, const Mat &_highFilter )const{assert( _src.rows==1 && _lowFilter.rows==1 && _highFilter.rows==1 );assert( _src.cols>=_lowFilter.cols && _src.cols>=_highFilter.cols );Ma

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值