数字水印入门篇——空间域LSB的数字水印(附matlab代码)

空间域LSB的数字水印

根据数字水印技术作用域的不同,数字水印技术可以分为空间域水印技术和变换域水印技术。空间域技术都是使用各种方法直接改变图像的像素,直接将水印信息加载在数据上,属于早期的数字水印研究,典型的几种空域水印算法包括:最低有效位方法(LSB)、Patchwork方法、文档结构微调方法等。我们今天来详细介绍一下作为空间域水印的基础LSB方法的数字水印。

LSB方法的原理

在敲代码之前,我们先解释一下LSB方法的原理,了解了原理会更好的理解每一步代码。LSB全称为Least Significant Bit,解释为“最低有效位”,什么是最低有效位?我们知道,像素是数字图像的基本元素,图像是由像素构成的,而每个像素又是由多比特的方式构成的,在灰度图像中,每个像素通常为8位,在RGB图像中,每个像素为24比特(R,G,B三色各8位)每一位的取值为0或1。

对于8位的灰度图像,我们可以把图像分为8个位平面,从LSB(最低有效位0)到MSB(最高有效位7)。从位平面的分布来看,随着位平面从低位到高位(即从位平面0到位平面7),位平面图像的特征逐渐变得复杂,细节不断增加,比较低的位平面包含的图像信息很少,所以,改变低位对图像的质量影响不大。LSB方法就是利用了这一点,在图像的低位隐藏水印信息。

从原理上我们就能看出这种方法简单,计算量小,隐藏量大,但很明显,鲁棒性很差,攻击者只需通过简单的操作删除图像低位数据或者对数字图像进行某种简单数学变换就可将水印信息滤除或破坏掉,因此以LSB方法为原型,产生了很多变形的LSB方法。

LSB数字水印源代码(matlab)

嵌入部分:

%将水印图像按最不重要位(LSB)方法嵌入到载体图像中,并计算PSNR
clc
clear all;
close all;

% 读入载体图像
file_name='lena.bmp';
cover_object=imread(file_name);
cover_object=rgb2gray(cover_object);
figure(1);subplot(1,2,1);
imshow(cover_object,[]);
title('原始图像');
% 读入水印图像
file_name='64.bmp';
message=imread(file_name);
message=double(message);
message=round(message/256);
message=uint8(message);
% 确定载体图像的大小
Mc=size(cover_object,1);
Nc=size(cover_object,2);
% 确定水印图像的大小
Mm=size(message,1);
Nm=size(message,2);
% 将水印扩展为原图像大小,并写入watermark
for ii = 1:Mc
    for jj = 1:Nc
        watermark(ii,jj)=message(mod(ii, Mm)+1,mod(jj, Nm)+1);
    end
end
% 将原图的最低有效位值换为水印的值
watermarked_image=cover_object;
for ii = 1:Mc
   for jj = 1:Nc
       watermarked_image(ii, jj)=bitset(watermarked_image(ii, jj), 1, watermark(ii ,jj));
   end 
end
imwrite(watermarked_image,'lsb_watermarked.bmp','bmp');

% 显示已嵌入水印的图像 
figure(1);subplot(1,2,2);
imshow(watermarked_image,[]);
title('嵌入水印后图像');

% 计算已嵌入水印图像的PSNR
psnr=PSNR(cover_object, watermarked_image),

提取部分:

%将水印从载体图像中提取出来,并计算误比特率

clc
clear all;
close all;

%水印图像提取
file_name='lsb_watermarked.bmp';
watermarked_image=imread(file_name);
Mw =size(watermarked_image,1);
Nw =size(watermarked_image,2);

%读入原始水印
file_name='64.bmp';
orig_watermark=imread(file_name);
figure(1);subplot(1,2,1);
imshow(orig_watermark,[]);
title('原水印图');

message_pad=double(orig_watermark);
message_pad=round(message_pad./256);
message_pad=uint8(message_pad);


%%原始水印的行数与列数
Mm=size(orig_watermark,1);	        %水印的行数
Nm=size(orig_watermark,2);	        %水印的列数

% 用嵌入水印图像的最低有效位重建水印
for ii = 1:Mw
   for jj = 1:Nw
       watermark(ii, jj)=bitget(watermarked_image(ii, jj),1);
   end
end
watermark=256*double(watermark);

%将提取水印变为原始水印大小
for ii = 1:Mm-1
    for jj = 1:Nm-1
        watermark1(ii+1,jj+1)=watermark(ii,jj);
    end
end
watermark1(1,1)=watermark(Mm,Nm);
%显示提取的水印图像
figure(1);subplot(1,2,2);
imshow(watermark1,[]);
title('提取出的水印图');

message_pad_recover=double(watermark1);
message_pad_recover=round(message_pad_recover./256);
message_pad_recover=uint8(message_pad_recover);
message_pad_recover=reshape(message_pad_recover,[1,64*64]);

% 显示提取错误比特的比例

len=length(message_pad);
bit_error_rate=sum(abs(message_pad_recover(1:len)-message_pad(1:len)))/len,

附上代码运行效果:
在这里插入图片描述
在这里插入图片描述
本人还在学习阶段,若有错误欢迎大家指正

  • 19
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值