小波变换 C++ opencv 实现
来源:互联网 发布:mac os x sierra壁纸 编辑:程序博客网 时间:2024/05/01 20:35
小波简介: http://www.blogbus.com/shijuanfeng-logs/221293135.html
源码:
/// 小波变换Mat WDT( const Mat &_src, const string _wname, const int _level )const{ int reValue = THID_ERR_NONE; Mat src = Mat_<float>(_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<row; i++ ) { /// 取出src中要处理的数据的一行 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 ); /// 将src这一行置为oneRow中的数据 for ( int j=0; j<col; j++ ) { dst.at<float>(i,j) = oneRow.at<float>(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<col; j++ ) { /// 取出src数据的一行输入 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); } oneCol = ( waveletDecompose( oneCol.t(), lowFilter, highFilter ) ).t(); for ( int i=0; i<row; i++ ) { dst.at<float>(i,j) = oneCol.at<float>(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_<float>(_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<col; j++ ) { /// 取出src数据的一行输入 Mat oneCol = Mat::zeros( row, 1, src.type() ); for ( int i=0; i<row; i++ ) { oneCol.at<float>(i,0) = src.at<float>(i,j); } oneCol = ( waveletReconstruct( oneCol.t(), lowFilter, highFilter ) ).t(); for ( int i=0; i<row; i++ ) { dst.at<float>(i,j) = oneCol.at<float>(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<row; i++ ) { /// 取出src中要处理的数据的一行 Mat oneRow = Mat::zeros( 1,col, src.type() ); for ( int j=0; j<col; j++ ) { oneRow.at<float>(0,j) = dst.at<float>(i,j); } oneRow = waveletReconstruct( oneRow, lowFilter, highFilter ); /// 将src这一行置为oneRow中的数据 for ( int j=0; j<col; j++ ) { dst.at<float>(i,j) = oneRow.at<float>(0,j); } } #if 0 //normalize( dst, dst, 0, 255, NORM_MINMAX ); IplImage dstImg1 = IplImage(dst); cvSaveImage( "dst.jpg", &dstImg1 );#endif row *= 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<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( 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 ); Mat &src = Mat_<float>(_src); int D = src.cols; Mat &lowFilter = Mat_<float>(_lowFilter); Mat &highFilter = Mat_<float>(_highFilter); /// 频域滤波,或时域卷积;ifft( fft(x) * fft(filter)) = cov(x,filter) 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( 1, D/2, src.type() ); resize( dst1, downDst1, downDst1.size() ); resize( dst2, downDst2, downDst2.size() ); /// 数据拼接 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 waveletReconstruct( 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 ); Mat &src = Mat_<float>(_src); int D = src.cols; Mat &lowFilter = Mat_<float>(_lowFilter); Mat &highFilter = Mat_<float>(_highFilter); /// 插值; Mat Up1 = Mat::zeros( 1, D, src.type() ); Mat Up2 = Mat::zeros( 1, D, src.type() ); /// 插值为0 //for ( int i=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 ); ///< 后一半 //} /// 线性插值 Mat roi1( src, Rect(0, 0, D/2, 1) ); Mat roi2( 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 ); /// 前一半低通,后一半高通 Mat dst1 = Mat::zeros( 1, D, src.type() ); Mat dst2= Mat::zeros( 1, D, src.type() ); filter2D( Up1, dst1, -1, lowFilter ); filter2D( Up2, dst2, -1, highFilter ); /// 结果相加 dst1 = dst1 + dst2; return dst1; }
0 0
- 小波变换 C++ opencv 实现
- 小波变换 C++ opencv 实现
- Opencv实现离散小波变换小结
- Opencv实现离散小波变换小结
- 小波变换 opencv
- 基于opencv的小波变换的实现代码
- opencv小波变换代码
- opencv小波变换代码
- opencv c++ 小波变换
- OpenCV下的小波变换
- 基于opencv的小波变换
- 基于opencv的小波变换
- 基于OpenCV的小波变换
- 基于opencv的小波变换
- 基于opencv的小波变换
- 中值形态小波变换的OpenCV代码
- Haar小波变换的快速实现
- 小波变换的C++实现
- hdu 1201 18岁生日
- 4.10-char2
- C++ curl跨平台HttpClient
- hdu杭电1873 看病要排队【优先队列】
- 线程和正则表达式
- 小波变换 C++ opencv 实现
- Verilog HDL语言不全面但基本入门够用介绍
- 2.1 编写第一个C#程序
- Gym100187E,Two Labyrinths,广搜
- 4.11-char练习
- noip过河卒
- mysql启动报错,找不到mysql.sock
- 4.12-数组
- nginx proxy-pass简单的应用