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

📄 multimark.cpp

📁 十分详细的基于Wavelet的图像水印嵌入程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		for(i=nTW;i<2*nTW;i++)			//读取HL层信息
		{
			for(j=0;j<nTW;j++)
			{
				nIn[nCount][0]=i;
				nIn[nCount][1]=j;
				nIn[nCount][2]=nLay;
				nIn[nCount][3]=nTemp[i][j];
				nCount++;
			}
		}
		nLay++;

		for(i=nTW;i<2*nTW;i++)			//读取HH层信息
		{
			for(j=nTW;j<2*nTW;j++)
			{
				nIn[nCount][0]=i;
				nIn[nCount][1]=j;
				nIn[nCount][2]=nLay;
				nIn[nCount][3]=nTemp[i][j];
				nCount++;
			}
		}
		nLay++;
		nTW=nTW*2;
		
	}
	nLength=nCount;

	FILE *fOutFile;

	fOutFile=fopen("d:\\BlockData.txt","w+");

	for(i=0;i<nLength;i++)
	{
		for(k=0;k<4;k++)
		{
			fprintf(fOutFile,"%8d",nIn[i][k]);
		}
		fprintf(fOutFile,"\n");
	}
	fclose(fOutFile);
}


void CMultiMarkView::TreeSearch()
{
	//nIn[][0]:x
	//nIn[][1]:y
	//nIn[][2]:层信息
	//nIn[][3]:系数

	//nMask[][0]:x
	//nMask[][1]:y
	//nMask[][2]:层信息

	int i;
	//搜索最大系数
	int nMax=0;
	int nPMax;
	int nCount;
	//阈值
	int nT;
	for(i=0;i<nLength;i++)
	{
		if(abs(nMax)<abs(nIn[i][3]))
		{
			nMax=nIn[i][3];			//纪录最大值
			nPMax=i;				//纪录最大值的位置
		}
	}

	nT=2<<((int)floor(log((double)abs(nMax))/log(2.0))-1);	//初始阈值

	nCount=0;
	do
	{		
		for(i=0;i<nLength;i++)
		{
			if(abs(nIn[i][3])>=nT && abs(nIn[i][3])<(2*nT))
			{
				nMask[nCount][0]=nIn[i][0];
				nMask[nCount][1]=nIn[i][1];
				nMask[nCount][2]=nIn[i][2];
				nCount++;
			}
		}
		nT=nT>>1;
	}while(nT>=1);
	
	for(i=0;i<nLength;i++)
	{
		if(nIn[i][3]==0 )
		{
			nMask[nCount][0]=nIn[i][0];
			nMask[nCount][1]=nIn[i][1];
			nMask[nCount][2]=nIn[i][2];
			nCount++;
		}
	}

	FILE *fOutFile;
	int k;

	fOutFile=fopen("d:\\MaskData.txt","w+");

	for(i=0;i<nLength;i++)
	{
		for(k=0;k<3;k++)
		{
			fprintf(fOutFile,"%4d",nMask[i][k]);
		}
//		fprintf(fOutFile,"\n");
	}
	fclose(fOutFile);
}


void CMultiMarkView::OnAdapdtiveWaveletWatermark() 
{
	CMultiMarkDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	int *pn;
	int *pnI;

	int nPW=pDoc->m_nWidth;
	int nPH=pDoc->m_nHeight;
	long lgSizePicture;
	lgSizePicture=nPW*nPH;
	long i,j;
	BYTE *pb;
	pb=pDoc->m_Dib.m_lpImage;
	pn=pDoc->m_pnPic;
	int nLineWidth;
	FILE *fOutFile;
	int *pnRandomMark;
	int nNum=1000;
	int nF;

	pnRandomMark=new int[1000];
	fOutFile=fopen("d:\\WaveletData.txt","w+");

	if( pDoc->m_nBitCount== 8 )
	{
		nLineWidth=(nPW+3)/4*4;
		pnI=new int[nPW*nPH];

		for( i = 0; i < lgSizePicture; i++ )	
			*( pnI + i) = (*( pDoc->m_pnPic+i)-128);

		m_IntWT.IntWT_2D( pnI, nPH, nPW, 1, 4 );
		BlockValue(pnI);
		TreeSearch();

			
		
		//生成随机水印
		RandomMark(pnRandomMark,nNum);
		for(i=0;i<nLength;i++)
		{
			fprintf(fOutFile,"%6d",pnI[nMask[i][0]*512+nMask[i][1]]);
		}

		fprintf(fOutFile,"\n\n\n");
		//嵌入水印信息
		for(i=0;i<nNum;i++)
		{
			//nF=(int)(dF[nMask[i][2]]*2.0+0.5);
			nF=(int)(dF[nMask[i][2]]+0.5);
			if(pnI[nMask[i][0]*512+nMask[i][1]]>0)
			{
				pnI[nMask[i][0]*512+nMask[i][1]]=pnI[nMask[i][0]*512+nMask[i][1]]/nF*nF
					+(pnRandomMark[i]*(nF/2));
			}else if(pnI[nMask[i][0]*512+nMask[i][1]]<0)
			{
				pnI[nMask[i][0]*512+nMask[i][1]]=pnI[nMask[i][0]*512+nMask[i][1]]/nF*nF
					-(pnRandomMark[i]*(nF/2));
			}
		}
		for(i=0;i<nLength;i++)
		{
			fprintf(fOutFile,"%6d",pnI[nMask[i][0]*512+nMask[i][1]]);
		}
//		ReadRandomMark(pnRandomMark,nNum);
//		Test(pnRandomMark,pnRandomMark,nNum);
		m_IntWT.IntWT_2D_I(pnI, nPH, nPW, 1, 4);
	}
	fclose(fOutFile);
	for(i=0;i<nPH;i++)
	{
		for(j=0;j<nPW;j++)
		{
			pb[i*nLineWidth+j]=(BYTE)(pnI[i*nPW+j]+128);
			pDoc->m_pbPic[i*nPW+j]=(BYTE)(pnI[i*nPW+j]+128);
		}
	}
	delete[] pnI;
	delete[] pnRandomMark;
	Invalidate();

}

//生成并存储随机水印图像
void CMultiMarkView::RandomMark(int *pnRandomMark, int nNum)
{
	int i;
	//生成伪随机种子
	srand((unsigned)time(NULL));

	for(i=0;i<nNum;i++)
	{
		pnRandomMark[i]=rand()%2;
	}

	//存储随机水印图像
	FILE *fOutFile;

	fOutFile=fopen("d:\\RandomMask.txt","w+");
	
	fprintf(fOutFile,"%6d",nNum);
	for(i=0;i<nNum;i++)
	{		
		fprintf(fOutFile,"%3d",pnRandomMark[i]);
	}
	fclose(fOutFile);
}

//读取随机水印图像
void CMultiMarkView::ReadRandomMark(int *pnRandomMark, int nNum)
{
	int i;
	//存储随机水印图像
	FILE *fOutFile;

	fOutFile=fopen("d:\\RandomMask.txt","r ");

	fscanf(fOutFile,"%6d",&nNum);
	for(i=0;i<nNum;i++)
	{
		fscanf(fOutFile,"%3d",&pnRandomMark[i]);
	}
	fclose(fOutFile);

	fOutFile=fopen("d:\\TestRandomMask.txt","w+");
	
	fprintf(fOutFile,"%6d",nNum);
	for(i=0;i<nNum;i++)
	{		
		fprintf(fOutFile,"%3d",pnRandomMark[i]);
	}
	fclose(fOutFile);
}

void CMultiMarkView::Test(int *pnOriMark, int *pnDrawMark, int nNum)
{
	int i;
	int nOriMark=0,nDrawMark=0;
	int nC=0;
	double dC;

	for(i=0;i<nNum;i++)
	{
		nOriMark=nOriMark+pnOriMark[i];
	}
	for(i=0;i<nNum;i++)
	{
		nDrawMark=nDrawMark+pnDrawMark[i];
	}
	for(i=0;i<nNum;i++)
	{
		nC=nC+pnOriMark[i]*pnDrawMark[i];
	}
	dC=((double)nC)/(sqrt((double)nOriMark)*sqrt((double)nDrawMark));
	CString str;
	str.Format("相似度检测: %10.4f",dC);
	AfxMessageBox(str,MB_OK,0);	
}

void CMultiMarkView::ReadPoint(int nNum)
{
	FILE *fOutFile;
	int i,k;

	fOutFile=fopen("d:\\MaskData.txt","r");

	for(i=0;i<nNum;i++)
	{
		for(k=0;k<3;k++)
		{
			fscanf(fOutFile,"%4d",&nMask[i][k]);
		}
	}
	fclose(fOutFile);
}


//水印图像的检测                        
void CMultiMarkView::OnAdapdtiveWaveletWatermarkDraw() 
{
	CMultiMarkDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);	
	int *pnI;

	int nPW=pDoc->m_nWidth;
	int nPH=pDoc->m_nHeight;
	long lgSizePicture;
	lgSizePicture=nPW*nPH;
	long i;

	int *pnRandomMark,*pnDrawMark;
	int nNum=1000;
	int nF;

	//pnRandomMark表示已经存在的标准水印信息
	pnRandomMark=new int[1000];
	//pnDrawMark表示从图像中提取出来的水印信息
	pnDrawMark=new int[1000];
	
	//读取嵌入水印信息的位置全局变量——nMask
	ReadPoint(nNum);

	if( pDoc->m_nBitCount== 8 )
	{
		//图像数据变换中间变量分配空间
		pnI=new int[nPW*nPH];

		//获取包含水印信息的图像数据
		for( i = 0; i < lgSizePicture; i++ )	
			*( pnI + i) = ((int)*( pDoc->m_pbPic+i)-128);

		//水印图像作二维整数小波变换
		m_IntWT.IntWT_2D( pnI, nPH, nPW, 1, 4 );

		//读取标准水印
		ReadRandomMark(pnRandomMark,nNum);

		//提取水印信息
		for(i=0;i<nNum;i++)
		{
			//nF=(int)(dF[nMask[i][2]]*2.0+0.5);
			nF=(int)(dF[nMask[i][2]]+0.5);

			//if(abs(pnI[nMask[i][0]*512+nMask[i][1]]%nF)<(int)(dF[nMask[i][2]]/4.0))
			if((pnI[nMask[i][0]*512+nMask[i][1]]%nF)<(nF/4) && (pnI[nMask[i][0]*512+nMask[i][1]]%nF)>(-nF/4))
			{
				pnDrawMark[i]=0;
			}else
				pnDrawMark[i]=1;
		}

		//相似性检验		
		Test(pnRandomMark,pnDrawMark,nNum);
	}

	//存储提取水印图像
	FILE *fOutFile;

	fOutFile=fopen("d:\\DrawMask.txt","w+");
	
	fprintf(fOutFile,"%6d",nNum);
	for(i=0;i<nNum;i++)
	{		
		fprintf(fOutFile,"%3d",pnDrawMark[i]);
//		fprintf(fOutFile,"%6d",pnI[nMask[i][0]*512+nMask[i][1]]);
	}

	fclose(fOutFile);
	delete[] pnI;
	delete[] pnDrawMark;
	delete[] pnRandomMark;
	Invalidate();
}


void CMultiMarkView::OnAdapdtiveWaveletImage() 
{
	CMultiMarkDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	int *pn;
	int *pnI;

	int nPW=pDoc->m_nWidth;
	int nPH=pDoc->m_nHeight;
	long lgSizePicture;
	lgSizePicture=nPW*nPH;
	long i,j;
	BYTE *pb;
	pb=pDoc->m_Dib.m_lpImage;
	pn=pDoc->m_pnPic;
	int nLineWidth;
	int nNum=m_nMarkWidth*m_nMarkHeight;
	int nF,nW;

/*	CClientDC *pDC=new CClientDC(this);
	CPoint point;

	for(i=0;i<m_nMarkHeight;i++)
	{
		for(j=0;j<m_nMarkWidth;j++)
		{
			point.x=nPW+j;
			point.y=m_nMarkHeight+i;

			//pDC->SetPixel(point,RGB(pnDrawMark[i*m_nMarkWidth+j]*255,pnDrawMark[i*m_nMarkWidth+j]*255,pnDrawMark[i*m_nMarkWidth+j]*255));
			pDC->SetPixel(point,RGB(m_pbMark[3*i*m_nMarkWidth+3*j],m_pbMark[3*i*m_nMarkWidth+3*j],m_pbMark[3*i*m_nMarkWidth+3*j]));
			//pDC->SetPixel(point,RGB(0,0,0));
		}
	}*/

	if( pDoc->m_nBitCount== 8 )
	{
		nLineWidth=(nPW+3)/4*4;
		pnI=new int[nPW*nPH];

		for( i = 0; i < lgSizePicture; i++ )	
			*( pnI + i) = (*( pDoc->m_pnPic+i)-128);

		m_IntWT.IntWT_2D( pnI, nPH, nPW, 1, 4 );
		BlockValue(pnI);
		TreeSearch();

		//嵌入水印信息
		for(i=0;i<nNum;i++)
		{
			//nF=(int)(dF[nMask[i][2]]*2.0+0.5);
			nF=(int)(dF[nMask[i][2]]+0.5);
			if(m_pbMark[i*3]>128)
			{
				nW=1;
			}else
				nW=0;
			if(pnI[nMask[i][0]*512+nMask[i][1]]>=0)
			{
				pnI[nMask[i][0]*512+nMask[i][1]]=pnI[nMask[i][0]*512+nMask[i][1]]/nF*nF
					+(nW*(nF/2));
			}else if(pnI[nMask[i][0]*512+nMask[i][1]]<0)
			{
				pnI[nMask[i][0]*512+nMask[i][1]]=pnI[nMask[i][0]*512+nMask[i][1]]/nF*nF
					-(nW*(nF/2));
			}
		}
		m_IntWT.IntWT_2D_I(pnI, nPH, nPW, 1, 4);
	}

	for(i=0;i<nPH;i++)
	{
		for(j=0;j<nPW;j++)
		{
			pb[i*nLineWidth+j]=(BYTE)(pnI[i*nPW+j]+128);
			pDoc->m_pbPic[i*nPW+j]=(BYTE)(pnI[i*nPW+j]+128);
		}
	}
	delete[] pnI;
	Invalidate();
}

void CMultiMarkView::OnAdapdtiveWaveletImageDraw() 
{
	CMultiMarkDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);	
	int *pnI;

	int nPW=pDoc->m_nWidth;
	int nPH=pDoc->m_nHeight;
	long lgSizePicture;
	lgSizePicture=nPW*nPH;
	long i;

	int *pnDrawMark;
	int nNum=m_nMarkWidth*m_nMarkHeight;
	int nF;

	//pnDrawMark表示从图像中提取出来的水印信息
	pnDrawMark=new int[m_nMarkWidth*m_nMarkHeight];
	
	//读取嵌入水印信息的位置全局变量——nMask
	ReadPoint(nNum);

	if( pDoc->m_nBitCount== 8 )
	{
		//图像数据变换中间变量分配空间
		pnI=new int[nPW*nPH];

		//获取包含水印信息的图像数据
		for( i = 0; i < lgSizePicture; i++ )	
			*( pnI + i) = ((int)*( pDoc->m_pbPic+i)-128);

		//水印图像作二维整数小波变换
		m_IntWT.IntWT_2D( pnI, nPH, nPW, 1, 4 );

		//提取水印信息
		for(i=0;i<nNum;i++)
		{
			//nF=(int)(dF[nMask[i][2]]*2.0+0.5);
			nF=(int)(dF[nMask[i][2]]+0.5);

			if((pnI[nMask[i][0]*512+nMask[i][1]]%nF)<(nF/3) && (pnI[nMask[i][0]*512+nMask[i][1]]%nF)>(-nF/3))
			{
				pnDrawMark[i]=0;
			}else
				pnDrawMark[i]=1;
		}
	}

	int j;
	CClientDC *pDC=new CClientDC(this);
	CPoint point;

	for(i=0;i<m_nMarkHeight;i++)
	{
		for(j=0;j<m_nMarkWidth;j++)
		{
			point.x=nPW+j;
			point.y=2*m_nMarkHeight-i;

			pDC->SetPixel(point,RGB(pnDrawMark[i*m_nMarkWidth+j]*255,pnDrawMark[i*m_nMarkWidth+j]*255,pnDrawMark[i*m_nMarkWidth+j]*255));
		}
	}
	
	delete[] pnI;
	delete[] pnDrawMark;
//	Invalidate();
}

//多重水印嵌入策略
void CMultiMarkView::OnAdapdtiveWaveletImageM() 
{
	//嵌入水印重数
	int nTimes=3;
	int k;

	//获取当前文档工作区
	CMultiMarkDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	int *pn;
	int *pnI;

	//获取图像宽度和高度
	int nPW=pDoc->m_nWidth;
	int nPH=pDoc->m_nHeight;
	long lgSizePicture;
	lgSizePicture=nPW*nPH;
	
	long i,j;
	BYTE *pb;

	//获取当前显示区内图像的像素信息
	pb=pDoc->m_Dib.m_lpImage;
	pn=pDoc->m_pnPic;
	
	//图像数据行宽度
	int 

⌨️ 快捷键说明

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