本文共 3291 字,大约阅读时间需要 10 分钟。
关于离散小波变换的原理在
中已经有了非常详细的总结,这里介绍下本博客利用离散小波变换进行降噪的原理(其实不能算是降噪,应该算是图像压缩),就是在小波变换之后,将输出系数进行由大到小的排序,然后将前10%大的通过小波反变换成图像,因为噪声不属于图像的主要信息,因此通过这种方法会有降噪的效果,这种算法又称为小波硬阈值滤波。
这里是基于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> dwtInput(src.rows, vector (src.cols)); for(int i = 0; i (i,j); } } //计算小波变换,输出结果是output vector dwtLength; vector dwtOutput, dwtFlag; dwt_2d(dwtInput, num, "db2", dwtOutput, dwtFlag, dwtLength); //******************************显示相关******************************// //通过dwtLength计算dim// vector dwtDim;// dwt_output_dim_sym(dwtLength, dwtDim, num);//// //dim的后两位是显示尺寸,并将dwtOutput构造成display// int dwtRow = dwtDim[dwtDim.size()-2], dwtCol = dwtDim[dwtDim.size()-1];// vector > dwtDisplay(dwtRow, vector (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 (i,j) = (uchar)(dwtDisplay[i][j]/m*255);// else// dst.at (i,j) = (uchar)(dwtDisplay[i][j]);// }// }// imshow("dst", dst); //****************************************************************** //******************************滤波相关****************************** //开始滤波 int filterSize = int(dwtOutput.size() / percentage); vector filter; for(auto it : dwtOutput) { filter.push_back(abs(it)); } sort(filter.begin(), filter.end(), greater ()); double threshold = filter.at(filterSize-1); for(int i = 0; i (i,j) = (uchar)(dwtDisplay[i][j]/m*255);// else// dst2.at (i,j) = (uchar)(dwtDisplay[i][j]);// }// }// imshow("dst2", dst2); //****************************************************************** //下面是进行小波反变换过程 vector > idwtOutput(src.rows, vector (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 (i,j) = (uchar)(idwtOutput[i][j]/m*255); } } return img;}
原图如下:
此外,这里我写一个各种算法的总结目录,对图像降噪算法感兴趣的同学欢迎参考
转载地址:http://sbszz.baihongyu.com/