基于LSB的图像数字水印实验
1. 实验类别
设计型实验:MATLAB设计并实现基于LSB的图像数字水印算法。
2. 实验目的
了解信息隐藏中最常用的LSB算法的特点,掌握LSB算法原理,设计并实现一种基于图像的LSB隐藏算法。
3. 实验条件
(1) Windows 2000或Windows Xp以上操作系统;
(2) MATLAB 6.5以上版本软件;
(3)图像文件
4. 实验原理
基于LSB的图像数字水印
任何多媒体信息在数字化时都会产生物理随机噪声,而人的感官系统对这些随机噪声并不敏感。替换技术就是利用这个原理,通过使用秘密信息比特替换随机噪声,从而实现信息隐藏目的。图像高位平面对图像感官质量起主要作用,去除图像最低几个位平面并不会造成画面质量的下降。利用这个原理可用秘密信息(或称水印信息)替代载体图像低位平面以实现信息嵌入。
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\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学习资料干货喔
1. 实验类别 设计型实验:MATLAB设计并实现基于DCT的图像数字水印算法. 2. 实验目的 了解基于DCT的图像数字水印技术,掌握基于DCT系数关系的图像水印算法原理,设计并实现一种基于DCT的 ... 简单介绍: 基于互信息的图像配准算法以其较高的配准精度和广泛的适用性而成为图像配准领域研究的热点之中的一个.而基于互信息的医学图像配准方法被觉得是最好的配准方法之中的一个.基于此.本文将介绍简单的基于 ... 基于clahe的图像去雾 通过阅读一些资料,我了解到clahe算法对图像去雾有所价值,正好opencv中有了实现,拿过来看一看. 但是现在实现的效果还是有所差异 #); clahe] ... 写在前面:一篇魏云超博士的综述论文,完整题目为<基于DCNN的图像语义分割综述>,在这里选择性摘抄和理解,以加深自己印象,同时达到对近年来图像语义分割历史学习和了解的目的,博古才能通今!感 ... 伴随着毕业论文的完成,这两天终于腾出了空闲,又有时间搞搞FFMPEG的研究了.想着之前一直搞的都是FFMPEG解码方面的工作,很少涉及到FFMPEG编码方面的东西,于是打算研究一下FFMPEG的编码. ... Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ... Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ... Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ... Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ... 题目: 第一题:二重循环: public class Text01 { //完成歌曲排序的效果 public static void main(String[] args) { String[] zi ... 一.JavaSript圆括号的使用 先来看一组通过函数声明来定义的函数: 先附代码: 运行结果如下: 这里我们可以看出: Ø 若没有加圆括号,则返回的是这个函数的内容 Ø 若加上圆括号,则返回的是 ... 主从数据库的复制原理:摘自MySQL官网 1. 异步 * 主在执行sql之后,记录二进制bin-log文件. * 同时从连接主服务器,并从主获取binlog,存于本地relay-log,并从上次记 ... 本篇是对springboot 使用webflux响应式开发教程(一)的进一步学习. 分三个部分: 数据库操作webservicewebsocket 创建项目,artifactId = trading- ... @(139 - Environment Settings | 环境配置) Git虽然极其强大,命令繁多,但常用的就那么十来个,掌握好这十几个常用命令,你已经可以得心应手地使用Git了. 友情附赠国外网 ... Mac安装Brew 安装命令如下:curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/loc ... API 一般用来暴露接口 项目分层一般是 api + entity + enums + model 就是接口加上一些实体之类的东西 1 准备 使用工具Procrun(http://commons.apache.org/proper/commons-daemon/procrun.html),下载地址(http://archive.a ... 碰撞检测关键步骤 碰撞检测需要处理经历下面两个关键的步骤: 计算判断两个物体是否发生碰撞 发生碰撞后,两个物体的状态和动画效果的处理 计算碰撞 只要两个物体相互接触,它们就会发生碰撞. 矩形物体碰撞检 ... boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intru ...基于LSB的图像数字水印实验的更多相关文章
随机推荐