密码学实验第八组实验报告.docx
《密码学实验第八组实验报告.docx》由会员分享,可在线阅读,更多相关《密码学实验第八组实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
![密码学实验第八组实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/1/444bdf64-270a-4aa8-a72c-32541fef85c2/444bdf64-270a-4aa8-a72c-32541fef85c21.gif)
密码学实验第八组实验报告
云南大学数学与与统计学院
上机实践报告
课程名称:
密码学实验
学期:
2013-2014学年第一学期
成绩:
指导教师:
陆正福
学生姓名:
卢富毓
学生学号:
20101910072
实验名称:
数字水印
实验要求:
必做
实验学时:
4学时
实验编号:
No.8
实验日期:
2013/12/15
完成日期:
2012/12/30
学院:
数学与统计学院
专业:
信息与计算科学
年级:
2010级
一、实验目的
熟悉并掌握数字水印的内容。
二、实验内容
用Matlab实现图像数字水印的离散余弦变换嵌入和提取。
三、实验环境
Win7,Matlab,Java&Eclipse
四、实验过程(请学生认真填写):
1.预备知识:
二维DCT变换原理:
M×N矩阵的二维离散余弦变换定义为:
其中,f(m,n)是M×N矩阵中坐标为(m,n)元素的原始值,
F(u,v)是经离散余弦变换后对应值。
对应的DCT逆变换定义为:
其中:
2.实验过程
A、原理分析:
水印嵌入思路:
(1)选用灰色图像lena.jpg作为宿主图像,选用二值图像c.jpg作为水印图像。
(2)提取原始图像lena的像素矩阵A和嵌入图像c的像素矩阵B;
(3)对像素矩阵A进行8*8分块,然后进行(快速)DCT变换;
(4)在进行DCT像素矩阵中的特定位置嵌入水印信息(如果B中对应位置是1则加一个系数d,否则减d)。
水印提取思路:
(1)获得原始图像的像素矩阵A和水印的嵌入图像的像素矩阵A*;
(2)对A和A*进行8*8分块,并进行(快速)DCT变换。
(3)比较进行DCT像素矩阵中嵌入水印的5个位置系数大小,如果A*对应位置上系数大则水印信息为1,相反为0。
B、实验结果:
可以看出,Matlab处理图像变换,造成图像的失真度很小,效果很好。
这个实验最开始我想用Java实现的,但在实验过程中遇到很多问题,虽然最后从理论上弄懂了,但是实现起来并不容易,最后完成了代码,却没有得到好的结果。
五、实验总结
1.遇到的问题、分析并的出方案(列出遇到的问题和解决办法):
遇到问题:
如何Java中将图像信息提取成为矩阵块,以及如何将像素矩阵还原成图像
分析并解决:
只是由于过于急于编写程序,对文献[1]中的细节部分没有仔细研究,只是对离散余弦变换这块阅读了一下,在编写代码过程中遇到一些Java调用包之类的问题,都查看文档跟参考文献尝试解决。
2.体会和收获。
由于准备考研的事情导致了这学期编写的实验质量不是很高。
由于对数字水印处理这方面没有花太多时间深究,阅读文献也并不全面,导致最后的Java实现有问题,没有得到较好的结果,但在这个过程中,通过阅读文献还是学到很多东西,比如学长讲的是灰色图像如何嵌入水印和提取水印,在学习过程中,我还了解到如何在彩色图像中进行水印的嵌入和提取。
六、参考文献
《应用密码学》林岱岳
《密码学概论》wadetrape
《JAVA实现图像处理》
七、教师评语:
八、代码
//Matlab代码
clc;
clear;
M=256;
N=32;
d=5;
NewPrint=zeros(N,N,'uint8');
InsertImage=zeros(M,M,'uint8');
D=zeros(M,M);
I=imread('d.jpg');
subplot(2,2,1);
imshow(I);
title('³õʼͼÏñ');
Origin=imread('c.jpg');
subplot(2,2,3);
imshow(Origin);
title('ǶÈëͼÏñ');
%
%ˮӡǶÈëËã·¨
%
fori=1:
N
forj=1:
N
II=zeros(8,8);%·Ö¿é
fork=1:
8
forl=1:
8
II(k,l)=I(8*(i-1)+k,8*(j-1)+l);
end
end
Idct=dct2(II);%Dct񄯯
if(Origin(i,j)==0)
Idct(4,4)=Idct(4,4)-d;
Idct(4,5)=Idct(4,5)-d;
Idct(4,6)=Idct(4,6)-d;
Idct(5,4)=Idct(5,4)-d;
Idct(5,5)=Idct(5,5)-d;
Idct(5,6)=Idct(5,6)-d;
else
Idct(4,4)=Idct(4,4)+d;
Idct(4,5)=Idct(4,5)+d;
Idct(4,6)=Idct(4,6)+d;
Idct(5,4)=Idct(5,4)+d;
Idct(5,5)=Idct(5,5)+d;
Idct(5,6)=Idct(5,6)+d;
end
Bidct=idct2(Idct);%Idct񄯯
fork=1:
8
forl=1:
8
InsertImage(8*(i-1)+k,8*(j-1)+l)=Bidct(k,l);
end
end
end
end
fori=1:
256
forj=1:
256
InsertImage(i,j)=round(InsertImage(i,j));
end
end
subplot(2,2,2);
imshow(InsertImage);
title('º¬ÓÐˮӡµÄͼÏñ');
%
%ˮӡÌáÈ¡
%
imwrite(InsertImage,'e.jpg','quality',100);
IV=imread('e.jpg');
fori=1:
N
forj=1:
N
a=0;
b=0;
II=zeros(8,8);
IX=zeros(8,8);
fork=1:
8
forl=1:
8
II(k,l)=I(8*(i-1)+k,8*(j-1)+l);
IX(k,l)=IV(8*(i-1)+k,8*(j-1)+l);
end
end
Idct=dct2(II);
Idct2=dct2(IX);
if(Idct(4,4)>Idct2(4,4))
a=a+1;
else
b=b+1;
end
if(Idct(4,5)>Idct2(4,5))
a=a+1;
else
b=b+1;
end
if(Idct(5,4)>Idct2(5,4))
a=a+1;
else
b=b+1;
end
if(Idct(5,5)>Idct2(5,5))
a=a+1;
else
b=b+1;
end
if(a>b)
NewPrint(i,j)=0;
else
NewPrint(i,j)=255;
end
end
end
imwrite(NewPrint,'f.jpg','quality',100);
subplot(2,2,4);
imshow(NewPrint);
title('ˮӡÌáÈ¡');
//Java代码
//嵌入水印
packageFDCT;
importjava.awt.image.BufferedImage;
importjava.awt.image.WritableRaster;
//FDCT水印嵌入
publicclassm3_2a{
privatestaticfinalintd=5;
publicstaticvoidmain(String[]args){
m3_2aembed=newm3_2a();
embed.start();
}
publicvoidstart(){
BufferedImageoImage=ImageAssistance.getImage("Picture\\a.jpg","jpeg");
BufferedImagewImage=ImageAssistance.getImage("Picture\\zhong.jpg","jpeg");
inttype=oImage.getType();
WritableRasteroRaster=oImage.getRaster();
WritableRasterwRaster=wImage.getRaster();
intoWidth=oRaster.getWidth();
intoHeight=oRaster.getHeight();
intwWidth=wRaster.getWidth();
intwHeight=wRaster.getHeight();
int[]oPixels=newint[3*oWidth*oHeight];
int[]wPixels=newint[3*wWidth*wHeight];
oRaster.getPixels(0,0,oWidth,oHeight,oPixels);
wRaster.getPixels(0,0,wWidth,wHeight,wPixels);
int[][][]RGBPixels=ImageAssistance.getRGBArrayToMatrix(oPixels,
oWidth,oHeight);
//得到RGB图像的三层矩阵表示
double[][]rPixels=MathTool.intToDouble(RGBPixels[1]);
int[][]wDMatrix=MathTool.arrayToMatrix(wPixels,wWidth,wHeight);
double[][]result=rPixels;
//嵌入算法
for(inti=0;ifor(intj=0;jdouble[][]blk=newdouble[8][8];
//对原始图像8*8分块
for(intm=0;m<8;m++){
for(intn=0;n<8;n++){
blk[m][n]=rPixels[8*i+m][8*j+n];
}
}
double[][]dBlk=FDct.fDctTransform(blk);
if(wDMatrix[i][j]==0){
dBlk[3][3]=dBlk[3][3]-d;
dBlk[3][4]=dBlk[3][4]-d;
dBlk[3][5]=dBlk[3][5]-d;
dBlk[4][3]=dBlk[4][3]-d;
dBlk[5][3]=dBlk[5][3]-d;
}else{
dBlk[3][3]=dBlk[3][3]+d;
dBlk[3][4]=dBlk[3][4]+d;
dBlk[3][5]=dBlk[3][5]+d;
dBlk[4][3]=dBlk[4][3]+d;
dBlk[5][3]=dBlk[5][3]+d;
}
blk=IFDct.iFDctTransform(dBlk);
//8block恢复
for(intm=0;m<8;m++){
for(intn=0;n<8;n++){
result[8*i+m][8*j+n]=blk[m][n];
}
}
}
}
double[][][]temp=newdouble[3][oWidth][oHeight];
temp[0]=MathTool.intToDouble(RGBPixels[0]);
temp[2]=MathTool.intToDouble(RGBPixels[2]);
temp[1]=result;
double[]rgbResult=ImageAssistance.getRGBMatrixToArray(temp);
//把嵌入水印的结果写到BufferedImage对象
BufferedImageoutImage=newBufferedImage(oWidth,oHeight,type);
WritableRasteroutRaster=outImage.getRaster();
//将像素写入到Raster
outRaster.setPixels(0,0,oWidth,oHeight,rgbResult);
//将BufferedImage对象写入磁盘
ImageAssistance.setImage(outImage,"Picture\\r.jpg","jpg");
}
}//end
//提取水印
packageFDCT;
//程序名:
m3_2b.java
//目的:
用于FDCT水印提取实验
//编写时间:
2008年10月13日
importjava.awt.image.*;
publicclassDistill{
publicstaticvoidmain(String[]args){
Distilldistill=newDistill();
distill.start(32,32);
}
publicvoidstart(intwWidth,intwHeight){
Stringfnm="Picture\\r.jpg";
Stringfnm1="Picture\\d.jpg";
//mImage是嵌入水印后的图像
BufferedImagemImage=ImageAssistance.getImage(fnm,"jpeg");
//原始图像
BufferedImageoImage=ImageAssistance.getImage(fnm1,"jpeg");
WritableRasteroRaster=oImage.getRaster();
WritableRastermRaster=mImage.getRaster();
intoWidth=oRaster.getWidth();
intoHeight=oRaster.getHeight();
int[]oPixels=newint[3*oWidth*oHeight];
int[]mPixels=newint[3*oWidth*oHeight];
oRaster.getPixels(0,0,oWidth,oHeight,oPixels);
mRaster.getPixels(0,0,oWidth,oHeight,mPixels);
//得rgb图像三层矩阵,mRgbPixels[0]表示b层分量
int[][][]mRgbPixels=ImageAssistance.getRGBArrayToMatrix(mPixels,
oWidth,oHeight);
int[][][]oRgbPixels=ImageAssistance.getRGBArrayToMatrix(oPixels,
oWidth,oHeight);
double[][]oDPixels=MathTool.intToDouble(mRgbPixels[2]);
double[][]mDPixels=MathTool.intToDouble(oRgbPixels[2]);
double[][]result=newdouble[wWidth][wHeight];
for(inti=0;ifor(intj=0;jresult[i][j]=0;
}
}
//提取水印算法
for(inti=0;ifor(intj=0;jdouble[][]oBlk=newdouble[8][8];
double[][]mBlk=newdouble[8][8];
intd=0;
intf=0;
for(intm=0;m<8;m++){
for(intn=0;n<8;n++){
oBlk[m][n]=oDPixels[8*i+m][8*j+n];
mBlk[m][n]=mDPixels[8*i+m][8*j+n];
}
}
double[][]dOBlk=FDct.fDctTransform(oBlk);
double[][]dMBlk=FDct.fDctTransform(mBlk);
if(dOBlk[3][3]d++;
}else{
f++;
}
if(dOBlk[3][4]d++;
}else{
f++;
}
if(dOBlk[3][5]d++;
}else{
f++;
}
if(dOBlk[4][3]d++;
}else{
f++;
}
if(dOBlk[5][3]d++;
}else{
f++;
}
if(d>=f){
result[i][j]=0;
}else{
result[i][j]=1;
}
}
}
int[]outResult=MathTool.matrixToArray(result);
//把嵌入水印的结果写到BufferedImage对象
BufferedImageoutImage=newBufferedImage(wWidth,wHeight,
BufferedImage.TYPE_3BYTE_BGR);
WritableRasteroutRaster=outImage.getRaster();
outRaster.setPixels(0,0,wWidth,wHeight,outResult);
ImageAssistance.setImage(outImage,"Picture\\mark.jpg","jpeg");//将BufferedImage对象写入磁盘
}
}//end