小波变换 C++ opencv 实现

小波简介: 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,sym2
void 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;
 
}

小波变换 C++ opencv 实现的更多相关文章

  1. 基于opencv的小波变换

    基于opencv的小波变换 提供函数DWT()和IDWT(),前者完成任意层次的小波变换,后者完成任意层次的小波逆变换.输入图像要求必须是单通道浮点图像,对图像大小也有要求(1层变换:w,h必须是2的 ...

  2. 基于opencv的小波变换代码和图像结果

    #include "stdafx.h" #include "WaveTransform.h" #include <math.h> #include ...

  3. 学习OpenCV——Gabor函数的应用

    原文:http://blog.csdn.net/yao_zhuang/article/details/2532279 下载cvgabor.cpp和cvgabor.h到你的C/C++工程目录下 注:在我 ...

  4. 【转】opencv检测运动物体的基础_特征提取

    特征提取是计算机视觉和图像处理中的一个概念.它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征.特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点.连续的曲线或者连 ...

  5. OpenCV——SIFT特征检测与匹配

    SIFT特征和SURF特征比较 比较项目 SIFT SURF 尺度空间极值检测 使用高斯滤波器,根据不同尺度的高斯差(DOG)图像寻找局部极值 使用方形滤波器,利用海森矩阵的行列式值检测极值,并利用积 ...

  6. 基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)

    一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiD ...

  7. 目标检测之harr---角点检测harr 的opencv实现

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

  8. OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  9. C++vector and opencv Mat

    转载:https://blog.csdn.net/u012507022/article/details/50979011?utm_source=blogxgwz5 最近在写Opencv程序,用到离散小 ...

随机推荐

  1. HD1285(拓扑排序)

    package cn.hncu.dataStruct.search.topSort; import java.util.Scanner; public class Hdu1285 { static S ...

  2. C# 解决DrawImage绘制图片拉伸产生渐变

    ImageAttributes ImgAtt = new ImageAttributes(); ;                 ImgAtt.SetWrapMode(System.Drawing. ...

  3. inux设置普通用户无密码sudo权限

    配置普通用户无密码sudo权限: root用户进入到Linux系统的/etc目录下 cd /etc 将sudoers文件赋予写的权限 chmod u+w /etc/sudoers 编辑sudoers文 ...

  4. sqlserver 连不上的问题

    tcp ip  属性 ipall  属性改为1433

  5. Sublime Text 使用简介

    Sublime Text使用介绍 如果说Notepad++是一款不错Code神器,那么Sublime Text应当称得上是神器滴哥.Sublime Text最大的优点就是跨平台,Mac和Windows ...

  6. A swift Tour

    传统的认为,一个新的语言的第一个应用程序都会打印"Hellow,Word",在Swift中,可以只需要一行代码: pringln("Hello, word") ...

  7. 转载--SQL Server 2005的XQuery介绍

    原文地址: http://bbs.51cto.com/thread-458009-1-1.html   引用: 摘要 本文介绍了SQL Server 2005能够支持的XQuery的各方面特性如FLW ...

  8. SQL Server调优系列基础篇 - 性能调优介绍

    前言 关于SQL Server调优系列是一个庞大的内容体系,非一言两语能够分析清楚,本篇先就在SQL 调优中所最常用的查询计划进行解析,力图做好基础的掌握,夯实基本功!而后再谈谈整体的语句调优. 通过 ...

  9. Android版本分布——2016年10月更新

    Code Name Version API Level Distribution frogy(冻酸奶) 2.2.x 8 0.1% gingerbread(姜饼) 2.3.3——2.3.7 10 2.0 ...

  10. python常用函数 库 转

    可能经常用到的标准模块和第三方常用的50个库 本文由python培训班授课老师整理 数学计算:     numbers - Numeric abstract base classes     math ...