⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diproc.cpp

📁 一种新型小波树构造程序
💻 CPP
字号:
// Diproc.cpp: implementation of the CDiproc class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "wavelets.h"
#include "Diproc.h"
#include "WvltTrans.h"
#include <math.h>

#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])
				MaxPixVal=spWvltNormData[y][x];
			if(MinPixVal>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);	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -