clc
clear all;
k=20;
blocksize=8; % 设置块的大小
% 读入原图像
file_name='_lena_std_bw.bmp';
cover_object=double(imread(file_name));
% 原图像的行数与列数
Mc=size(cover_object,1); %原图像行数
Nc=size(cover_object,2); %原图像列数
% 最大嵌入信息量
max_message=Mc*Nc/(blocksize^2);
% 读入水印图像
file_name='c.bmp';
message=double(imread(file_name));
%%水印图像的行数与列数
Mm=size(message,1); %水印行数
Nm=size(message,2); %水印列数
message_vector=reshape(message,1,Mm*Nm);
% 检查水印信息是否过大
if (Mm*Nm> max_message)
error('水印太大')
end
% 产生watermarked_image,并写入原图信息
watermarked_image=cover_object;
% 将图像分块嵌入
% 当 (2,2) > (2,3) 且 message_pad(kk)=0
% 当 (2,2) < (2,3) 且 message_pad(kk)=1
%%在提取水印时,如果cD1(2,2)>cD1(2,3)便是嵌入了水印的黑色像素,
%%反之则是嵌入了白色像素
x=1;
y=1;
h=waitbar(0,'嵌入水印,请等待');
for (kk = 1:length(message_vector))
% 对块进行DWT变换
[cA1,cH1,cV1,cD1] = dwt2(cover_object(x:x+blocksize-1,y:y+blocksize-1),'haar');
% 如果 message_pad(kk)== 0
if (message_vector(kk) == 0)
% 且(2,2) < (2,3) ,交换它们
if (cD1(2,2) < cD1(2,3))
temp=cD1(2,3);
cD1(2,3)=cD1(2,2);
cD1(2,2)=temp;
end
% 如果message_pad(kk) == 1,
elseif (message_vector(kk) == 1)
% 且(2,2) > (2,3) ,交换它们
if (cD1(2,2) >= cD1(2,3))
temp=cD1(2,3);
cD1(2,3)=cD1(2,2);
cD1(2,2)=temp;
end
end
% 检查(2,2) , (2,3)的差是否>= k
if cD1(2,2) > cD1(2,3)
if cD1(2,2) - cD1(2,3) < k
cD1(2,2)=cD1(2,2)+(k/2);
cD1(2,3)=cD1(2,3)-(k/2);
end
else
if cD1(2,3) - cD1(2,2) < k
cD1(2,3)=cD1(2,3)+(k/2);
cD1(2,2)=cD1(2,2)-(k/2);
end
end
%IDWT
watermarked_image(x:x+blocksize-1,y:y+blocksize-1)= idwt2(cA1,cH1,cV1,cD1,'haar',[Mc,Nc]);
% 移动到下一块
if (x+blocksize) >= Nc
x=1;
y=y+blocksize;
else
x=x+blocksize;
end
waitbar(kk/length(message_vector),h);
end
close(h);
% 转换为uint8并写入dwt_watermarked.bmp
watermarked_image_uint=uint8(watermarked_image);
imwrite(watermarked_image_uint,'dwt_watermarked.bmp','bmp');
% 计算psnr值
psnr=psnr(cover_object,watermarked_image),
% 显示图像
%figure(1)
%imshow(message,[]);
%title('水印');
figure(2)
subplot(1,2,1);
imshow(watermarked_image,[])
title('嵌入水印图像')
subplot(1,2,2);
imshow(cover_object,[]);
title('原图');
%提取源码
clear all;
blocksize=8; % 设置块的大小
% 读入嵌入水印图像
file_name='dwt_watermarked.bmp';
watermarked_image=double(imread(file_name));
% 嵌入水印图像的行数与列数
Mw=size(watermarked_image,1); %嵌入水印图像的行数
Nw=size(watermarked_image,2); %嵌入水印图像的列数
% 最大嵌入信息量
max_message=Mw*Nw/(blocksize^2);
% 读入原始水印
file_name='c.bmp';
orig_watermark=double(imread(file_name));
% 原始水印的行数与列数
Mo=size(orig_watermark,1); %原始水印的行数
No=size(orig_watermark,2); %原始水印的列数
% 将图像分块提取水印
x=1;
y=1;
h=waitbar(0,'水印提取中,请等待');
for (kk = 1:max_message)
% 对块进行dwt变换
[cA1,cH1,cV1,cD1] = dwt2(watermarked_image(x:x+blocksize-1,y:y+blocksize-1),'haar');
% 如果cD1(2,2) > cD1(3,3) 那么 message_vector(kk)=0
% 否则 message_vector(kk)=1
if cD1(2,2)>cD1(2,3)
message_vector(kk)=0;
else
message_vector(kk)=1;
end
% 移动到下一块
if (x+blocksize) >= Mw
x=1;
y=y+blocksize;
else
x=x+blocksize;
end
waitbar(kk/max_message,h);
end
close(h);
% 将message重新排列
message_vector=message_vector(1,1:Mo*No); %%只需前Mo*No个
message=reshape(message_vector,Mo,No);
%计算相关系数
NC=corr2(orig_watermark,message),
% 显示提取水印与原始水印
figure(3)
subplot(1,2,1);
imshow(message,[]);
title('提取水印')
subplot(1,2,2);
imshow(orig_watermark,[])
title('原始水印');
clear;
%pause;
f=imread('dwt_watermarked.bmp');
%将含水印图像f归一化,以便于攻击处理。
m=max(max(f));
f=double(f)./double(m);
%攻击实验
disp('输入你想攻击的方法:');
disp('0--JPEG 压缩');
disp('1--中值滤波');
disp('2--高斯低通滤波');
disp('3--直方图均衡化');
disp('4--图像增亮');
disp('5--图像变暗');
disp('6--增加对比度');
disp('7--降低对比度');
disp('8--添加高斯噪声');
disp('9--椒盐噪声');
disp('10--添加乘积性噪声');
attack=input('请输入你的选择:');
%while attack~=0
switch attack
%%0.JPEG 压缩
case 0,
imwrite(f,'attackf.jpg','jpg','quality',30);
attackf=imread('attackf.jpg');
attackf=double(attackf)/255;
att='JPEG压缩';
case 1,
%%1. 中值滤波
attackf=medfilt2(f,[2 2]);
att='中值滤波';
case 2,
%%2. 高斯低通滤波
h=fspecial('gaussian',3,1);
attackf=filter2(h,f);
att='高斯低通滤波';
case 3,
%%3. 直方图均衡化
attackf=histeq(f);
att='直方图均衡化';
case 4,
%%4. 图像增亮
attackf=imadjust(f,[],[0.4,1]);
att='图像增亮';
case 5,
%%5. 图像变暗
attackf=imadjust(f,[],[0,0.85]);
att='图像变暗';
case 6,
%%6. 增加对比度
attackf=imadjust(f,[0.3,0.6],[]);
att='增加对比度';
case 7,
%%7. 降低对比度
attackf=imadjust(f,[],[0.2,0.8]);
att='降低对比度';
case 8,
%%8. 添加高斯噪声
attackf=imnoise(f,'gaussian',0,0.002);
att='添加高斯噪声';
case 9,
%%9. 椒盐噪声
attackf=imnoise(f,'salt & pepper',0.008);
att='椒盐噪声';
case 10,
%%10. 添加乘积性噪声
attackf=imnoise(f,'speckle',0.008);
att='添加乘积性噪声';
end;
%---攻击后处理--------------------------------------------------------------
f=attackf*double(m);
figure(2);
imshow(uint8(f));%显示水印嵌入图攻击后效果
title(att);
imwrite(uint8(f),'attack.bmp');
clear all;
blocksize=8; % 设置块的大小
% 读入嵌入水印后的攻击图像
file_name='attack.bmp';
attack_image=double(imread(file_name));
% 被攻击图像的行数与列数
Mw=size(attack_image,1); %嵌入水印图像的行数
Nw=size(attack_image,2); %嵌入水印图像的列数
% 最大嵌入信息量
max_message=Mw*Nw/(blocksize^2);
% 读入原始水印
file_name='c.bmp';
orig_watermark=double(imread(file_name));
% 原始水印的行数与列数
Mo=size(orig_watermark,1); %原始水印的行数
No=size(orig_watermark,2); %原始水印的列数
% 将图像分块提取水印
x=1;
y=1;
h=waitbar(0,'水印提取中,请等待');
for (kk = 1:max_message)
% 对块进行dwt变换
[cA1,cH1,cV1,cD1] = dwt2(attack_image(x:x+blocksize-1,y:y+blocksize-1),'haar');
% 如果cD1(2,2) > cD1(3,3) 那么 message_vector(kk)=0
% 否则 message_vector(kk)=1
if cD1(2,2)>cD1(2,3)
message_vector(kk)=0;
else
message_vector(kk)=1;
end
% 移动到下一块
if (x+blocksize) >= Mw
x=1;
y=y+blocksize;
else
x=x+blocksize;
end
waitbar(kk/max_message,h);
end
close(h);
% 将message重新排列
message_vector=message_vector(1,1:Mo*No); %%只需前Mo*No个
message=reshape(message_vector,Mo,No);
%计算相关系数
NC=corr2(orig_watermark,message),
% 显示提取水印与原始水印
figure(3)
subplot(1,2,1);
imshow(message,[]);
title('攻击后提取水印')
subplot(1,2,2);
imshow(orig_watermark,[])
title('原始水印');