设计型实验:MATLAB设计并实现基于LSB的图像数字水印算法。python
了解信息隐藏中最经常使用的LSB算法的特色,掌握LSB算法原理,设计并实现一种基于图像的LSB隐藏算法。算法
(1) Windows 2000或Windows Xp以上操做系统;函数
(2) MATLAB 6.5以上版本软件;学习
(3)图像文件ui
基于LSB的图像数字水印spa
任何多媒体信息在数字化时都会产生物理随机噪声,而人的感官系统对这些随机噪声并不敏感。替换技术就是利用这个原理,经过使用秘密信息比特替换随机噪声,从而实现信息隐藏目的。图像高位平面对图像感官质量起主要做用,去除图像最低几个位平面并不会形成画面质量的降低。利用这个原理可用秘密信息(或称水印信息)替代载体图像低位平面以实现信息嵌入。操作系统
LSB算法选用最低位平面来嵌入秘密信息,最低位平面对图像的视觉效果影响最轻微,但很容易受噪声影响和攻击,可采用冗余嵌入的方式来加强稳健性加以解决,即在一个区域中嵌入相同的信息,提取时根据该区域中的全部像素判断。设计
1.嵌入水印.m脚本代码:code
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嵌入水印后的图像');
运行截图:blog
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\LSB_watermark.txt','w'); % 以只写模式打开一个名为mark_message.txt的文件,不存在则建立之 fwrite(fobject,key,'bit1'); % 将key矩阵中的数做为bit写入文件句柄为fobject的文件 fclose(fobject); % 关闭文件句柄所对应的文件
运行后hidden.txt与LSB_watermark.txt文件水印内容
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群!
欢迎加入QQ群:735472015,群内有VC,MFC,win32API,批处理,python学习资料干货喔👌
若您以为对您有帮助,不妨点个赞👍呗!