基于LSB的图像数字⽔印实验
1. 实验类别
设计型实验:MATLAB设计并实现基于LSB的图像数字⽔印算法。
2. 实验⽬的
了解信息隐藏中最常⽤的LSB算法的特点,掌握LSB算法原理,设计并实现⼀种基于图像的LSB隐藏算法。
条件
实验条件
3. 实验
(1) Windows 2000或Windows Xp以上操作系统;
(2) MATLAB 6.5以上版本软件;
(3)图像⽂件
4. 实验原理
基于LSB的图像数字⽔印
fopen绝对路径任何多媒体信息在数字化时都会产⽣物理随机噪声,⽽⼈的感官系统对这些随机噪声并不敏感。替换技术就是利⽤这个原理,通过使⽤秘密信息⽐特替换随机噪声,从⽽实现信息隐藏⽬的。图像⾼位平⾯对图像感官质量起主要作⽤,去除图像最低⼏个位平⾯并不会造成画⾯质量的下降。利⽤这个原理可⽤秘密信息(或称⽔印信息)替代载体图像低位平⾯以实现信息嵌⼊。
LSB算法选⽤最低位平⾯来嵌⼊秘密信息,最低位平⾯对图像的视觉效果影响最轻微,但很容易受噪声影响和攻击,可采⽤冗余嵌⼊的⽅式来增强稳健性加以解决,即在⼀个区域中嵌⼊相同的信息,提取时根据该区域中的所有像素判断。
1.嵌⼊⽔印.m脚本代码:
clear all;
clc;
picpath = input('请输⼊图⽚绝对路径(加单引号):');
watermark_path = input('请输⼊⽔印⽂件绝对路径(加单引号):');
msgfid = fopen(watermark_path,'r'); % 打开秘密⽂件,读⼊秘密信息
[key,count] = fread(msgfid,'ubit1'); % 读取秘密信息,存⼊key,count为成功读⼊了多少位
fclose(msgfid); % 关闭⽂件
i = imread(picpath);
i1 = i(:,:,1); % 提取RGB第1层嵌⼊⽔印
[row,col] = size(i1); % x⾏y列
contents = row * col; % 图像能嵌⼊⽔印最⼤⽐特数
if count > contents
disp('warning: 当前图⽚容量⽆法通过LSB⽅法嵌⼊所有⽔印信息!按enter退出matlab.');
pause;
quit;
else
disp(['当前图⽚通过LSB能嵌⼊的最⼤⽔印⽐特数为: ',num2str(contents),' bits']);
end
key_counter = 1;
round_counter = 0;
total_watermark_bits = 0;
if mod(count,row) == 0
round = floor(count/row);
else
round = floor(count/row) + 1;
end
for ii=1:1:round
for jj = 1:1:row
i1(jj,ii) = bitset(i1(jj,ii),1,key(key_counter,1));% bitset函数改变像素值最后⼀位bit为⽔印bit值
key_counter = key_counter + 1;
total_watermark_bits = total_watermark_bits + 1;
if key_counter > count
break;
end
end %内层for
round_counter = round_counter + 1;
disp(['当前嵌⼊轮数: ',num2str(round_counter)]);
if key_counter > count
disp(['LSB嵌⼊正常结束!共嵌⼊⽔印⽐特数: ',num2str(total_watermark_bits),' bits']);
break;
end
end %外层for
i(:,:,1) = i1;
imwrite(i,'E:\new\LSB_watermarked.bmp');
figure;
subplot(1,2,1);
imshow(picpath);
title('原始图像');
subplot(1,2,2);
imshow(i);
title('LSB嵌⼊⽔印后的图像');
运⾏截图:
2.提取⽔印.m脚本代码:
clear all;
clc;
picpath = input('请输⼊待提取LSB⽔印图⽚绝对路径(加单引号):');
watermark_bits = input('请输⼊提取的⽔印⽐特数:');
i = imread(picpath); % 读取含有⽔印信息的彩⾊图像
i1 = i(:,:,1);
key = zeros(watermark_bits,1); % 创建⼀个watermark_bits⾏1列的全0矩阵,⽤于存放⽔印⽐特[row,col] = size(i1);
key_counter = 1;
round = 0;
round_counter = 0;
total_watermark_bits = 0;
if mod(watermark_bits,row) == 0
round = floor(watermark_bits/row);
else
round = floor(watermark_bits/row) + 1;
end
for ii = 1:1:round
for jj = 1:1:row
key(key_counter,1) = bitget(i1(jj,ii),1); % 提取图像矩阵的bit⽔印信息
key_counter = key_counter + 1;
total_watermark_bits = total_watermark_bits + 1;
if key_counter > watermark_bits
break;
end
end %内层for
round_counter = round_counter + 1;
disp(['当前提取轮数: ',num2str(round_counter)]);
if key_counter > watermark_bits
disp(['LSB⽔印提取正常结束!共提取⽔印⽐特数:',num2str(total_watermark_bits),' bits']);
break;
end
end %外层for
fobject = fopen('E:\new\','w'); % 以只写模式打开⼀个名为的⽂件,不存在则创建之fwrite(fobject,key,'bit1'); % 将key矩阵中的数作为bit写⼊⽂件句柄为fobject的⽂件
fclose(fobject); % 关闭⽂件句柄所对应的⽂件
运⾏后与⽂件⽔印内容
LSB⽔印实验的要点
1.该实验选取的是彩⾊RGB图像,是3维图像,因此要选RGB中的某⼀层进⾏⽔印嵌⼊,可以选第1,2或3层,分别对于R,G,B层,本实验选择R层及第⼀层i1 = i(:,:,1)
2.还应对图像所能容纳⽔印⽐特最⼤数进⾏检查,以防⽔印信息太多导致嵌⼊失败.
3.嵌⼊完成后,要将选取的RGB层赋给原3维矩阵对应层i(:,:,1) = i1
4.代码注意if及for与end配对,⼀个if或for配⼀个end
上述脚本在matlab6.5能正确运⾏.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论