% 读入载体图像文件
file_name='1.bmp';
f=imread(file_name);
subplot(221);
imshow(f)
title('原图');
f=double(f);
% 读入载体文件的大小
Mc=size(f,1); %高度
Nc=size(f,2); %宽度
% 读入数字水印图像文件
file_name='2.bmp';
m=imread(file_name);
subplot(222);
imshow(m)
title('原水印');
m=double(m);
Mm=size(m,1); %水印图像的高度
Nm=size(m,2); %水印图像的宽度
%将水印图像转换为二值图像
m1=double(m);
m=fix(m1./12);
m=uint8(m);
%一层haar小波变换
[A1,H1,V1,D1] = dwt2(f,'haar');
[r1,c1]=size(A1);
r2=r1/2;
c2=c1/2;
% 嵌入水印
for i= 1:r1
for j= 1:c1
w(i,j)=m(mod(i,Mm)+1,mod(j,Nm)+1);
end
end
for i=1:r2
for j=1:c2
if w(i,j)==1
if H1(i,(2*j-1))<H1(i,2*j)
temp=H1(i,(2*j-1));
H1(i,(2*j-1))=H1(i,2*j);
H1(i,2*j)=temp;
end
if H1(i,(2*j-1))==H1(i,2*j)
H1(i,(2*j))=H1(i,(2*j))-0.0001;
end
end
if w(i,j)==0
if H1(i,(2*j-1))>H1(i,2*j)
temp=H1(i,2*j-1);
H1(i,(2*j-1))=H1(i,2*j);
H1(i,2*j)=temp;
end
if H1(i,(2*j-1))==H1(i,2*j)
H1(i,(2*j))=H1(i,(2*j))+0.0001;
end
end
end
end
% 实现小波的反变换
f=idwt2(A1,H1,V1,D1,'haar',[Mc,Nc]);
subplot(223)
imshow(uint8(f));
title('嵌入水印后的图');
% 读取该图像的高度和宽度
Mw=size(f,1); %高度
Nw=size(f,2); %宽度
%一层harr小波变换
[A1,H1,V1,D1] = dwt2(f,'haar');
[r1,c1] = size(A1);
r2=r1/2;
c2=c1/2;
%提取水印
for i=1:r2
for j=1:c2
if H1(i,2*j-1)>=H1(i,2*j)
k(i,j)=1;
else
k(i,j)=0;
end
end
end
subplot(224)
imshow(k);
title('提取的水印')
效果:
原理:嵌入算法
首先将256×256分辨率的256级载体灰度图像进行一层小波变换,如下:[A1,H1,V1,D1] = dwt2(f,‘haar’)得到A1,H1,V1,D1这样四个128×128大小的矩阵。其中f是256×256大小的矩阵,保存着分辨率为256×256、灰度级别为256的载体灰度图像,A1、H1、V1、D1分别是lena图像的低频逼近子图、水平方向细节子图、垂直方向细节子图、对角线方向的高频细节子图。接着,读入水印图像,将水印图像转换为二值图像,要求水印图像的大小为载体图像的八分之一。将水印图像的信息存入一个二维数组中。
最后,嵌入水印。如果将水印嵌入低频系数A1中,水印的鲁棒性好,但水印的隐蔽性差;如果将水印嵌入高频系数D1中,水印的隐蔽性好,但水印的鲁棒性差。同时考虑到水印的鲁棒性和隐蔽性,将这两种方案折中一下,本算法将水印嵌入到小波变换的水平方向细节的中频系数H1中。H1是一个二维数组,将H1的数据分为像素对,比较每对像素值的大小,前者大于后者表示1,前者小于后者表示0,若二者相等,则将其中一个的值做微小调整,使得每一像素对的大小关系和水印二值图像的每一位相对应。对不能对应的像素对,将像素对前后的位置互换。
水印提取算法
首先读入带有水印的载体图像,将该图像进行一层小波分解:
[A1,H1,V1,D1]=dwt2(f,‘haar’)
其中f是256×256大小的矩阵,保存着分辨率为256×256、灰度级别为256的嵌入了水印图像的载体灰度图像。
接着,从H1中提取水印,提取水印是嵌入水印的逆过程,将H1分为像素对,比较每对像素值的大小,如果前者大于后者,提取1,如果前者小于后者,提取0。