之前写过一篇介绍空间域LSB的数字水印算法,有需要的朋友可以看看
数字水印入门篇——空间域LSB的数字水印(附matlab代码)
因空间域的数字水印是通过直接在图像上改变像素的方式来隐藏水印信息的,所以对于大部分的攻击都没有较好的鲁棒性,在经过攻击后,无法提取出水印信息。因此,为了提高水印的鲁棒性,更倾向于使用频域的数字水印。
数字水印算法常用的频域变换包括DCT(离散余弦变换)、DWT(小波变换)、DFT(傅里叶变换),以及一些引申的其他变换,如FWT(快速小波变换),Contourlet变换等等,所用的变换不同,但算法的逻辑思路是相通的。
这里单独介绍一下基于DWT-SVD的数字水印算法。
小波变换的基本定义,实现原理这里不作过多介绍,感兴趣可以搜搜其他博主写过的介绍,这里简单介绍一下在数字水印算法中涉及到的内容。
1.图像经过小波分解,会分解得到四个频带:LL(低频部分),LH(高频部分的水平方向),HL(高频部分的垂直方向),HH(高频部分的对角线方向);
2.低频包含了图像的主要内容,与原始图像非常相似,而高频部分可以认为是图像冗余的噪声部分;
3.得到的四个频带的大小相同均为原图大小的四分之一。
利用函数dwt2()可以实现图像小波分解,具体实现如下:
I=imread('lena.png');
I=rgb2gray(I);
[LL,LH,HL,HH]=dwt2(I,'haar');
figure,
subplot(221);imshow(uint8(LL));title('低频');
subplot(222);imshow(LH);title('高频水平');
subplot(223);imshow(HL);title('高频垂直');
subplot(224);imshow(HH);title('高频对角线');
通常将水印嵌入到载体图像的低频分量上,能够提高水印的鲁棒性,后面的例子也是将水印嵌在低频分量。
SVD通常用来提取图像的特征值,实现降维、图像压缩。在数字水印技术中,也可以用来提高水印的鲁棒性,具体可参考刘瑞祯、谭铁牛的这篇论文《基于奇异值分解的数字图像水印方法》
1.图像经过SVD分解会得到三个矩阵,左奇异矩阵U,奇异值矩阵S和右奇异矩阵V;
2.奇异值矩阵为奇异值由大到小排列的对角矩阵;
通常将水印奇异值分解后的奇异值矩阵S加到载体图像上实现水印的嵌入
%% 水印嵌入
I=imread('lena.png'); %载入载体图像
I=im2double(I);
I=rgb2gray(I); %转为灰度图
[LL,LH,HL,HH]=dwt2(I,'haar'); %载体图像dwt变换
[U,S,V]=svd(LL); %低频分量SVD分解
W=imread('digital.png'); %载入水印图像
W=im2double(W);
W=rgb2gray(W); %转为灰度图
[Uw,Sw,Vw]=svd(W); %水印图SVD分解
af=0.2; %嵌入量
S2=S+af*Sw; %水印图的奇异值矩阵Sw以af嵌入量加到载体图像LL子代的奇异值矩阵S上
LL2=U*S2*V'; %嵌入后新的低频分量
IW=idwt2(LL2,LH,HL,HH,'haar'); %dwt逆变换得到含水印图
imwrite(IW,'watermarked.png');
figure,
subplot(221);imshow(I);title('载体图像');
subplot(222);imshow(W);title('水印图像');
subplot(223);imshow(IW);title('含水印图');
%% 水印提取
J=imread('watermarked.png'); %读取含水印图
J=im2double(J);
[LL3,LH3,HL3,HH3]=dwt2(J,'haar'); %含水印图dwt变换
[U3,S3,V3]=svd(LL3); %低频分量SVD分解
S4=(S3-S)/af; %得到提取水印图的奇异值矩阵
W2=Uw*S4*Vw'; %SVD逆变换得到提取水印图
subplot(224);imshow(W2);title('提取水印图');
这里的例子是最简单基础的DWT-SVD数字水印算法,还可以尝试对载体图像进行分块,水印图像进行加密或置乱等操作来增加水印算法的安全性。
以上就是基于DWT-SVD数字水印算法的简单介绍和代码实现。
如果觉得本篇文章有帮到您,希望可以点赞支持,本人还在学习当中,若有错误和问题,欢迎大家给我留言呀~