信息隐藏实验3 DCT域水印算法
实验目的
一、熟悉变换域隐秘技术
二、使用DCT变换在图片中嵌入和提取文本水印
实验要求
一、要求能够利用C/C++、Matlab等高级编程语言编写基本的算法程序,并通过调试、运行程序。
二、上交实验报告
实验内容
实验3.1:使用LSB上的顺序嵌入算法,将秘密消息文本隐藏于载体图像中。
(1)用imread()函数读取一个宿主图像
(2)对该图像进行DCT变换,形成64像素的小块
(3)将水印信号嵌入DCT系数的中频部位
(4)进行DCT逆变换,得到嵌入水印后的图像
载体图片:lenna.jpg
实验3.2:提取实验3.1生成的隐蔽图像中上的秘密消息文本。
参考程序1
%;文件名:hidedctadv.m
%函数功能:本函数用于DCT域的信息隐藏
%输入格式举例:[count,msg,data]=hidedctadv('lenna.jpg','1.jpg','1.txt',1982,1);
%参数说明:
%image为载体图象
%imagegoal为藏有秘密信息的载体,即隐秘载体
%msg为待隐藏的信息
%key为密钥,用来控制随机选块
%alpha为控制量,用来保证编码的正确性
%count为待隐藏信息的长度
%result为隐藏结果
function [count,msg,result]=hidedctadv(image,imagegoal,msg,key,alpha)
%按位读取秘密信息
frr=fopen(msg,'r');
[msg,count]=fread(frr,'ubit1');
fclose(frr);
data0=imread(image);
%将图象矩阵转为double型
data0=double(data0)/255;
%取图象的一层做隐藏
data=data0(:,:,1);
%对图象分块
T=dctmtx(8);
%对分块图象做DCT变换
DCTrgb=blkproc(data,[8 8],'P1*x*P2',T,T');
DCTrgb0=DCTrgb;
%产生随机的块选择,确定图像块的首地址
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8);
a=zeros([row col]);
[k1,k2]=randinterval(a,count,key);
for i=1:count
k1(1,i)=(k1(1,i)-1)*8+1;
k2(1,i)=(k2(1,i)-1)*8+1;
end
%信息嵌入
temp=0;
for i=1:count
if msg(i,1)==0
if DCTrgb(k1(i)+4,k2(i)+1)>DCTrgb(k1(i)+3,k2(i)+2)
temp=DCTrgb(k1(i)+4,k2(i)+1);
DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+3,k2(i)+2);
DCTrgb(k1(i)+3,k2(i)+2)=temp;
end
else
if DCTrgb(k1(i)+4,k2(i)+1)
temp=DCTrgb(k1(i)+4,k2(i)+1);
DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+3,k2(i)+2);
DCTrgb(k1(i)+3,k2(i)+2)=temp;
end
end
if DCTrgb(k1(i)+4,k2(i)+1)>DCTrgb(k1(i)+3,k2(i)+2)
DCTrgb(k1(i)+3,k2(i)+2)=DCTrgb(k1(i)+3,k2(i)+2)-alpha;%将原本小的系数调整得更小
else
DCTrgb(k1(i)+4,k2(i)+1)=DCTrgb(k1(i)+4,k2(i)+1)-alpha;
end
end
%信息写回保存
DCTrgb1=DCTrgb;
data=blkproc(DCTrgb,[8 8],'P1*x*P2',T',T);
result=data0;
result(:,:,1)=data;
imwrite(result,imagegoal);
参考程序2
%文件名:extractdctadv.m
%函数功能:本函数用于DCT隐藏信息的提取
%输入格式举例:tt=extractdctadv('lennahide.jpg','2.txt',1982,40)
%参数说明:
%image为已经藏有信息的图象
%permission为图象格式
%msg为提取信息存放的位置
%key为密钥,用来控制随机选块
%count为信息的比特数,由藏入方给出
function result=extractdctadv(image,msg,key,count)
data0=imread(image);
data0=double(data0)/255;
%用图象第一层做提取
data=data0(:,:,1);
%分块做DCT变换
T=dctmtx(8);
DCTcheck=blkproc(data,[8 8],'P1*x*P2',T,T');
%产生随机的块选择,确定图像块的首地址
[row,col]=size(DCTcheck);
row=floor(row/8);
col=floor(col/8);
a=zeros([row col]);
[k1,k2]=randinterval(a,count,key);
for i=1:count
k1(1,i)=(k1(1,i)-1)*8+1;
k2(1,i)=(k2(1,i)-1)*8+1;
end
%准备提取并回写信息
frr=fopen(msg,'a');
for i=1:count
if DCTcheck(k1(i)+4,k2(i)+1)<=DCTcheck(k1(i)+3,k2(i)+2)
fwrite(frr,0,'bit1');
result(i,1)=0;
else
fwrite(frr,1,'bit1');
result(i,1)=1;
end
end
fclose(frr);
参考程序3
%文件名:randinterval.m
%函数功能:本函数将利用随机序列进行间隔控制,选择消息隐藏位.
%输入格式举例:[row,col]=randinterval(test,60,1983)
%参数说明:
%matrix为载体矩阵
%count为要嵌入的信息的数量(要选择的像素数量)
%key为密钥
%row为伪随机输出的像素行标
%col为伪随机输出的像素列标
function [row,col]=randinterval(matrix,count,key)
%计算间隔的位数
[m,n]=size(matrix);
interval1=floor(m*n/count)+1;
interval2=interval1-2;
if interval2<=0
error( '载体太小不能将秘密信息隐藏进去!' );
end
%生成随机序列
rand('seed',key);
a=rand(1,count);
%初始化
row=zeros([1 count]);
col=zeros([1 count]);
%计算row和col
r=1;
c=1;
row(1,1)=r;
col(1,1)=c;
for i=2:count
if a(i)>=0.5
c=c+interval1;
else
c=c+interval2;
end
if c>n
r=r+1;
if r>m
error( '载体太小不能将秘密信息隐藏进去!' );
end
c=mod(c,n);
if c==0
c=1;
end
end
row(1,i)=r;
col(1,i)=c;
end