// STDM.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "file.h"
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
#define PI 3.1415926
int _tmain(int argc, _TCHAR* argv[])
{
file dct;
//嵌入
dct.filer1(); //打开LENA.BMP
dct.filer2(); //打开tj-logo.bmp
dct.STDM(); //DCT变换并嵌入
//解码
dct.filer2(); //打开tj-logo.bmp
dct.filer3(); //打开嵌入水印的lenalogo.bmp
dct.inSTDM(); //解码
/* int ch;
do
{
cout<<"嵌入or解码?\n嵌入——1\t解码——2\t退出——0\n";
cin>>ch;
switch (ch)
{
case 1:
{
dct.filer1(); //打开LENA.BMP
dct.filer2(); //打开tj-logo.bmp
dct.STDM(); //DCT变换并嵌入
break;
}
case 2:
{
dct.filer1(); //打开LENA.BMP
dct.filer2(); //打开tj-logo.bmp
dct.filer3(); //打开嵌入水印的lenalogo.bmp
dct.inSTDM(); //解码并统计错误率
break;
}
default:break;
}
} while (ch!=0);
cout<<"ByeBye!"<<endl;*/
return 0;
}
void file::filer1() //导入LENA图
{
FILE *fp;
if ((fp=fopen("LENA.bmp","r b"))==NULL)
{
cout<<"can't open this file!\n";
}
fread(&head,1,1078,fp);
fread(&color,1,262144,fp);
for(int i=0;i<512;i++)
for (int j=0;j<512;j++)
lena[i][j]=int(color[i][j])-128;
fclose(fp);
}
void file::filer2() //导入tj-logo图
{
FILE *fp;
if ((fp=fopen("LOGO.bmp","r b"))==NULL)
{
cout<<"can't open this file!\n";
}
fread(&head1,1,62,fp);
fread(&color1,1,512,fp);
int m;
double po; //以下为将32*4的数组转化为32*32的数组程序
for(int i=0;i<64;i++)
{
for (int j=0;j<64;j++)
{
logo[i][j]=0;
m=j/8;
po=pow(2.0,7-j%8);
logo[i][j]=color1[i][m]/po;
if (color1[i][m]>=po)
color1[i][m]=color1[i][m]-po;
if (logo[i][j]==0)
{
logo[i][j]=-1;
}
// cout<<logo[i][j]<<" ";
}
// cout<<endl;
}
fclose(fp);
}
void file::filer3() //导入lenalogo图
{
FILE *fp;
if ((fp=fopen("lenalogo.bmp","r b"))==NULL)
{
cout<<"can't open this file!\n";
}
fread(&head,1,1078,fp);
fread(&color,1,262144,fp);
for(int i=0;i<512;i++)
for (int j=0;j<512;j++)
lena[i][j]=int(color[i][j])-128;
fclose(fp);
}
void file::setT() //设置T和T'
{
for (int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
if (i==0)
{
T[i][j]=1/sqrt(8*1.0);
}
else
{
T[i][j]=cos(PI*i*(1+2*j)/2/8)/sqrt(8/2.0);
}
T1[j][i]=T[i][j];
}
}
void file::Matrix(double a[8][8],double b[8][8],double c[8][8],double d[8][8]) //矩阵乘法
{
double temp[8][8];
for(int i=0;i<8;i++)
{
for (int j=0;j<8;j++)
{
temp[i][j]=0.0;
for (int k=0;k<8;k++)
temp[i][j]+=a[i][k]*b[k][j];
}
}
for(int i=0;i<8;i++)
{
for (int j=0;j<8;j++)
{
d[i][j]=0.0;
for (int k=0;k<8;k++)
d[i][j]+=temp[i][k]*c[k][j];
}
}
}
void file::STDM() //DCT变换及嵌入
{
double dtemp[8][8],X[8][8],Y[8][8];
int q1,q0;
float d1,d0;
d1=deta/8.0;
d0=-deta/8.0;
setT();
for(int a=0;a<64;a++)
for(int b=0;b<64;b++)
{
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
dtemp[i][j]=lena[8*b+i][8*a+j];
Matrix(T,dtemp,T1,X);
float sum=0;
for (int d=0;d<8;d++)
{
sum+=X[d][7-d]*w[d];
}
sum=sum/8;
q0=deta*gauss((sum-d0)/deta+0.5)+d0;
q1=deta*gauss((sum+d1)/deta+0.5)+d1;
if (logo[a][b]==-1)
{
s=q0-sum;
}
else
{
s=q1-sum;
}
for(int c=0;c<8;c++) //嵌入
{
X[c][7-c]=X[c][7-c]+s*w[c];
}
Matrix(T1,X,T,Y);
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
lena[8*b+i][8*a+j]=Y[i][j];
}
FILE *fp;
if ((fp=fopen("lenalogo.bmp","w b"))==NULL)
{
cout<<"can't open this file!\n";
}
for(int i=0;i<512;i++)
for (int j=0;j<512;j++)
{
if (lena[i][j]>127)
{
lena[i][j]=127;
}
else if (lena[i][j]<-128)
{
lena[i][j]=-128;
}
color[i][j]=lena[i][j]+128;
}
fwrite(&head,1,1078,fp);
fwrite(&color,1,262144,fp);
fclose(fp);
}
void file::inSTDM() //DCT变换及解码
{
double dtemp[8][8],X[8][8];
float temp1,temp2;
setT();
for(int i=0;i<32;i++) //inlogo和colort初始化
{
for(int j=0;j<32;j++)
{
inlogo[i][j]=0;
}
}
float d1,d0;
d1=deta/8.0;
d0=-deta/8.0;
for(int a=0;a<64;a++)
{
for(int b=0;b<64;b++)
{
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
dtemp[i][j]=lena[8*b+i][8*a+j]; //将大矩阵分解
Matrix(T,dtemp,T1,X);
float temp=0.0;
for(int c=0;c<8;c++)
{
temp+=X[c][7-c]*w[c];
}
temp=temp/8;
temp1=deta*gauss((temp-d0)/deta+0.5)+d0-temp;
temp2=deta*gauss((temp-d1)/deta+0.5)+d1-temp;
if (abs(temp1)<abs(temp2))
inlogo[a][b]=0;
else
inlogo[a][b]=1;
}
}
sta();
int m;
double po; //以下为将64*64的数组转化为64*8的数组程序
for(int i=0;i<64;i++)
{
for (int j=0;j<64;j++)
{
m=j/8;
po=pow(2.0,7-j%8);
color1[i][m]+=inlogo[i][j]*po;
}
}
FILE *fp;
if ((fp=fopen("tjlogo.bmp","w b"))==NULL)
{
cout<<"can't open this file!\n";
}
fwrite(&head1,1,62,fp);
fwrite(&color1,1,512,fp);
fclose(fp);
}
int file::gauss(float a)
{
if (a<0)
{
return int(a)-1;
}
else
{
return int(a);
}
}
void file::sta()
{
double count,fa;
fa=count=0.0;
for(int i=0;i<64;i++)
for(int j=0;j<64;j++)
{
if(logo[i][j]==1 && inlogo[i][j]==0)
count++;
else if(logo[i][j]==-1 && inlogo[i][j]==1)
count++;
}
fa=count/64/64;
cout<<"解码的错误率是:"<<fa<<endl;
}
STDM水印嵌入及其解码
![star](https://csdnimg.cn/release/downloadcmsfe/public/img/star.98a08eaa.png)
![avatar](https://profile-avatar.csdnimg.cn/f01e81aba34545aa89edf77858cb1dcb_nishiwodidi.jpg!1)
MichaelJ_九歌
- 粉丝: 1
- 资源: 6
最新资源
- 基于C#和NET MAUI开发的音乐播放器+源代码+文档说明+sln.zip
- 基于python+flask+mysql实现的豆瓣电影可视化系统+源代码+文档说明+数据库sql.zip
- 程氏舞曲V4.2程氏舞曲V4.2程氏舞曲V4.2程氏舞曲V4.2
- FPGA读写 AD9708+ AD9280 ADDA实验Verilog逻辑源码Quartus工程文件+文档说明+硬件参考原理图
- 基于CH340C设计USB转TLL串口通信模块PADS 9.5设计硬件(原理图+PCB)文件.zip
- 信号与系统大作业-图像处理 实现了直接滤波法维纳滤波法最小二乘滤波法LR递归法matlab源码.zip
- php-leetcode题解之最小栈.zip
- php-leetcode题解之最长不含重复字符的子字符串.zip
- php-leetcode题解之最长公共前缀.zip
- php-leetcode题解之最小差值.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)