1.实验目的
(1)了解频域水印的特点
(2)掌握基于DCT系数关系的图像水印算法原理
2.实验内容(二选一)
(1)DCT域的图像水印嵌入与提取
(2)完全脆弱图像水印实验
3.实验原理
(1)DCT域的图像水印嵌入与提取
在信号的频域(变换域)中隐藏信息要比在时域中嵌入信息具有更好的鲁棒性。一副图像经过时域到频域的变换后,可将待隐藏信息藏入图像的显著区域,这种方法比 LSB 以及其他一些时域水印算法更具抗攻击能力,而且还保持了对人类感官的不可察觉性。常用的变换域方法有离散余弦变换(DCT)、离散小波变换(DWT)和离散傅里叶变换(DFT)等。
本章介绍一种提取秘密信息的时候不需要原始图像的盲水印算法,算法的思想是利用载体中两个特定DCT 系数的相对大小来表示隐藏的信息。载体图像分为 8×8 分块,进行二维 DCT 变换,分别选择其中的两个位置,比如用(u1,v1)和(u2,v2)代表所选定的两个系数的坐标。如果 Bi(u1,v1) < Bi(u2,v2),代表隐藏 1,如果相反,则交换两系数,如果 Bi(u1,v1) > Bi(u2,v2),代表隐藏 0,如果相反,则交换两系数。提取的时候接收者对包含水印的图像文件进行二维 DCT 变换,比较每一块中约定位置的 DCT 系数值,根据其相对大小,得到隐藏信息的比特串,从而恢复出秘密信息。但是在使用上述算法的过程中,一般都是引入一个 Alpha 变量对系数的差值进行控制,将两个系数的差别方法,可以保证提取秘密信息的正确性。
(2)完全脆弱图像水印实验
在保证多媒体信息一定感知质量的前提下,将数字、序列号、文字、图像标志等作为数字水印嵌入到多媒体数据中,当多媒体内容受到怀疑时,可将该水印提取出来用于多媒体内容的真伪识别,并指出篡改位置,甚至攻击类型等。这种水印称为脆弱性水印,脆弱性水印分为完全脆弱性水印和半脆弱性水印。当原始载体内容发生改变时,被嵌入的水印信息就遭到了破坏,因此图像的接收方就不能完整的提取水印信息。从而可以鉴定原始数据是否被篡改。完全脆弱水印主要用于完整性保护,图像不能发生任何修改,图像如果发生一个比特的修改都会影响水印信息的提取。而半脆弱水印对一般图像处理(如:滤波、加噪声、替换、压缩等)有较强的免疫能力(鲁棒性),但是能检测到对图像的恶意篡改,一般用于内容保护。
完全脆弱水印系统要求图像的任何部分均不能被修改,检测器对图像任何细微的变动都会做出拒绝判决。完全脆弱水印一般是从空域 LSB 水印算法演变过来,其中最具有代表性的是校验和(checksum)算法、公钥认证水印算法和查找表水印算法。
本节介绍的算法的原理如下:校验和算法首先计算每个像素字节最高 7 位的 checksum 值,checksum 值定义为一系列相同长度数据的二进制位的模 2 和。在该算法中,此长度为 8 个连续像素中的最高 7 位的联合长度,共 56 位。在 checksum 值计算过程中,整幅图像中的每个像素都参与计算,但每个像素只计算一次,最后结果为 56 位的数据。该算法随后在图像中随机选取 56 个像素,将每个像素的最低位变为与上述checksum 比特位相同,以此存储 checksum 值,从而完成水印的嵌入。图像认证时,只需要将被检图像的checksum 值与提取的水印信息进行比较,便可得知图像是否被篡改。
在这个算法中,随机选取的存访 checksum 值的像素位置以及 checksum 值本身构成了水印信息。在提取水印时,只需计算图像的 checksum 值并与水印信息中的 checksum 值进行比较,便可知水印是否因遭受篡改而被破坏。
4.实验记录
(1)完全脆弱图像水印实验
1)Checksum水印嵌入
cuiruoshuiyin.m源代码:(自定义一个函数)
function [row,col]=cuiruoshuiyin(omatrix,count,key) %定义一个函数
[m,n]=size(omatrix);
distance1=ceil(m*n/count); %朝正无穷的方向取整数
distance2=distance1-2;
if distance2==0
error('载体太小');
end
rand('state',key);
a=rand(1,count);
row=zeros([1 count]);
col=zeros([1 count]);
r=1;
c=1;
row(1,1)=r;
col(1,1)=c;
for i=2:count
if a(i)>=0.5
c=c+distance1;
else
c=c+distance2;
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
checksum.m源代码:(嵌入水印)
clc;
clear;
oi=imread('dream.png');
[orow,ocol]=size(oi);
pixelcount=orow*ocol; %计算总像素个数
count=floor(pixelcount/8); %将总像素分为8个一组
wi=oi(:);
for i=1:count %用于存放56bit
for j=1:56
l(i,j)=uint8(0);
end
end
k=1;
i=1;
for i=1:count
wherestart=8*(i-1);
for j=1:8
b(i,j)=wi(wherestart+j);
end
end
%把每个像素值的高7位取出,顺序为2,3,4,5,6,7,8
modcount=1;
for i=1:count
for j=1:8
for k=1:7
l(i,7*(j-1)+k)=bitget(b(i,j),k+1); %由低位到高位输出,取第k+1位
modcount=modcount+1;
end
end
end
%把所有的56位的值按照模2加的到一个56位长度的checksum值
for i=1:count-1
for j=1:56
sum(1,j)=xor(l(i,j),l(i+1,j));
end
end
%从图像中随机选取56个像素点
key=123; %用户选取随机嵌入的位置
sum=uint8(sum);
[row col] = cuiruoshuiyin(oi,56,key);
for k=1:56
bitset(oi(row(k),col(k)),1,sum(1,k));
end
imwrite(oi,'watermarke.png','png');
figure; %显示原图和添加水印信息后的图
subplot(1,2,1); %显示的位置
imshow('dream.png'); %显示的图像
title('原始图像'); %图像的标题
subplot(1,2,2);
imshow('watermarke.png');
title('添加水印信息后的图像');

图1-1 完全脆弱水印嵌入前后对比
2)判断图像是否被修改
extractwatermark.m源代码:
clc;
clear;
oi=imread('dream.png');
[orow ocol]=size(oi);
pixelcount=orow*ocol; %计算总像素个数
count=floor(pixelcount/8); %总像素分为8个一组
wi=oi(:);
for i=1:count %用于存放56比特
for j=1:56
l(i,j)=uint8(0);
end
end
k=1;
i=1;
for i=1:count
wherestart=8*(i-1);
for j=1:8
b(i,j)=wi(wherestart+j);
end
end
%把每个像素值的高7位取出,顺序为2、3、4、5、6、7、8
modcount=1;
for i=1:count
for j=1:8
for k=1:7
l(i,7*(j-1)+k)=bitget(b(i,j),k+1);
modcount=modcount+1;
end
end
end
%把所有的56位的值按照模2加的到一个56位长度的checksum值
for i=1:count-1
for j=1:56
sum(1,j)=xor(l(i,j),l(i+1,j));
end
end
%从图像中随机选取56个像素点
key=123; %用户选取随机嵌入的位置
for k=1:56
watermark(1,k)=0;
end
[row col]=cuiruoshuiyin(oi,56,key);
for k=1:56
watermark(1,k)=bitget(oi(row(k),col(k)),1);
end
for k=1:56
diff(1,k)=sum(1,k)-watermark(1,k);
end
for k=1:56
if diff(1,k)~=0
modified=1;
else
modified=0;
end
end

图2-1 运行结果
3)判断图像是否被篡改
modpic.m源代码:
clc;
clear;
oi=imread('watermarke.png'); %读入图像
[orow ocol]=size(oi);
pixelcount=orow*ocol; %计算总像素个数
count=floor(pixelcount/8); %总像素分为8个一组
for i=1:10
for j=1:10
oi(i,j)=0;
end
end
imwrite(oi,'watermarke.png','png'); %画出图像
figure;
subplot(1,2,1);
imshow('dream.png');
title('原始图像');
subplot(1,2,2);
imshow('watermarke.png');
title('被篡改的图像');

图3-1 原始图像与被篡改图像的对比