#include "stdafx.h"
#include "WaveTransform.h"
#include <math.h>
#include <imgproc/imgproc.hpp> Mat WaveTransform::WDT(const Mat &_src,const string _wname,const int _level)
{
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=;
int row=N;
int col=D;
while (t<=_level)
{
//先进行 行小波变换
for (int i=;i<row;i++)
{
//取出src中要处理的数据的一行
Mat oneRow=Mat::zeros(,col,src.type());
for (int j=;j<col;j++)
{
oneRow.at<float>(,j)=src.at<float>(i,j);
}
oneRow=waveletDecompose(oneRow,lowFilter,highFilter);
for (int j=;j<col;j++)
{
dst.at<float>(i,j)=oneRow.at<float>(,j);
}
}
char s[];
itoa(t,s,);
imshow(s,dst);
waitKey();
#if 0
// normalize(dst,dst,0,255,NORM_MINMAX);
IplImage dstImg1=IplImage(dst);
cvSaveImage("dst1.jpg",&dstImg1);
#endif //小波列变换
for (int j=;j<col;j++)
{
Mat oneCol=Mat::zeros(row,,src.type());
for (int i=;i<row;i++)
{
oneCol.at<float>(i,)=dst.at<float>(i,j);//dst,not src
}
oneCol=(waveletDecompose(oneCol.t(),lowFilter,highFilter)).t();
for (int i=;i<row;i++)
{
dst.at<float>(i,j)=oneCol.at<float>(i,);
}
}
#if 0
// normalize(dst,dst,0,255,NORM_MINMAX);
IplImage dstImg2=IplImage(dst);
cvSaveImage("dst2.jpg",&dstImg2);
#endif
//更新
row/=;
col/=;
t++;
src=dst; }
return dst;
}

//生成不同类型的小波
void WaveTransform::wavelet( const string _wname, Mat &_lowFilter, Mat &_highFilter )
{ if (_wname=="haar" || _wname=="db1")
{
int N=;
_lowFilter=Mat::zeros(,N,CV_32F);
_highFilter=Mat::zeros(,N,CV_32F); _lowFilter.at<float>(,)=/sqrtf(N);
_lowFilter.at<float>(,)=/sqrtf(N); _highFilter.at<float>(,)=-/sqrtf(N);
_highFilter.at<float>(,)=/sqrtf(N);
}
if (_wname=="sym2")
{
int N=;
float h[]={-0.483, 0.836, -0.224, -0.129};
float l[]={-0.129, 0.224, 0.837, 0.483}; _lowFilter=Mat::zeros(,N,CV_32F);
_highFilter=Mat::zeros(,N,CV_32F); for (int i=;i<N;i++)
{
_lowFilter.at<float>(,i)=l[i];
_highFilter.at<float>(,i)=h[i];
}
} }

//小波分解
Mat WaveTransform::waveletDecompose( const Mat &_src, const Mat &_lowFilter, const Mat &_highFilter )
{
assert(_src.rows== && _lowFilter.rows== && _highFilter.rows ==);
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(,D,src.type());
Mat dst2=Mat::zeros(,D,src.type()); filter2D(src,dst1,-,lowFilter);
filter2D(src,dst2,-,highFilter); //下采样
Mat downDst1=Mat::zeros(,D/,src.type());
Mat downDst2=Mat::zeros(,D/,src.type()); resize(dst1,downDst1,downDst1.size());
resize(dst2,downDst2,downDst2.size()); //数据拼接
for (int i=;i<D/;i++)
{
src.at<float>(,i)=downDst1.at<float>(,i);
src.at<float>(,i+D/)=downDst2.at<float>(,i); }
return src;
}

用main函数调用WDT

Mat imgWave=m_waveTransform.WDT(src,"haar",);
imshow("img",Mat_<uchar>(imgWave));
waitKey();

用一张考拉图来分析小波变换过程:

原图:

3层小波变换结果图(图片有压缩):

下面逐一分析:

1 只做完小波行变换

2 行列变换

3 再次行变换

4 再次行列变换

三次之后到最后的分解图。

代码来自:http://shijuanfeng.blogbus.com/logs/221385402.html

基于opencv的小波变换代码和图像结果的更多相关文章

  1. 基于opencv的小波变换

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

  2. Python图像处理丨基于OpenCV和像素处理的图像灰度化处理

    摘要:本篇文章讲解图像灰度化处理的知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,使用像素处理方法对图像进行灰度化处理. 本文分享自华为云社区<[Python图像处理 ...

  3. 图像矫正-基于opencv实现

    一.引言 上篇文章中四种方法对图像进行倾角矫正都非常有效.Hough变换和Radon相似,其抗干扰能力比较强,但是运算量大,程序执行慢,其改进方法为:我们可以不对整幅图像进行操作,可以在图像中选取一块 ...

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

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

  5. Java基于opencv实现图像数字识别(五)—投影法分割字符

    Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...

  6. Java基于opencv实现图像数字识别(四)—图像降噪

    Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...

  7. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  8. Java基于opencv实现图像数字识别(一)

    Java基于opencv实现图像数字识别(一) 最近分到了一个任务,要做数字识别,我分配到的任务是把数字一个个的分开:当时一脸懵逼,直接百度java如何分割图片中的数字,然后就百度到了用Buffere ...

  9. 基于qml创建最简单的图像处理程序(3)-使用opencv&qml进行图像处理

    <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...

随机推荐

  1. [POJ1741]Tree(点分治)

    树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 ...

  2. 20155207 实验四 《Android程序设计》实验报告

    20155207 实验四 <Android程序设计>实验报告 实验名称 Android程序设计 实验内容 1.Android Stuidio的安装测试: 参考<Java和Androi ...

  3. 20155330 实验二 Java面向对象程序设计

    20155330 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...

  4. WPF MVVM从入门到精通8:数据验证

    原文:WPF MVVM从入门到精通8:数据验证 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF M ...

  5. 分类问题中的“维数灾难” - robotMax

    分类问题中的“维数灾难” - robotMax 在看机器学习的论文时,经常会看到有作者提到“curse of dimensionality”,中文译为“维数灾难”,这到底是一个什么样的“灾难”?本文将 ...

  6. 【转】 线段树完全版 ~by NotOnlySuccess

    载自:NotOnlySuccess的博客 [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时觉得挺自豪的,还去pku打广告,但是现在我自己都不太好意思去看那篇文章 ...

  7. 搜索引擎ElasticSearch系列(四): ElasticSearch2.4.4 sql插件安装

    一:ElasticSearch sql插件简介 With this plugin you can query elasticsearch using familiar SQL syntax. You ...

  8. Oracle和MySQL在使用上的区别

    1.  Oracle是大型数据库而MySQL是中小型数据库,MySQL是开源的而Oracle的价格非常高. 2.  Oracle支持大并发,大访问量. 3.  安装所用的空间差别也是很大,MySQL安 ...

  9. ExpressJS基础概念及简单Server架设

    NodeJS Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.js 的包 ...

  10. 清空git缓存

    git rm -r --cached .git add . git commit -m 'update .gitignore' 读了下git文档,才发现,这些东西其实很简单,很容易理解.cached其 ...