密码学实验第八组实验报告Word文档下载推荐.docx
《密码学实验第八组实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《密码学实验第八组实验报告Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
二、实验内容
用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,'
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);
Ç
¶
È
ë
%
%Ë
®
Ó
¡
Ë
ã
·
¨
fori=1:
N
forj=1:
II=zeros(8,8);
%·
Ö
¿
é
fork=1:
8
forl=1:
II(k,l)=I(8*(i-1)+k,8*(j-1)+l);
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;
Bidct=idct2(Idct);
%Idct±
InsertImage(8*(i-1)+k,8*(j-1)+l)=Bidct(k,l);
end
256
InsertImage(i,j)=round(InsertImage(i,j));
subplot(2,2,2);
imshow(InsertImage);
º
¬
Ð
µ
Ä
Ì
á
imwrite(InsertImage,'
e.jpg'
'
quality'
100);
IV=imread('
a=0;
b=0;
IX=zeros(8,8);
IX(k,l)=IV(8*(i-1)+k,8*(j-1)+l);
Idct2=dct2(IX);
if(Idct(4,4)>
Idct2(4,4))
a=a+1;
b=b+1;
if(Idct(4,5)>
Idct2(4,5))
if(Idct(5,4)>
Idct2(5,4))
if(Idct(5,5)>
Idct2(5,5))
if(a>
b)
NewPrint(i,j)=0;
NewPrint(i,j)=255;
imwrite(NewPrint,'
f.jpg'
subplot(2,2,4);
imshow(NewPrint);
//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"
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<
wWidth;
i++){
for(intj=0;
j<
wHeight;
j++){
double[][]blk=newdouble[8][8];
//对原始图像8*8分块
for(intm=0;
m<
8;
m++){
for(intn=0;
n<
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恢复
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
//提取水印
//程序名:
m3_2b.java
//目的:
用于FDCT水印提取实验
//编写时间:
2008年10月13日
importjava.awt.image.*;
publicclassDistill{
Distilldistill=newDistill();
distill.start(32,32);
publicvoidstart(intwWidth,intwHeight){
Stringfnm="
;
Stringfnm1="
Picture\\d.jpg"
//mImage是嵌入水印后的图像
BufferedImagemImage=ImageAssistance.getImage(fnm,"
//原始图像
BufferedImageoImage=ImageAssistance.getImage(fnm1,"
WritableRastermRaster=mImage.getRaster();
int[]mPixels=newint[3*oWidth*oHeight];
mRaster.getPixels(0,0,oWidth,oHeight,mPixels);
//得rgb图像三层矩阵,mRgbPixels[0]表示b层分量
int[][][]mRgbPixels=ImageAssistance.getRGBArrayToMatrix(mPixels,
int[][][]oRgbPixels=ImageAssistance.getRGBArrayToMatrix(oPixels,
double[][]oDPixels=MathTool.intToDouble(mRgbPixels[2]);
double[][]mDPixels=MathTool.intToDouble(oRgbPixels[2]);
double[][]result=newdouble[wWidth][wHeight];
result[i][j]=0;
//提取水印算法
double[][]oBlk=newdouble[8][8];
double[][]mBlk=newdouble[8][8];
intd=0;
intf=0;
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]<
dMBlk[3][3]){
d++;
f++;
if(dOBlk[3][4]<
dMBlk[3][4]){
if(dOBlk[3][5]<
dMBlk[3][5]){
if(dOBlk[4][3]<
dMBlk[4][3]){
if(dOBlk[5][3]<
dMBlk[5][3]){
if(d>
=f){
result[i][j]=0;
result[i][j]=1;
int[]outResult=MathTool.matrixToArray(result);
BufferedImageoutImage=newBufferedImage(wWidth,wHeight,
BufferedImage.TYPE_3BYTE_BGR);
outRaster.setPixels(0,0,wWidth,wHeight,outResult);
Picture\\mark.jpg"
//将BufferedImage对象写入磁盘