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

📄 wvlttrans.cpp

📁 一种图像水印加密算法 该算法抗攻击性强 安全性高 可以直接运行
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// WvltTrans.cpp: implementation of the CWvltTrans class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WvltTrans.h"
#include <stdlib.h>
#include <stdio.h>


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//引用外部的全局变量
extern CString MarkFile;
const double strength = 0.1;//嵌入强度因子
//CString CoeffChoosedSavePath;
CString FileName[PIC_NUM];
 char currentpath[MAX_PATH];
 CString SavePath;//加水印后图像保存路径
 CString picName;//原始图像名,不包括路径部分 
 unsigned char* m_pBitmap;//位图数据缓冲区

 BITMAPFILEHEADER BFH;//原始图像文件头
 BITMAPINFOHEADER BIH;//原始图像信息头
 LPBITMAPFILEHEADER lpBFHMark;//水印文件文件头
 LPBITMAPINFOHEADER lpBIHMark;//水印文件信息头及调色板
 
 unsigned long biHeight ;
 unsigned long biWidth ;
 unsigned long biAlign ;//原始图像每行字节数
 unsigned long bmSize ;//原始图像大小字节数
 int layer;//原始图像DWT变换层数
 float **pY,**pU,**pV;//存原始图的Y、U、V分量
 float** m_WvltCoeff;//小波变换后的系数数组
	 
float **LL1,**LL2,**LL3,**LH1,**LH2,**LH3,**HL1,**HL2,**HL3,**HH1,**HH2,**HH3;//存放变换后各子带系数
float** CoeffAfterLoad;//加载水印后的所有系数
float** CoeffIDWT;//3层小波逆变换后的系数
float** CoeffChoosed;//存放嵌入位置

//水印全局变量
unsigned long MarkLength;//水印长度
unsigned long MarkHeight;//水印图像高像素数
unsigned long MarkWidth;//水印图像宽像素数
unsigned long bmSizeMark;//水印图像数据大小字节数

BYTE* pMarkData;//水印数据数组
BYTE* DistillMarkData;//对单个图像提取出的水印灰度值
BYTE* lpDataMark ;//水印图像数据,无论是灰度图像还是彩色图像,此数组中每像素均占3字节
int* WaterMarkOrigin;//一维数组,存放原始水印信息(二值信息)
int* WaterMarkForLoad;


CWvltTrans::CWvltTrans()
{
	
	

}

CWvltTrans::~CWvltTrans()
{
	if (WaterMarkOrigin != NULL)
	{
		delete []WaterMarkOrigin;
		WaterMarkOrigin = NULL;
	}
	if(pMarkData != NULL)
	{
		delete []pMarkData;
		pMarkData = NULL;
	}
	if(lpDataMark != NULL)
	{
		delete []lpDataMark;
		lpDataMark = NULL;
	}
	
	delete []lpBFHMark;
	lpBFHMark = NULL;
	delete []lpBIHMark;
	lpBIHMark = NULL;

	for(int i = 0; i < biHeight; i++)
	{
		delete []CoeffChoosed[i];//检测后将选定系数空间删除
		
		CoeffChoosed[i] = NULL;
        
	}
	delete []CoeffChoosed;	
	CoeffChoosed = NULL;
	delete []DistillMarkData;	
	DistillMarkData = NULL;	
	
}


/********************************************************************************
*函数描述:Hori_Transform完成一次图像水平方向的小波变换							*	
*函数参数:short **spOriginData:二维指针,指向原始的图像数据					*
*		  short **spTransData0:小波变换系数,存放一次水平变换后的小波系数		*
*		  int   nHeight		  :图像属性参数,数值为原始图像的高				*
*		  int	nWidth_H	  :图像属性参数,数值为原始图像宽度值的一半		*
*		  float fRadius		  :小波变换因子,在调用时候已指定数值为1			*
********************************************************************************/

void CWvltTrans::Hori_Transform(float** spOriginData, float** spTransData0, int nHeight, int nWidth_H, float fRadius)
{
    int Trans_W = 0,				//图像扫描线控制:横坐标
		Trans_H = 0,				//图像扫描线控制:纵坐标
		Trans_M = 0,				//图像矩阵的横坐标
		Trans_N = 0;				//图像矩阵的纵坐标
 	int iWidth = nWidth_H * 2;	//原始图像的宽度值
	int Trans_Coeff0;			//小波变换系数
    signed int Trans_Coeff1;
	//本模块完成变换系数的赋值采样
    for(Trans_H = 0; Trans_H < nHeight; Trans_H ++)            
	{
			for(Trans_N = 0; Trans_N < nWidth_H; Trans_N ++)           
			{
				Trans_W = Trans_N << 1;
	            if (fRadius == 2)
				{
					spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]);
                    spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]);
				}
	            else
				{
                    spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]-128);		//even
                    spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]-128);	//odd
				}
	   		}
	}
	//通过图像的差分,完成小波变换
	for(Trans_H=0; Trans_H<nHeight; Trans_H++)
	{
		for(Trans_N=0; Trans_N<nWidth_H-1; Trans_N++)
		{
			//奇偶数值和的一半
			Trans_Coeff1 = (int)((spTransData0[Trans_H][Trans_N]+spTransData0[Trans_H][Trans_N+1])/2);	
			//逻辑非操作后数值加1
			Trans_Coeff1=~Trans_Coeff1+1;	
			//系数预测
			spTransData0[Trans_H][nWidth_H+Trans_N] = spTransData0[Trans_H][nWidth_H+Trans_N]+Trans_Coeff1;	
		}
		//完成一个偶系数的边界处理
		Trans_Coeff1 = (int)((spTransData0[Trans_H][nWidth_H-1]+spTransData0[Trans_H][nWidth_H-2])/2);
		Trans_Coeff1=~Trans_Coeff1+1;
		spTransData0[Trans_H][iWidth-1] = spTransData0[Trans_H][iWidth-1]+Trans_Coeff1;
		//完成一个奇系数的边界处理
		Trans_Coeff0 = (int)((spTransData0[Trans_H][nWidth_H]+spTransData0[Trans_H][nWidth_H+1])/4);
		spTransData0[Trans_H][0] = spTransData0[Trans_H][0]+Trans_Coeff0;
		//提升,整数到整数的变换
		for(Trans_N=1; Trans_N<nWidth_H; Trans_N++)
		{
			Trans_Coeff0 = (int)((spTransData0[Trans_H][nWidth_H+Trans_N]+spTransData0[Trans_H][nWidth_H+Trans_N-1])/4);
			spTransData0[Trans_H][Trans_N] = spTransData0[Trans_H][Trans_N]+Trans_Coeff0;
		}

	}
}

/********************************************************************************
*函数描述:	Vert_Transform完成一次图像竖直方向的小波变换						*	
*函数参数:	short **spOriginData:二维指针,指向原始的图像数据					*
*			short **spTransData1:小波变换系数,存放一次竖直变换后的小波系数	*
*			int   nHeight_H		:图像属性参数,数值为原始图像高度值的一半		*
*			int	  nWidth		:图像属性参数,数值为原始图像宽度				*
*			float fRadius		:小波变换因子,在调用时候已指定数值为1		*
********************************************************************************/
void CWvltTrans::Vert_Transform(float** spOriginData, float** spTransData1, int nHeight_H, int nWidth, float fRadius)
{
	int Trans_W = 0,				//图像扫描线控制:横坐标
		Trans_H = 0,				//图像扫描线控制:纵坐标
		Trans_M = 0,				//图像矩阵的横坐标
		Trans_N = 0;				//图像矩阵的纵坐标
 	int iHeight = nHeight_H * 2;//原始图像的宽度值
	int Trans_Coeff0;			//小波变换系数
    signed int Trans_Coeff1;
	//本模块完成变换系数的赋值采样
	for(Trans_W = 0; Trans_W < nWidth; Trans_W ++)            
	{
			for(Trans_M = 0; Trans_M < nHeight_H; Trans_M ++)           
			{
				Trans_H = Trans_M << 1;
	            if (fRadius == 2)
				{
					spTransData1[Trans_M][Trans_W] = (spOriginData[Trans_H][Trans_W]);
                    spTransData1[nHeight_H + Trans_M][Trans_W] = (spOriginData[Trans_H+1][Trans_W]);
				}
	            else
				{
                    spTransData1[Trans_M][Trans_W] = (spOriginData[Trans_H][Trans_W]-128);		//even
                    spTransData1[nHeight_H + Trans_M][Trans_W] = (spOriginData[Trans_H+1][Trans_W]-128);	//odd
				}
	   		}
	}
	//通过图像的差分,完成小波变换
	for(Trans_W=0; Trans_W<nWidth; Trans_W++)
	{
		for(Trans_M=0; Trans_M<nHeight_H-1; Trans_M++)
		{
			//奇偶数值和的一半
			Trans_Coeff1 = (int)((spTransData1[Trans_M][Trans_W]+spTransData1[Trans_M+1][Trans_W])/2);	
			//逻辑非操作后数值加1
			Trans_Coeff1=~Trans_Coeff1+1;	
			//系数预测
			spTransData1[nHeight_H + Trans_M][Trans_W] = spTransData1[nHeight_H + Trans_M][Trans_W]+Trans_Coeff1;
		}
		//完成一个偶系数的边界处理
		Trans_Coeff1 = (int)((spTransData1[nHeight_H-1][Trans_W]+spTransData1[nHeight_H-2][Trans_W])/2);
		Trans_Coeff1=~Trans_Coeff1+1;
		spTransData1[iHeight-1][Trans_W] = spTransData1[iHeight-1][Trans_W]+Trans_Coeff1;
		//完成一个奇系数的边界处理
		Trans_Coeff0 = (int)((spTransData1[nHeight_H][Trans_W]+spTransData1[nHeight_H+1][Trans_W])/4);
		spTransData1[0][Trans_W] = spTransData1[0][Trans_W]+Trans_Coeff0;
		//提升,整数到整数的变换
		for(Trans_M=1; Trans_M<nHeight_H; Trans_M++)
		{
			Trans_Coeff0 = (int)((spTransData1[nHeight_H + Trans_M][Trans_W]+spTransData1[nHeight_H + Trans_M -1][Trans_W])/4);
			spTransData1[Trans_M][Trans_W] = spTransData1[Trans_M][Trans_W]+Trans_Coeff0;
		}

	}
}

/********************************************************************************
*函数描述:	DWT_Once完成一次图像的小波变换										*
*函数参数:	short **spOriginData:二维指针,指向原始的图像数据					*
*			short **spTransData0:小波变换系数,存放一次水平变换后的小波系数	*
*			short **spTransData1:小波变换系数,存放一次竖直变换后的小波系数	*
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			*
*			int	  nHeight_H		:图像属性参数,数值为原始图像高度值的一半		*
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			*
*			int	  nWidth_H		:图像属性参数,数值为原始图像宽度值的一半		*
*			int   layer			:小波变换的层数,数值为1层						*
*			float fRadius		:小波变换因子,在调用时候已指定数值为1.414		*
********************************************************************************/

void CWvltTrans::DWT_Once(float** spOriginData, float** spTransData0, float** spTransData1, int nHeight, int nHeight_H, int nWidth, int nWidth_H, int layer, float fRadius)
{
	int Trans_W,				//图像扫描线控制:横坐标
		Trans_H,				//图像扫描线控制:纵坐标
		Trans_M,				//图像矩阵的横坐标
		Trans_N;				//图像矩阵的纵坐标
	int Trans_Coeff0;			//小波变换系数
    signed int Trans_Coeff1;
	fRadius=1.414f;				//变换滤波系数,此小波为Haar小波
	//本模块完成变换系数的赋值采样
	//行变换,第一次(layer=1时)时nHeight即为原始图像的高度值
    for(Trans_H=0; Trans_H<nHeight; Trans_H++)            
	{
		if(layer == 1)//第一层小波变换
		{
			 //layer=1时,nWidth_H为原始图像宽度值的一半
			for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)          
			{
				Trans_W=Trans_N<<1;
	            if (fRadius==2)
				{
					spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]);
                    spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]);
				}
	            else
				{
                    spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]-128);	//加载彩色图像水印时此处有错,为何要减去128?	
                    spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]-128);	
				}
	   		}
		}
		//若变换层数大于1,则仅采样低频的小波系数
		if(layer > 1)
		{
			for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
			{
				Trans_W = Trans_N<<1;
				spTransData0[Trans_H][Trans_N] = spTransData1[Trans_H][Trans_W];
				spTransData0[Trans_H][nWidth_H+Trans_N] = spTransData1[Trans_H][Trans_W+1];
			}
		}
	}

	for(Trans_H=0; Trans_H<nHeight; Trans_H++)
	{
		for(Trans_N=0; Trans_N<nWidth_H-1; Trans_N++)
		{
			//奇偶数值和的一半
			Trans_Coeff1 = (int)((spTransData0[Trans_H][Trans_N]+spTransData0[Trans_H][Trans_N+1])/2);	
			//逻辑非操作后数值加1
			Trans_Coeff1 = ~Trans_Coeff1 + 1;	
			//系数预测
			spTransData0[Trans_H][nWidth_H+Trans_N] = spTransData0[Trans_H][nWidth_H+Trans_N]+Trans_Coeff1;	
		}
		//完成一个偶系数的边界处理
		Trans_Coeff1 = (int)((spTransData0[Trans_H][nWidth_H-1]+spTransData0[Trans_H][nWidth_H-2])/2);
		Trans_Coeff1 = ~Trans_Coeff1 + 1;
		spTransData0[Trans_H][nWidth-1] = spTransData0[Trans_H][nWidth-1]+Trans_Coeff1;
		//完成一个奇系数的边界处理
		Trans_Coeff0 = (int)((spTransData0[Trans_H][nWidth_H]+spTransData0[Trans_H][nWidth_H+1])/4);
		spTransData0[Trans_H][0] = spTransData0[Trans_H][0]+Trans_Coeff0;
		//提升,整数到整数的变换
		for(Trans_N=1; Trans_N<nWidth_H; Trans_N++)
		{
			Trans_Coeff0 = ((spTransData0[Trans_H][nWidth_H+Trans_N]+spTransData0[Trans_H][nWidth_H+Trans_N-1])/4);
			spTransData0[Trans_H][Trans_N] = spTransData0[Trans_H][Trans_N]+Trans_Coeff0;
		}

	}//水平方向的变换结束
	
	//竖直方向的变换开始,数据源为水平变换后的小波系数
	for(Trans_M=0; Trans_M<nHeight; Trans_M++)
	{
		for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
		{
			spTransData0[Trans_M][Trans_N] *= fRadius;
			spTransData0[Trans_M][Trans_N+nWidth_H] /= fRadius;
		}
	}
	//行提升后的数据在spTransData0中,spTransData0中的数据自然奇偶有序
	for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
	{
		//列变换
		for(Trans_M=0; Trans_M<nHeight_H; Trans_M++)
		{
			Trans_H = Trans_M<<1;//Trans_H为Trans_M的2倍
			//频带LL部分
			spTransData1[Trans_M][Trans_N] = spTransData0[Trans_H][Trans_N];
			//频带HL部分
			spTransData1[nHeight_H+Trans_M][Trans_N] = spTransData0[Trans_H+1][Trans_N];
			//频带LH部分
			spTransData1[Trans_M][nWidth_H+Trans_N] = spTransData0[Trans_H][nWidth_H+Trans_N];	
			//频带HH部分
			spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N] = spTransData0[Trans_H+1][nWidth_H+Trans_N];
		}
		//第一次提升奇数坐标系数
		for(Trans_M=0; Trans_M<nHeight_H-1; Trans_M++)
		{
		//竖直方向的变换 
			Trans_Coeff1 = (int)((spTransData1[Trans_M][Trans_N]+spTransData1[Trans_M+1][Trans_N])/2);
			Trans_Coeff1 = ~Trans_Coeff1+1;
			spTransData1[nHeight_H+Trans_M][Trans_N] = spTransData1[nHeight_H+Trans_M][Trans_N]+Trans_Coeff1;
			Trans_Coeff1 = ((spTransData1[Trans_M][nWidth_H+Trans_N]+spTransData1[Trans_M+1][nWidth_H+Trans_N])/2);
			Trans_Coeff1 = ~Trans_Coeff1+1;
			spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N] = spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N]+Trans_Coeff1;
		}
		Trans_Coeff1 = (int)((spTransData1[nHeight_H-1][Trans_N]+spTransData1[nHeight_H-2][Trans_N])/2);
		Trans_Coeff1 = ~Trans_Coeff1+1;
		spTransData1[nHeight-1][Trans_N] = spTransData1[nHeight-1][Trans_N]+Trans_Coeff1;
		Trans_Coeff1 = (int)((spTransData1[nHeight_H-1][nWidth_H+Trans_N]+spTransData1[nHeight_H-2][nWidth_H+Trans_N])/2);
		Trans_Coeff1 = ~Trans_Coeff1+1;
		//边界处理
		spTransData1[nHeight-1][nWidth_H+Trans_N] = spTransData1[nHeight-1][nWidth_H+Trans_N]+Trans_Coeff1;

		Trans_Coeff0 = (int)((spTransData1[nHeight_H][Trans_N]+spTransData1[nHeight_H+1][Trans_N])/4);
		spTransData1[0][Trans_N] = spTransData1[0][Trans_N]+Trans_Coeff0;
		Trans_Coeff0 = (int)((spTransData1[nHeight_H][nWidth_H+Trans_N]+spTransData1[nHeight_H+1][nWidth_H+Trans_N])/4);
		//边界处理
		spTransData1[0][nWidth_H+Trans_N] = spTransData1[0][nWidth_H+Trans_N]+Trans_Coeff0;
		//第一次提升偶数坐标系数
		for(Trans_M=1; Trans_M<nHeight_H; Trans_M++)
		{
			Trans_Coeff0 = (int)((spTransData1[nHeight_H+Trans_M][Trans_N]+spTransData1[nHeight_H+Trans_M-1][Trans_N])/4);
			spTransData1[Trans_M][Trans_N] = spTransData1[Trans_M][Trans_N]+Trans_Coeff0;
			Trans_Coeff0 = (int)((spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N]+spTransData1[nHeight_H+Trans_M-1][nWidth_H+Trans_N])/4);
			spTransData1[Trans_M][nWidth_H+Trans_N] = spTransData1[Trans_M][nWidth_H+Trans_N]+Trans_Coeff0;
		}
	}
	
	//存放小波系数,LL频带的系数进行幅值增强处理,其它高频频带的系数则削弱其幅值	
	for(Trans_N=0; Trans_N<nWidth; Trans_N++)//控制列
	{
		for(Trans_M=0; Trans_M<nHeight_H; Trans_M++)//控制行
		{
			spTransData1[Trans_M][Trans_N] *= fRadius;
			spTransData1[Trans_M+nHeight_H][Trans_N] /= fRadius;
		}
	}
	/*
	//把低频LL系数输出到文件
	ofstream fout("nfile.txt");
	for(int i=0; i<Trans_M; i++)//控制行
	{
		for(int j=0; j<Trans_N; j++)//控制列
		{
			fout << spTransData1[i][j] << " ";
		}
		fout << endl;
	}
	
	//把所有系数输出到文件,我修改的
	ofstream fout("nfile.txt");
	for(int i=0; i<nHeight; i++)//控制行
	{
		for(int j=0; j<nWidth; j++)//控制列
		{
			fout << spTransData1[i][j] << " ";
		}
		fout << endl;
	}	
   */
}

/********************************************************************************
*函数描述:	DWT_TwoLayers完成一层以上图像的小波变换									*	
*函数参数:	short **spOriginData:二维指针,指向原始的图像数据					*
*			short **spTransData0:小波变换系数,存放一次水平变换后的小波系数	*
*			short **spTransData1:小波变换系数,存放一次竖直变换后的小波系数	*
*			int   nHeight		:图像属性参数,数值为原始图像的高度值			*
*			int	  nHeight_H		:图像属性参数,数值为原始图像高度值的一半		*
*			int   nWidth		:图像属性参数,数值为原始图像的宽度值			*
*			int	  nWidth_H		:图像属性参数,数值为原始图像宽度值的一半		*
*			int   layer			:小波变换的层数,数值为2层						*
*			float fRadius		:小波变换因子,在调用时候已指定数值为1.414		*
********************************************************************************/

void CWvltTrans::DWT_nLayers(float** spOriginData, float** spTransData0, float** spTransData1, int nHeight, int nHeight_H, int nWidth, int nWidth_H, int layer, float fRadius)
{
	int i;
	float **pData, **pTran0, **pTran1;

⌨️ 快捷键说明

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