MATLAB实现的彩色数字水印算法

算法思想来自《彩色数字水印技术研究》一文

数字水印技术就是将特定的信息嵌入到数字信息的内容中,以保护所有者的权益。一个有效的数字水印应至少满足下面三个特性:不可觉察性:水印的存在不应明显干扰被保护的数据;安全性:水印的存在应该是安全的、可靠的,水印图像必须唯一标志原始图像的相关信息,任何第三者都不能伪造他人的水印图像;鲁棒性:给定一个水印文档,非授权的个人或团体在使文档可用的情况下无法剔除水印。可能看出水印的鲁棒性和不可觉察性是相互矛盾。对于一个特定的水印算法,必须折衷考虑这两个属性。

用的数字水印算法包含两个基本方面:水印的嵌入和水印的提取或检测。水印可由多种模型构成,如随机数字序列、数字标识、文本以及图像等。从鲁棒性和安全性考虑,常常要对水印进行随机化以及加密处理。

水印的嵌入过程:设有算法E,原始图像I和水印 W~,那么水印图像可表示如下:

数字水印的一般原理也可应用于彩色水印的嵌入和提取。但由于彩色水印含有比较多的信息,它比起一般水印信息来又有自己的特点。有文献利用静态图像的压缩编码技术,基于原始图像的DCT系数之间的关系,将彩色数字水印编码为一系列二值ID数字序列,直接作为掩码信息实现水印的嵌入。虽然水印的提取不需要原始图像,但水印只能抵抗JPEG有损压缩操作,对其它的图像操作的抵抗性很弱。基于这种情况,这篇文章提出了一种基于小波变换(DWT)的双彩色图印方案。实验证明,此方案不仅能抵抗JPEG有损压缩,还能抵抗剪切、放缩和平滑等操作。

彩色水印图像的详细嵌入过程如图3所示。基本步骤如下:

具体实践上有几点细节:

1.水印图像由[0 255]归一化到[-1 1],这应该是为了达到零均值,实际叠加时会乘以一个系数,文章认为α=4是不可察觉性和鲁棒性的一个很好的平衡

2.小波变换在YUV空间进行,文章说这是因为YUV是符合人视觉系统的一套颜色空间,而本人试了一下其他的色彩空间,确实YUV是效果最好的

3.加入水印分量是尽量往大的中频系数上加,大的系数意味着较强的能量,加一个小的扰动不会在视觉上变化太明显。

提取水印图像则是加水印的逆过程,基本步骤如图4所示

下面是MATLAB上的实现,与文章所述有一些变化:

1.只使用了二级小波变换,而不是四级,鲁棒性会有所下降,但水印尺寸得以提升

2.文章认为应向中频系数上添加水印,但低频分量能量和抗干扰性能比中频更强,所以优先向低频分量添加水印,如果低频分量系数个数不够再向中频分量添加

3.颜色空间使用的是YCbCr,跟YUV没有本质区别

function [Imgout] = Hide_3(OriImg,Print) 
%  功能   将Print中的携带的信息通过图像处理技术隐藏在OriImg中 
% OriImg  输入参数,RGB彩色图像,uint8格式,大小为512*512*3,作为隐
% 藏信息的载体 
% Print   输入参数,RGB彩色图像,uint8格式,大小为140*200*3,信息本
% 身所在 
% MarkedImg  输出参数,RGB彩色图像,uint8格式,大小为512*512*3,经过
% 信息隐藏处理后的图像 

OriImg = rgb2ycbcr(OriImg);

MarkedImg = zeros(size(OriImg));

alpha = 4;
for i=1:3
    Orilayer = OriImg(:,:,i);
    Printlayer = Print(:,:,i);
    Print_ori = Printlayer;
    Printlayer = (double(Printlayer)-128)/128;  %归一到-1~1
    
    [C,S] = wavedec2(Orilayer,2,'db2');
    [rows, cols] = size(Printlayer);
    totallength = rows*cols;
    cA2 = appcoef2(C,S,'db2',2);
    cH2 = detcoef2('h',C,S,2);
    [cA2_r, cA2_c] = size(cA2);
    [cH2_r, cH2_c] = size(cH2);
    part1length = cA2_r*cA2_c;
    part2length = cH2_r*cH2_c;
    flattenpri = reshape(Printlayer, 1, []);
    C(1:part1length) = C(1:part1length)+alpha*flattenpri(1:part1length);
    leftlength = totallength-part1length;
    
    cH2 = C(part1length+1:part1length+part2length);
    [~, IH] = sort(abs(cH2),'descend');
    IH = IH(1:leftlength);
    cH2(IH) = cH2(IH)+alpha*flattenpri(part1length+1:totallength);
    C(part1length+1:part1length+part2length) = cH2;
    
    Outlayer = waverec2(C,S,'db2');
    MarkedImg(:,:,i) = uint8(Outlayer);
end

Imgout = ycbcr2rgb(uint8(MarkedImg));

end

function Print = Recover_3(MarkedImg, OriImg) 

%  功能   将含有隐藏信息的图像MarkedImg中的信息标记(图像)分离到
%Print图像之中 
% MarkedImg  输入参数,RGB彩色图像,uint8格式,大小为512*512*3,可能
%含有隐藏信息的图像 
% OriImg  输入参数,RGB彩色图像,uint8格式,大小为512*512*3,不含隐
%藏信息的原始图像载体 
% Print   输出参数,RGB彩色图像,uint8格式,大小为140*200*3,信息本
%身所在 


rec_row = 140; %此处为水印图片的高度和宽度
rec_col = 200;


OriImg = rgb2ycbcr(OriImg);

MarkedImg = rgb2ycbcr(MarkedImg);

outImg = zeros(rec_row, rec_col, 3);
alpha = 4;
for i=1:3
    Orilayer = OriImg(:,:,i);
    Marklayer = MarkedImg(:,:,i);
    [Co,So] = wavedec2(Orilayer,2,'db2');
    coA2 = appcoef2(Co,So,'db2',2);
    [cA2_r, cA2_c] = size(coA2);
    part1length = cA2_r*cA2_c;
    coA2 = Co(1:part1length);
    coH2 = detcoef2('h',Co,So,2);
    [cH2_r, cH2_c] = size(coH2);
    part2length = cH2_r*cH2_c;
    coH2 = Co(part1length+1:part1length+part2length);
    [~, IHo] = sort(abs(coH2),'descend');
    %IHo = 1:length(IHo);
    leftlength = rec_row*rec_col-part1length;
    IHo = IHo(1:leftlength);
    
    [Cm,Sm] = wavedec2(Marklayer,2,'db2');
    cmA2 = Cm(1:part1length);
    cmH2 = Cm(part1length+1:part1length+part2length);
    
    flat_print = zeros(1,rec_row*rec_col);
    flat_print(1:part1length) = cmA2-coA2;
    flat_print(part1length+1:rec_row*rec_col) = cmH2(IHo)-coH2(IHo);

    
    Print = reshape(flat_print, rec_row, rec_col)/alpha;
    Print = (Print*128)+128;
    outImg(:,:,i) = Print;
end

Print = uint8(outImg);
end
    

实验效果

原图

水印

加水印后

恢复结果

对加水印图进行JPEG压缩攻击后的恢复结果

进行白色条形污损后的恢复结果

应该说,效果还是不错的

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值