www.pudn.com > WaveletsAndProcessing.rar > Diproc.cpp
// Diproc.cpp: implementation of the CDiproc class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "wavelets.h" #include "Diproc.h" #include "WvltTrans.h" #include#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDiproc::CDiproc() { } CDiproc::~CDiproc() { } /******************************************************************************** *函数描述: DIP_WvltRevers完成图像小波系数的复原,恢复出原始的图像数据 * *函数参数: short **spData :二维指针,指向原始的图像数据 * * short **spTransData0:小波变换系数,存放一次水平变换后的小波系数 * * short **spTransData1:小波变换系数,存放一次数值变换后的小波系数 * * int nHeight :图像属性参数,数值为原始图像的高度值 * * int nHeight_H :图像属性参数,数值为原始图像高度值的一半 * * int nWidth :图像属性参数,数值为原始图像的宽度值 * * int nWidth_H :图像属性参数,数值为原始图像宽度值的一半 * * int layer :小波变换的层数,数值为3层 * * float fRadius :小波变换因子,在调用时候已指定数值为1.414 * ********************************************************************************/ void CDiproc::DIP_WvltRevers(short **spData, short **spTransData0, short **spTransData1, int nHeight, int nHeight_H, int nWidth, int nWidth_H, int layer, float fRadius) { short **spOriginData, **spTransData, **spWvltData; int iHeight = (int)nHeight /pow(2,layer-1), iWidth =(int)nWidth / pow(2,layer-1); int iHeight_H =(int) nHeight_H / pow(2,layer-1), iWidth_H = (int)nWidth_H/ pow(2,layer-1); //分配图像复原所需的内存空间 spOriginData = spData; spTransData = spTransData0; spWvltData = spTransData1; //完成图像小波变换的逆变换 CWvltTrans *WTrans; for(int i = layer; i >= 1; i--) { WTrans->DWTi_Once(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, i, 1.414); iHeight <<= 1; iWidth <<= 1; iHeight_H <<= 1; iWidth_H <<= 1; } } /******************************************************************************** *函数描述: DIP_ConsEnhance完成图像对比度信息的增强,获取隐藏的图像信息 * *函数参数: short **spData :二维指针,指向原始的图像数据 * * int nHeight :图像属性参数,数值为原始图像的高度值 * * int nWidth :图像属性参数,数值为原始图像的宽度值 * * float *NormWvltRng :存放图像小波的正则化参数以及逆变换的正则化参数* ********************************************************************************/ void CDiproc::DIP_ConsEnhance(short **spData, int nHeight, int nWidth, float *NormWvltRng) { short **spOriginData, **spTransData, **spWvltData; float **fpNormGradient , filtCoeff[10], *fWvltRng; int iHeight = nHeight, iWidth = nWidth; int iHeight_H = nHeight / 2, iWidth_H = nWidth / 2; int x, y; fWvltRng = NormWvltRng; //为图像处理分配内存空间 spOriginData = spData; spTransData = new short * [nHeight]; spWvltData = new short * [nHeight]; fpNormGradient = new float * [nHeight]; for(int i = 0; i < nHeight; i ++) { spTransData[i] = new short [nWidth]; spWvltData[i] = new short [nWidth]; fpNormGradient[i] = new float [nWidth]; } //完成一次图像小波变换 CWvltTrans *pTrans; pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, 3, 1.414); //小波系数的正则化处理 //正则化处理后spData存放非正则化的小波系数,spWvltData存放正则化后的小波系数 Wvlt_Normalize(spWvltData, iHeight, iWidth, fWvltRng); //计算小波系数的梯度信息,将其存放在spTransData中 //设定显示设备的颜色灰度范围是0~255 for(y = 0; y < nHeight; y ++) { for(x = 0; x < nWidth; x ++) { fpNormGradient[y][x] = (float) spWvltData[y][x] / 255; } } //选择线性滤波器gj(x) = x, 且v =kj gj(u) //统计出不同频带小波系数的极大值 for(y = 0; y < 3; y ++) { if(y == 0) { filtCoeff[4*y] = Search_BandMax(spWvltData, 0, 0, iHeight / 8, iWidth / 8); } filtCoeff[3*y + 1] = Search_BandMax(spWvltData, 0, (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 8), (int)(pow(2,y)*iWidth / 4)); filtCoeff[3*y + 2] = Search_BandMax(spWvltData, (int)(pow(2,y) * iHeight / 8), 0, (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 8)); filtCoeff[3*y + 3] = Search_BandMax(spWvltData, (int)(pow(2,y) * iHeight / 8), (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 4)); } //计算得到各频带滤波器的滤波系数 for(y = 0; y < 10; y++) { filtCoeff[y] = (float) 255.0 / filtCoeff[y]; filtCoeff[0] += (float)sqrt(filtCoeff[y]); } filtCoeff[0] /= 10; //正则化后小波信息的梯度信息滤波处理 for(y = 0; y < 3; y ++) { if(y == 0) { Band_Enhance(fpNormGradient, filtCoeff[3*y], 0, 0, iHeight / 8, iWidth / 8); } Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 1]) /2, 0, (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 8), (int)(pow(2,y)*iWidth / 4)); Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 2]) /2, (int)(pow(2,y) * iHeight / 8), 0, (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 8)); Band_Enhance(fpNormGradient, (float)sqrt(filtCoeff[3*y + 3]) /2, (int)(pow(2,y) * iHeight / 8), (int)(pow(2,y) * iWidth / 8), (int)(pow(2,y)* iHeight / 4), (int)(pow(2,y)*iWidth / 4)); } //还原出滤波增强后的小波系数 for(y = 0; y< iHeight; y ++) { for(x = 0; x < iWidth; x++) { fpNormGradient[y][x] *= (float) (fWvltRng[1] - fWvltRng[0]); fpNormGradient[y][x] /= 255.0; spWvltData[y][x] = (short) fpNormGradient[y][x] + fWvltRng[0]; } } //复原增强后的小波系数 DIP_WvltRevers(spOriginData, spTransData, spWvltData, iHeight, iHeight_H, iWidth, iWidth_H, 3, 1.414); //将复原的图像数据进行正则化 Wvlt_Normalize(spOriginData, iHeight, iWidth, fWvltRng); //释放临时的数据空间 delete spTransData; delete spWvltData; delete fpNormGradient; } /******************************************************************************** *函数描述: DIP_ImageFusion完成两幅图像的融合,恢复出原始的图像 * *函数参数: short **spImgData0 :二维指针,存放其中一幅原始图像的数据 * * short **spImgData1 :二维指针,存放其中另外一幅原始图像的数据 * * int nHeight :图像属性参数,数值为原始图像的高度值 * * int nWidth :图像属性参数,数值为原始图像的宽度值 * ********************************************************************************/ void CDiproc::DIP_ImageFusion(short **spImgData0, short **spImgData1, int nHeight, int nWidth) { //获取图像的属性参数 int iHeight = nHeight, iWidth = nWidth; //图像融合所用到的数据空间及数据指针 short **spOriginData, **spTransData, **spWvltData0, **spWvltData1; //分配数据空间 spTransData = new short *[iHeight]; spWvltData0 = new short *[iHeight]; spWvltData1 = new short *[iHeight]; for(int i = 0; i < iWidth; i ++) { spTransData[i] = new short [iWidth]; spWvltData0[i] = new short [iWidth]; spWvltData1[i] = new short [iWidth]; } //创建小波变换类,完成图像的小波变换 CWvltTrans *pTrans; //获得图像数据空间的指针,完成小波变换 spOriginData = spImgData0; //三层小波变换 pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData0, iHeight, iHeight / 2, iWidth, iWidth / 2, 1, 1.414); //获得图像数据空间的指针,完成另一幅图像的小波变换 spOriginData = spImgData1; //三层小波变换 pTrans->DWT_TriLayers(spOriginData, spTransData, spWvltData1, iHeight,iHeight / 2, iWidth, iWidth / 2, 1, 1.414); //小波系数的融合处理:频带有LL3,LH3,HL3,HH3,LH2,HL2,HH2,LH1,HL1,HH1 //融合处理将分频带进行,处理方法采用的是3*3的窗口 //LL3频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, 0, 0, iHeight / 8, iWidth / 8); //HL3频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 8, iHeight / 8, iWidth / 4); //LH3频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 8, 0, iHeight / 4, iWidth / 8); //HH3频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 8, iWidth / 8, iHeight / 4, iWidth / 4); //HL2频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 4, iHeight / 4, iWidth / 2); //LH2频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 4, 0, iHeight / 2, iWidth / 4); //HH2频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 4, iWidth / 4, iHeight / 2, iWidth / 2); //HL1频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, 0, iWidth / 2, iHeight / 2, iWidth); //LH1频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 2, 0, iHeight, iWidth / 2); //HH1频带小波系数的融合 Window_WvltFusion(spWvltData0, spWvltData1, iHeight / 2, iWidth / 2, iHeight, iWidth); //将融合后的小波系数复原,完成图像的融合 DIP_WvltRevers(spOriginData, spTransData, spWvltData0, iHeight, iHeight / 2, iWidth, iWidth / 2, 1, 1.414); //释放临时的数据空间 delete spTransData; delete spWvltData0; delete spWvltData1; } /******************************************************************************** *函数描述: Wvlt_Normalize完成图像小波数据与逆变换数据的正则化处理 * *函数参数: short **spWvltNormData:二维指针,存放正则化后的小波系数 * * int nHeight :图像属性参数,数值为原始图像的高度值 * * int nHeight_H :图像属性参数,数值为原始图像高度值的一半 * * int nWidth :图像属性参数,数值为原始图像的宽度值 * * float *NormWvltRng :存放图像小波的正则化参数以及逆变换的正则化参数* ********************************************************************************/ void CDiproc::Wvlt_Normalize(short **spWvltNormData, int nHeight, int nWidth, float *nWvltRng) { int MaxPixVal, MinPixVal, Diff; int x, y; float NormCoeff; MaxPixVal=spWvltNormData[0][0]; MinPixVal=spWvltNormData[0][0]; for( y=0; y < nHeight; y++) { for( x=0; x < nWidth; x++) { if(MaxPixVal spWvltNormData[y][x]) MinPixVal=spWvltNormData[y][x]; //spWvltData[y][x] = spWvltNormData[y][x]; } } Diff=MaxPixVal-MinPixVal; nWvltRng[1] = MaxPixVal; nWvltRng[0] = MinPixVal; for(y=0; y < nHeight; y++) { for(x=0; x < nWidth; x++) { //因为小波变换后的小波系数有可能超过255甚至更多,那么就将 //小波系数的范围映射到0~255区间内,以后出现类似的处理,目的都是一样的 NormCoeff = spWvltNormData[y][x]; NormCoeff -= MinPixVal; NormCoeff *= 255; NormCoeff /= (float) Diff; spWvltNormData[y][x] = NormCoeff; } } } /********************************************************************************* *函数描述: Window_WvltFusion完成图像小波系数的融合操作,得到各频带的小波融合数据* *函数参数: short **spWvltData0 :二维指针,存放其中一幅图像的原始小波系数 * * short **spWvltData1 :二维指针,存放其中另外一幅图像的原始小波系数 * * int Scan_y :扫描线起始横坐标 * * int Scan_x :扫描线起始纵坐标 * * int End_y :扫描线终止横坐标 * * int End_x :扫描线终止纵坐标 * *********************************************************************************/ void CDiproc::Window_WvltFusion(short **spWvltData0, short **spWvltData1, int Scan_y, int Scan_x, int End_y, int End_x) { int y,x; short WndSum0, WndSum1; for(y = Scan_y; y < End_y; y ++) { for(x = Scan_x; x < End_x; x ++) { //初始化窗口中小波系数的和 WndSum0 = 0; WndSum1 = 0; //计算窗口中小波系数的和 for(int i = -1; i <= 1; i++) { for(int j = -1; j <= 1; j++) { if( (y+i) < Scan_y || (x+j) < Scan_x || (y+i) >= End_y || (x+j) >= End_x) { WndSum0 += 0; WndSum1 += 0; } else { WndSum0 += abs((int)spWvltData0[y + i][x + j]); WndSum1 += abs((int)spWvltData1[y + i][x + j]); } } } if(WndSum0 < WndSum1) spWvltData0[y][x] = spWvltData1[y][x]; } } } float CDiproc::Search_BandMax(short **spWvltData, int Scan_y, int Scan_x, int End_y, int End_x) { int x, y; float Band_max; Band_max = 0; for(y = Scan_y; y < End_y; y ++) { for(x = Scan_x; x < End_x; x ++) { if(Band_max < spWvltData[y][x]) Band_max = spWvltData[y][x]; } } return Band_max; } void CDiproc::Band_Enhance(float **fpNormGradient, float FilterCoeff, int Scan_y, int Scan_x, int End_y, int End_x) { for(int y = Scan_y; y < End_y; y ++) for(int x = Scan_x; x < End_x; x ++) fpNormGradient[y][x] *= (float)(255.0 * FilterCoeff); }