图像处理 二维小波变换
2015-06-04 21:35
471 查看
编程环境:windows下结合opencv库
//二维图像小波变换 /* nLayer:变换尺度 type:小波类型 */ void ImageDWT(IplImage* src, IplImage* dst, int nLayer, char* type);
//通用的二维小波变换 /* nLayer:小波变换的层数 type:选取的小波名称 可用为: "haar","db4","sym4" 使用Mallat算法,并利用傅里叶变换来快速执行卷积运算 src与dst深度均为IPL_DEPTH_8U */ void ImageDWT(IplImage* src, IplImage* dst, int nLayer, char* type) { if (!src || !dst) { return; } //判断src与dst的长度宽度是否为2的倍数 if (((dst->width >> nLayer) << nLayer != dst->width) || ((dst->height >> nLayer) << nLayer != dst->height) || (src->nChannels != 1) || (dst->nChannels != 1) || (nLayer <= 0)) { return; } CvMat* pMatData = NULL;//用于保存计算过程中的向量 CvMat* pMatCA = NULL; CvMat* pMatCD = NULL; CvMat* pMatDst = cvCreateMat(dst->height, dst->width, CV_64FC1);//结果矩阵 CvMat tmp; int nWidth = dst->width; int nHeight = dst->height; int nHalfW = nWidth / 2; int nHalfH = nHeight / 2; int i, x, y; double* *pfDst = (double**)(malloc(sizeof(double*) * pMatDst->height));//pMatDst数据的起始地址 double* pfCA;//CA数据起始地址 double* pfCD;//CD数据起始地址 double* pfData;//Data数据起始地址 //保存图像数据每行的起始地址 for (y = 0; y < nHeight; y++) { pfDst[y] = (double*)(pMatDst->data.ptr + y * pMatDst->step); } //预先填充pMatDst cvZero(pMatDst); cvGetSubRect(pMatDst, &tmp, cvRect(0, 0, src->width, src->height)); cvScale(src, &tmp); while (nLayer > 0) { //行变换 pMatData = cvCreateMat(1, nWidth, CV_64FC1); pMatCA = cvCreateMat(1, nHalfW, CV_64FC1); pMatCD = cvCreateMat(1, nHalfW, CV_64FC1); y = 0; for (y = 0; y < nHeight; y++) { pfCA = (double*)(pMatCA->data.ptr); pfCD = (double*)(pMatCD->data.ptr); pfData = (double*)(pMatData->data.ptr); //获取每一行数据 for (i = 0; i < nWidth; i++) { pfData[i] = pfDst[y][i]; } cvDWT(pMatData, pMatCA, pMatCD, type);//对每一行数据进行一维快速小波变换 //将小波变换结果拼接到一起并设置到pMatDst中 for (i = 0; i < nWidth; i++) { if (i < nHalfW) { pfDst[y][i] = pfCA[i]; } else { pfDst[y][i] = pfCD[i - nHalfW]; } } } cvReleaseMat(&pMatData); cvReleaseMat(&pMatCA); cvReleaseMat(&pMatCD); //列变换 pMatData = cvCreateMat(1, nHeight, CV_64FC1); pMatCA = cvCreateMat(1, nHalfH, CV_64FC1); pMatCD = cvCreateMat(1, nHalfH, CV_64FC1); y = 0; for (x = 0; x < nWidth; x++) { pfCA = (double*)(pMatCA->data.ptr); pfCD = (double*)(pMatCD->data.ptr); pfData = (double*)(pMatData->data.ptr); //获取每一列数据 for (i = 0; i < nHeight; i++) { pfData[i] = pfDst[i][x]; } cvDWT(pMatData, pMatCA, pMatCD, type);//对每一列数据进行一维快速小波变换 //将小波变换结果拼接到一起并设置到dst中 for (i = 0; i < nHeight; i++) { if (i < nHalfH) { pfDst[i][x] = pfCA[i]; } else { pfDst[i][x] = pfCD[i - nHalfH]; } } } cvReleaseMat(&pMatData); cvReleaseMat(&pMatCA); cvReleaseMat(&pMatCD); //一层变换后的宽度长度缩小 nWidth = nHalfW; nHeight = nHalfH; nHalfW = nHalfW / 2; nHalfH = nHalfH / 2; nLayer--; } //缩放以便显示 cvScale(pMatDst, dst); }
相关文章推荐
- SSO单点登录的实现原理是怎样的
- Win7下用命令行方式收发邮件的方法
- Android的数字选择器NumberPicker-android学习之旅(三十七)
- Android的数字选择器NumberPicker-android学习之旅(三十七)
- Android的数字选择器NumberPicker-android学习之旅(三十七)
- Mat 的类型(type)
- 类似于微信通讯录的界面Demo
- 用例建模(设计)
- Android程序启动加载动画实现
- chapter10test8
- Java开发中的23种设计模式详解(转)
- 图像处理 一维快速小波变换
- 【hiho四十八周】 求最后感染到的病毒总数(拓扑排序模板)
- iOS键盘自适应高度
- 类模板友元函数坑死人不偿命的错误
- Linux常用网络工具:hping高级主机扫描
- Job found still running .Jobs should be canceled by the plugin that scheduled them during shutdown:
- 面试题之求二叉树的深度
- 如何清除tomcat缓存
- 两个栈实现队列 两个队列实现栈