密码学实验第八组实验报告.docx
- 文档编号:8917430
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:15
- 大小:86.47KB
密码学实验第八组实验报告.docx
《密码学实验第八组实验报告.docx》由会员分享,可在线阅读,更多相关《密码学实验第八组实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
密码学实验第八组实验报告
云南大学数学与与统计学院
上机实践报告
课程名称:
密码学实验
学期:
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;i for(intj=0;j double[][]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;i for(intj=0;j result[i][j]=0; } } //提取水印算法 for(inti=0;i for(intj=0;j double[][]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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 密码学 实验 第八 报告