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学习资料干货喔

基于LSB的图像数字水印实验的更多相关文章

  1. 基于DCT的图片数字水印实验

    1. 实验类别 设计型实验:MATLAB设计并实现基于DCT的图像数字水印算法. 2. 实验目的 了解基于DCT的图像数字水印技术,掌握基于DCT系数关系的图像水印算法原理,设计并实现一种基于DCT的 ...

  2. 【图像配准】基于互信息的图像配准算法:MI、EMI、ECC算法

    简单介绍: 基于互信息的图像配准算法以其较高的配准精度和广泛的适用性而成为图像配准领域研究的热点之中的一个.而基于互信息的医学图像配准方法被觉得是最好的配准方法之中的一个.基于此.本文将介绍简单的基于 ...

  3. 基于clahe的图像去雾

    基于clahe的图像去雾     通过阅读一些资料,我了解到clahe算法对图像去雾有所价值,正好opencv中有了实现,拿过来看一看.   但是现在实现的效果还是有所差异 #);    clahe] ...

  4. 笔记:基于DCNN的图像语义分割综述

    写在前面:一篇魏云超博士的综述论文,完整题目为<基于DCNN的图像语义分割综述>,在这里选择性摘抄和理解,以加深自己印象,同时达到对近年来图像语义分割历史学习和了解的目的,博古才能通今!感 ...

  5. 最简单的基于FFMPEG的图像编码器(YUV编码为JPEG)

    伴随着毕业论文的完成,这两天终于腾出了空闲,又有时间搞搞FFMPEG的研究了.想着之前一直搞的都是FFMPEG解码方面的工作,很少涉及到FFMPEG编码方面的东西,于是打算研究一下FFMPEG的编码. ...

  6. Java基于opencv实现图像数字识别(五)—投影法分割字符

    Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...

  7. Java基于opencv实现图像数字识别(四)—图像降噪

    Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...

  8. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  9. Java基于opencv实现图像数字识别(二)—基本流程

    Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...

随机推荐

  1. mysqlcppconn之ConnectOptionsMap的使用

    由来 继上一篇文章, 发现之前写的一篇文章中断线重连部分是错误的, 也是现在翻阅了源码才知道 想要自动重连, 必须使用ConnectOptionsMap才可以 但由于官方代码没有做好导出部分的处理, ...

  2. “云中论道”之——使用开源技术和Azure公有云服务快速搭建云端IoT解决方案(上)

    “云中论道”技术课堂第一课开讲啦!微软各路技术咖们齐聚一堂,为大家带来干货不断!作为“云中论道“课堂的开课之作,我们首先邀请到了微软Azure专家级的架构师:槐长清,他为我们带来了关于“使用开源技术和 ...

  3. javascript 获取文档/屏幕的Width||Height

    document.body.clientWidth //网页可见区域宽度document.body.clientHeight //网页可见区域高度document.body.offsetWidth / ...

  4. QA-IDEA中用maven配置项目无法加载JDBC

    java.lang.ClassNotFoundException: com.mysql.jdbc.Driver Im building Maven Java Web application and w ...

  5. (转)从信息隐藏的一个需求看C++接口与实现的分离

    原文地址https://blog.csdn.net/tonywearme/article/details/6926649 让我们从stackoverflow上一个同学的问题来开始.问题的原型是这样的( ...

  6. oracle 日期常用函數sysdate

    SYSDATE   2 --◎ 可得到目前系統的時間     3           4   ex.      5     select sysdate from dual;   6          ...

  7. CentOS查看线程、硬盘、内存、cpu、网卡

    1.查看硬盘 [mushme@investide ~]$ df -ah 2.查看内存 [mushme@investide ~]$ free -m 3.监控系统的负载 w    查看当前系统的负载,详细 ...

  8. git及github配置入门

    github是一个有海量开源代码库的网站,同时也是一个软件开发管理软件,作为软件来说它集成了git这个分布式的版本控制系统,可以上传.下载和管理自己的代码. 笔者刚接触不久,把认为入门应该知道的东西稍 ...

  9. luogu P1462 通往奥格瑞玛的道路

    嘟嘟嘟 这道题的题面相当的迷,我看了半天都没懂.最后看了题解的解释才懂. 他是这么个意思:对于所有能活着走到终点的路径,输出每一条路径中过路费最多的城市的最小值. 那么自然想到二分过路费,然后用dij ...

  10. [19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)

    一.RandomAccessFile 随机访问流 [版本1] /* *RandomAccessFile 所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件 * 实现文件的拆分与合并 模拟下载 ...