#include <iostream.h> #include <cv.h> #include <highgui.h> // 二维离散小波变换 ( 单通道浮点图像 ) void DWT(IplImage *pimage, int nlayer) // 执行条件 if (pimage) if (pimage->nchannels == 1 && pimage->depth == IPL_DEPTH_32F && ((pimage->width >> nlayer) << nlayer) == pimage->width && ((pimage->height >> nlayer) << nlayer) == pimage->height) int i, x, y, n; float fvalue = 0; float fradius = sqrt(2.0f); int nwidth = pimage->width; int nheight = pimage->height; int nhalfw = nwidth / 2; int nhalfh = nheight / 2; float **pdata = new float*[pimage->height]; float *prow = new float[pimage->width]; float *pcolumn = new float[pimage->height]; for (i = 0; i < pimage->height; i++) pdata[i] = (float*) (pimage->imagedata + pimage->widthstep * i); // 多层小波变换 for (n = 0; n < nlayer; n++, nwidth /= 2, nheight /= 2, nhalfw /= 2, nhalfh /= 2) // 水平变换 for (y = 0; y < nheight; y++) // 奇偶分离 memcpy(prow, pdata[y], sizeof(float) * nwidth); x = i * 2; pdata[y][i] = prow[x]; pdata[y][nhalfw + i] = prow[x + 1]; // 提升小波变换 for (i = 0; i < nhalfw - 1; i++)
fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] -= fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwidth - 1] -= fvalue; fvalue = (pdata[y][nhalfw] + pdata[y][nhalfw + 1]) / 4; pdata[y][0] += fvalue; for (i = 1; i < nhalfw; i++) fvalue = (pdata[y][nhalfw + i] + pdata[y][nhalfw + i - 1]) / 4; pdata[y][i] += fvalue; pdata[y][i] *= fradius; pdata[y][nhalfw + i] /= fradius; // 垂直变换 for (x = 0; x < nwidth; x++) // 奇偶分离 y = i * 2; pcolumn[i] = pdata[y][x]; pcolumn[nhalfh + i] = pdata[y + 1][x]; for (i = 0; i < nheight; i++) pdata[i][x] = pcolumn[i]; // 提升小波变换 for (i = 0; i < nhalfh - 1; i++) fvalue = (pdata[i][x] + pdata[i + 1][x]) / 2; pdata[nhalfh + i][x] -= fvalue; fvalue = (pdata[nhalfh - 1][x] + pdata[nhalfh - 2][x]) / 2; pdata[nheight - 1][x] -= fvalue; fvalue = (pdata[nhalfh][x] + pdata[nhalfh + 1][x]) / 4; pdata[0][x] += fvalue;
for (i = 1; i < nhalfh; i++) fvalue = (pdata[nhalfh + i][x] + pdata[nhalfh + i - 1][x]) / 4; pdata[i][x] += fvalue; pdata[i][x] *= fradius; pdata[nhalfh + i][x] /= fradius; delete[] pdata; delete[] prow; delete[] pcolumn; // 二维离散小波恢复 ( 单通道浮点图像 ) void IDWT(IplImage *pimage, int nlayer) // 执行条件 if (pimage) if (pimage->nchannels == 1 && pimage->depth == IPL_DEPTH_32F && ((pimage->width >> nlayer) << nlayer) == pimage->width && ((pimage->height >> nlayer) << nlayer) == pimage->height) int i, x, y, n; float fvalue = 0; float fradius = sqrt(2.0f); int nwidth = pimage->width >> (nlayer - 1); int nheight = pimage->height >> (nlayer - 1); int nhalfw = nwidth / 2; int nhalfh = nheight / 2; float **pdata = new float*[pimage->height]; float *prow = new float[pimage->width]; float *pcolumn = new float[pimage->height]; for (i = 0; i < pimage->height; i++) pdata[i] = (float*) (pimage->imagedata + pimage->widthstep * i);
// 多层小波恢复 for (n = 0; n < nlayer; n++, nwidth *= 2, nheight *= 2, nhalfw *= 2, nhalfh *= 2) // 垂直恢复 for (x = 0; x < nwidth; x++) pdata[i][x] /= fradius; pdata[nhalfh + i][x] *= fradius; // 提升小波恢复 fvalue = (pdata[nhalfh][x] + pdata[nhalfh + 1][x]) / 4; pdata[0][x] -= fvalue; for (i = 1; i < nhalfh; i++) fvalue = (pdata[nhalfh + i][x] + pdata[nhalfh + i - 1][x]) / 4; pdata[i][x] -= fvalue; for (i = 0; i < nhalfh - 1; i++) fvalue = (pdata[i][x] + pdata[i + 1][x]) / 2; pdata[nhalfh + i][x] += fvalue; fvalue = (pdata[nhalfh - 1][x] + pdata[nhalfh - 2][x]) / 2; pdata[nheight - 1][x] += fvalue; // 奇偶合并 y = i * 2; pcolumn[y] = pdata[i][x]; pcolumn[y + 1] = pdata[nhalfh + i][x]; for (i = 0; i < nheight; i++) pdata[i][x] = pcolumn[i]; // 水平恢复 for (y = 0; y < nheight; y++)
pdata[y][i] /= fradius; pdata[y][nhalfw + i] *= fradius; // 提升小波恢复 fvalue = (pdata[y][nhalfw] + pdata[y][nhalfw + 1]) / 4; pdata[y][0] -= fvalue; for (i = 1; i < nhalfw; i++) fvalue = (pdata[y][nhalfw + i] + pdata[y][nhalfw + i - 1]) / 4; pdata[y][i] -= fvalue; for (i = 0; i < nhalfw - 1; i++) fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] += fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwidth - 1] += fvalue; // 奇偶合并 x = i * 2; prow[x] = pdata[y][i]; prow[x + 1] = pdata[y][nhalfw + i]; memcpy(pdata[y], prow, sizeof(float) * nwidth); delete[] pdata; delete[] prow; delete[] pcolumn; void main() // 小波变换层数 int nlayer =1; // 输入彩色图像 IplImage *psrc = cvloadimage("lena.bmp", CV_LOAD_IMAGE_COLOR); // 计算小波图象大小
CvSize size = cvgetsize(psrc); if ((psrc->width >> nlayer) << nlayer!= psrc->width) size.width = ((psrc->width >> nlayer) + 1) << nlayer; if ((psrc->height >> nlayer) << nlayer!= psrc->height) size.height = ((psrc->height >> nlayer) + 1) << nlayer; // 创建小波图象 IplImage *pwavelet = cvcreateimage(size, IPL_DEPTH_32F, psrc->nchannels); if (pwavelet) // 小波图象赋值 cvsetimageroi(pwavelet, cvrect(0, 0, psrc->width, psrc->height)); cvconvertscale(psrc, pwavelet, 1, -128); cvresetimageroi(pwavelet); // 彩色图像小波变换 IplImage *pimage = cvcreateimage(cvgetsize(pwavelet), IPL_DEPTH_32F, 1); if (pimage) for (int i = 1; i <= pwavelet->nchannels; i++) cvsetimagecoi(pwavelet, i); cvcopy(pwavelet, pimage, NULL); // 二维离散小波变换 DWT(pImage, nlayer); // 二维离散小波恢复 // IDWT(pImage, nlayer); cvcopy(pimage, pwavelet, NULL); cvsetimagecoi(pwavelet, 0); cvreleaseimage(&pimage); // 小波变换图象 cvsetimageroi(pwavelet, cvrect(0, 0, psrc->width, psrc->height)); cvconvertscale(pwavelet, psrc, 1, 128); cvresetimageroi(pwavelet); // 本行代码有点多余, 但有利用养成良好的编程习惯 cvreleaseimage(&pwavelet); // 显示图像 psrc cvnamedwindow("yuhuan",0); cvshowimage("yuhuan",psrc);
cvwaitkey(10000); cvreleaseimage(&psrc);