图像降噪算法——小波硬阈值滤波(下)

  • 图像降噪算法——小波硬阈值滤波(下)
    • 1. 基本原理
    • 2. C++代码实现
    • 3. 结论

图像降噪算法——小波硬阈值滤波(下)

1. 基本原理

关于离散小波变换的原理在

图像降噪算法——小波硬阈值滤波(上)

中已经有了非常详细的总结,这里介绍下本博客利用离散小波变换进行降噪的原理(其实不能算是降噪,应该算是图像压缩),就是在小波变换之后,将输出系数进行由大到小的排序,然后将前10%大的通过小波反变换成图像,因为噪声不属于图像的主要信息,因此通过这种方法会有降噪的效果,这种算法又称为小波硬阈值滤波。

2. C++代码实现

这里是基于OpenCV、FFTW以及C++ Wavelet Libraries,这其中
(1)FFTW是一个基于C写的实现傅里叶变换和小波变换的基础库,链接戳这里,源码安装后用CmakeList链接到静态库文件即可。
(2)C++ Wavelet Libraries是利用FFTW封装的一个小波变换处理图像的库,下载链接戳这里,这里主要是用到了它的wavelet2d.cpp和wavelet2d.h两个文件。
我封装的小波变换的降噪算法如下:

Mat Denoise::WaveletFilter(const Mat &src, int num, int percentage)
{//需要讲Mat数据结构转换为vector数据结构vector<vector<double>> dwtInput(src.rows, vector<double>(src.cols));for(int i = 0; i<src.rows; i++){for(int j = 0; j<src.cols; j++){dwtInput[i][j] = (double)src.at<uchar>(i,j);}}//计算小波变换,输出结果是outputvector<int> dwtLength;vector<double> dwtOutput, dwtFlag;dwt_2d(dwtInput, num, "db2", dwtOutput, dwtFlag, dwtLength);//******************************显示相关******************************
//    //通过dwtLength计算dim
//    vector<int> dwtDim;
//    dwt_output_dim_sym(dwtLength, dwtDim, num);
//
//    //dim的后两位是显示尺寸,并将dwtOutput构造成display
//    int dwtRow = dwtDim[dwtDim.size()-2], dwtCol = dwtDim[dwtDim.size()-1];
//    vector<vector<double>> dwtDisplay(dwtRow, vector<double>(dwtCol));
//    dispDWT(dwtOutput, dwtDisplay, dwtLength, dwtDim, num);
//
//    //获取display中的最大值double m = 0;
//    for(int i = 0; i < dwtRow; i++)
//    {//        for(int j = 0; j < dwtCol; j++)
//        {//            if(m < dwtDisplay[i][j])
//                m = dwtDisplay[i][j];
//        }
//    }
//
//    //dst是用于显示的图像
//    Mat dst = Mat::zeros(dwtRow,dwtCol,CV_8UC1);
//    for(int i = 0; i < dwtRow; i++)
//    {//        for(int j = 0; j < dwtCol; j++)
//        {//            if(dwtDisplay[i][j] <= 0.0)
//                dwtDisplay[i][j] = 0.0;
//            if(i<=dwtDim[0] && j<=dwtDim[1])
//                dst.at<uchar>(i,j) = (uchar)(dwtDisplay[i][j]/m*255);
//            else
//                dst.at<uchar>(i,j) = (uchar)(dwtDisplay[i][j]);
//        }
//    }
//    imshow("dst", dst);//******************************************************************//******************************滤波相关******************************//开始滤波int filterSize = int(dwtOutput.size() / percentage);vector<double> filter;for(auto it : dwtOutput){filter.push_back(abs(it));}sort(filter.begin(), filter.end(), greater<double>());double threshold = filter.at(filterSize-1);for(int i = 0; i<dwtOutput.size(); i++){double tmp = abs(dwtOutput[i]);if(tmp < threshold)dwtOutput.at(i) = 0.0;}//******************************************************************//******************************显示相关******************************
//    dispDWT(dwtOutput, dwtDisplay, dwtLength, dwtDim, num);
//
//    //获取display中的最大值
//    m = 0;
//    for(int i = 0; i < dwtRow; i++)
//    {//        for(int j = 0; j < dwtCol; j++)
//        {//            if(m < dwtDisplay[i][j])
//                m = dwtDisplay[i][j];
//        }
//    }
//
//    //dst是用于显示的图像
//    Mat dst2 = Mat::zeros(dwtRow,dwtCol,CV_8UC1);
//    for(int i = 0; i < dwtRow; i++)
//    {//        for(int j = 0; j < dwtCol; j++)
//        {//            if(dwtDisplay[i][j] <= 0.0)
//                dwtDisplay[i][j] = 0.0;
//            if(i<=dwtDim[0] && j<=dwtDim[1])
//                dst2.at<uchar>(i,j) = (uchar)(dwtDisplay[i][j]/m*255);
//            else
//                dst2.at<uchar>(i,j) = (uchar)(dwtDisplay[i][j]);
//        }
//    }
//    imshow("dst2", dst2);//******************************************************************//下面是进行小波反变换过程vector<vector<double>> idwtOutput(src.rows, vector<double>(src.cols));idwt_2d(dwtOutput, dwtFlag, "db2", idwtOutput, dwtLength);int idwtRow = idwtOutput.size();int idwtCol = idwtOutput[0].size();//获取idwtOutput中的最大值m = 0;for(int i = 0; i < idwtRow; i++){for(int j = 0; j < idwtCol; j++){if(m < idwtOutput[i][j])m = idwtOutput[i][j];}}//显示降噪后的图像Mat img = Mat::zeros(idwtRow, idwtCol, CV_8UC1);for(int i = 0; i<idwtRow; i++){for(int j = 0; j<idwtCol; j++){if(idwtOutput[i][j] <= 0.0){idwtOutput[i][j] = 0.0;}img.at<uchar>(i,j) = (uchar)(idwtOutput[i][j]/m*255);}}return img;
}

原图如下:

加入高斯噪声:
进行图像小波变换:
按照上述方法进行滤波:

进行图像小波反变换:

3. 结论

  1. 可以看到通过图像小波变换进行降噪的效果看上去还可以,起码比傅里叶变换的效果要好,但是呢,感觉小波变换的速度还是比较慢,实时运行应该比较困难;
  2. 本文采用的降噪算法其实比较简单,在这篇文献中《Image Denoising Review From Classical to State-of-the-art Approaches,2020》提到,对于转换域的降噪算法主要有两个关键点:1.转换到什么变换域(傅里叶?小波?脊波?);2.采用什么类型的阈值进行滤波,这篇文献中提到了六种设计阈值的方法,需要了解的同学可以参考下;
  3. 小波变化提取信息主要是在水平、垂直和对角线三个方向,在小波的基础上,还有curvelet、contourlet等一些更加高级的变化,之后有需要再进一步了解。

此外,这里我写一个各种算法的总结目录图像降噪算法——图像降噪算法总结,对图像降噪算法感兴趣的同学欢迎参考

图像降噪算法——小波硬阈值滤波(下)相关推荐

  1. 图像降噪算法——小波硬阈值滤波(上)

    图像降噪算法--小波硬阈值滤波(上) 图像降噪算法--小波硬阈值滤波(上) 1. 多分辨率展开 2. 尺度函数 3. 小波函数 4. 小波级数展开 5. 离散小波变换 6. 快速小波变换 7. 图像小 ...

  2. 【语音去噪】基于matlab小波硬阈值语音降噪【含Matlab源码 532期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[语音去噪]基于matlab小波硬阈值语音降噪[含Matlab源码 532期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: ...

  3. matlab 小波启发式阈值滤波,小波阈值去噪

    小波阈值去噪 小波阈值去噪 目录 1.概念 2.原理 3.影响降噪效果的因素 3.1小波基的选择 3.2分解层数的选择 3.3阈值的选择 3.4阈值函数的选择 4.MATLAB代码 参考文献 小波分析 ...

  4. 图像降噪算法——图像降噪算法总结

    图像降噪算法--图像降噪算法总结 图像降噪算法--图像降噪算法总结 图像降噪算法--图像降噪算法总结 前面这段时间我看了几篇和图像降噪相关的Review,给我的感觉就是SLAM这一研究领域像是一片汪洋 ...

  5. 图像降噪算法——中值滤波/均值滤波/高斯滤波/双边滤波

    图像降噪算法--中值滤波/均值滤波/高斯滤波/双边滤波 图像降噪算法--中值滤波/均值滤波/高斯滤波/双边滤波 1. 基本原理 2. C++代码实现 3. 结论 图像降噪算法--中值滤波/均值滤波/高 ...

  6. 图像降噪算法——高斯低通滤波

    图像降噪算法--高斯低通滤波 图像降噪算法--高斯低通滤波 1. 基本原理 2. C++代码实现 3. 结论 图像降噪算法--高斯低通滤波 1. 基本原理 通过离散傅里叶变换对图像进行滤波流程作非常简 ...

  7. 单片机c语言小波阈值降噪,小波阈值去噪的基本原理_小波去噪阈值如何选取

    小波阈值去噪的基本原理 小波阈值去噪的基本思想是先设置一个临界阈值λ,若小波系数小于λ,认为该系数主要由噪声引起,去除这部分系数;若小波系数大于λ,则认为此系数主要是由信号引起,保留这部分系数,然后对 ...

  8. 图像降噪算法——时域降噪算法

    图像降噪算法--时域降噪算法 图像降噪算法--时域降噪算法 1.<MeshFLow Video Denoising> 2. <Real-Time Video Denoising On ...

  9. 图像降噪算法——低秩聚类:WNNM算法

    图像降噪算法--低秩聚类:WNNM算法 图像降噪算法--低秩聚类:WNNM算法 1. 基本原理 2. matlab代码 3. 结论 图像降噪算法--低秩聚类:WNNM算法 同样是为了完善自己知识版图的 ...

最新文章

  1. 十五天精通WCF——第八天 对“绑定”的最后一点理解
  2. xtragrid 上移下移
  3. 独家 | 菜鸟级机器学习入门(附代码实例)
  4. 入职体检——项目列表(7项)
  5. 资深Android开发带你入门Framework,架构师必备技能
  6. php radio js,如何使用JavaScript设置radio选中的示例
  7. python真的是吹过了-python是否被过度吹捧?
  8. JAVA JDK API查看方法
  9. 《老路用得上的商学课》61-65学习笔记
  10. python制作的简单程序_Python如何制作简易收银小程序
  11. 误删除文件怎么找回呢?
  12. vulcan 编程_我如何在四天内使用Vulcan.js构建应用程序
  13. POJ 3368 Frequent values
  14. DRB-GAN: A Dynamic ResBlock Generative Adversarial Network for Artistic Style Transfer
  15. 安卓用ffmeg解码
  16. 如何帮女朋友快速抢到各种票!火车票,演唱会票等!
  17. osgEarth示例分析——osgearth_skyview
  18. 关于有盘产品市场调查
  19. 7-3 小字辈 (25分)
  20. 关闭windows或者windows server多用户会话

热门文章

  1. Hibernate中的核心接口query接口用法
  2. Myeclipse+mysql出现中文乱码情况
  3. Struts1.x的使用
  4. 中fuse_一个Fanotify和FUSE配合使用导致的问题
  5. (Spring)声明式事务
  6. 数据流中的中位数,我轻敌了
  7. 在ListView中使用BaseAdapter进行适配
  8. 原型模式(ProtoType) - Java里的对象复制
  9. 将mysql的数据库导入到linux_linux 操作之一 如何在linux将本地数据*.sql文件导入到linux 云服务器上的mysql数据库...
  10. 200 ssl服务器证书无效_服务器证书无效网站显示异常怎么办?