数字图像水印

数字图像水印

数字图像水印简介

数字水印,是指将特定的信息嵌入数字讯号中,数字讯号可能是音频、图片或是影片等,但不影响原载体的使用价值。且若要拷贝嵌入数字水印的讯号,所嵌入的信息也会被一并被拷贝。一般来说,数字图像水印可分为浮现式和隐藏式两种,前者通常包含版权拥有者的名称或标志,例如微信公众号图片下方的水印。而隐藏式的水印是以人眼不可以见的形式将信息添加到图像中。隐藏式水印的一大重要应用就是数字版权的保护,通过添加数字水印的方式来避免未经许可的拷贝,乃至对于盗版内容的追踪。

而通过数字水印技术,我们可以在原图像中嵌入含有版权信息的数字水印,当发生版权冲突时,可以通过检测争议图像中的数字水印来判断归属,从而起到保护知识产权的作用。

根据数字水印的应用场景,其应具有以下几个特点:

  • 鲁棒性

    数字水印应该在经历有意或无意的操作后,仍保持完整或部分特征,使其能够被检测。

  • 隐蔽性

    数字水印应该对用户来说是不可见的,且水印的嵌入不应影响图像的可用性降低。

  • 安全性

    数字水印应该是难以伪造和篡改的。

  • 水印容量

    嵌入的水印信息必须足够多,且能够完整标识该图像的创建者或所有者的身份信息。

对于网络上常见的可见水印来说,其破坏了图像原本的特征,且鲁棒性差,不能抵抗剪切攻击。非法分子只需将图像裁剪即可盗取图像。所以,在数字资产版权保护的实际应用中,我们会更多的采用隐藏式的数字水印,常见的隐藏式水印算法有 LSB(最低有效位),QIM(量化索引调制),以及以 DCT 为主的变换域算法等。

数字图像水印发展历史

数字水印技术是从信息隐藏技术发展而来的,是数字信号处理,图像处理,密码学应用,算法设计等学科的交叉领域。相较于其他的数字图像技术,数字图像水印的发展历史并没有那么久远。虽然嵌入数字信息的实践最早可追溯到 1954 年 Muzak 公司为带有水印的音乐申请的一项专利,但直到 1993 年,A.Z.Tirkel 等人在Electronic Watermark[1]中,才第一次提出数字水印(watermark)的概念及可能的应用,并针对灰度图像提出了两种向图像最低有效位中嵌入水印的算法。1996 年在英国剑桥牛顿研究所召开了第一届国际信息隐藏学术研讨会,标志着信息隐藏学的诞生。[部分摘自百度百科]

数字水印的几个主要步骤

对于数字水印来说,主要会有嵌入、攻击、检测这样三个阶段。

嵌入

要嵌入原图像的有效信息就是数字水印本身,通过各类不同的嵌入算法,我们可以得到包含数字水印的图像,即对图像进行了保护。

常用的嵌入方法主要有以下两类:

  • 加法准则:

    Zwi=Zi+αWiZw_i = Z_i + \alpha W_i

  • 乘法准则:

    Zwi=Zi(1+αWi)Zw_i = Z_i(1+\alpha W_i)

其中Z={Zi}Z=\{Z_i\}代表原始图像,W={Wi}W=\{W_i\}代表需要嵌入的水印图像,Zw={Zwi}Zw=\{Zw_i\}为嵌入水印后的图像。

这里α\alpha表示水印的嵌入强度,由不同的嵌入算法,α\alpha取值也会不同,且α\alpha越大,水印的鲁棒性越好,但不可见性越差,因此需要根据不同的情况选择合适的嵌入强度。

攻击

对于一份包含数字水印的图像来说,其很有可能作为拷贝再分发出去。在这一分发过程中,该图像会经历无意或有意的裁剪、压缩、旋转、甚至噪声等。这一系列有可能影响数字水印检测效果的操作,都可以视作对数字水印的攻击。

常见的攻击有以下形式:

  1. 几何攻击

    即对水印图像进行裁剪、旋转等几何操作修改原图像,改变了图像像素值与坐标之间的对应关系,严重破坏了数据的同步性,从而使得水印的检测很难实现。几何攻击是对水印威胁最严重的攻击方式,会造成图像信息的大量丢失,甚至彻底破坏水印。

  2. 噪声攻击

    图像在传播过程中,最常见的影响就是噪声干扰,例如高斯噪声或椒盐噪声。一些脆弱的水印往往会在加入噪声后浮现。水印系统所能承受的最大限度噪声干扰也是水印鲁棒性的一个重要体现。

  3. 压缩攻击

    在常见的实际场景中,我们所使用的往往是压缩格式的图像,例如 JPEG。而这些有损图像压缩算法,也会破坏图像信息,使得水印无法被正常检测。

  4. 多重水印攻击

    不同于前几种无意攻击,多重水印攻击更多的是一种有意攻击。通过向一个已包含数字水印的图像中再次嵌入另一层水印,企图通过叠加的水印来混淆原有的水印信息,最终破坏原有水印信息。

检测

检测是一种从可能遭受到攻击的图像中提取数字水印的算法。如果图像未遭受到攻击,检测算法应该能完整提取出所嵌入的数字水印;且对于足够强大的数字水印来说,即使遭受了各种攻击,也应能从中提取出正确的水印。

一般来说,据提取水印时是否需要原始图像,可将提取算法归类为盲提取算法和非盲提取算法。在实际应用中,盲提取算法更具有实用性。

常见的数字水印算法

根据数字水印的隐藏位置,主要有空间域数字水印和频率域数字水印:

最低有效位算法(LSB)

由比特平面分层,我们可知不同位数据的表现力是不同的,且人眼对应较低位数据的微小变化很难感知,因此我们可将水印信息写入这些“无关紧要”的低位数据中。

clear
I = imread('Fig0314(a)(100-dollars).tif');
figure
subplot(3,3,1)
imshow(I)
title('原始图像')
for n=1:8
    % 位与操作
    tmp = bitand(I, 2^(n-1));
    In = tmp;
    % 二值化
    In(tmp == 2^(n-1)) = 255;
    In(tmp ~= 2^(n-1)) = 0;
    subplot(3, 3, n+1)
    imshow(In)
    title(['第', num2str(n), '比特平面'])
end

比特平面分层

嵌入低位比特平面效果对比:

嵌入低位比特平面

LSB 算法就是将原始图像的二进制最低有效位和水印信息的数据进行位异或运算,即如果相同,则原始图像对应位的值不变;如果不同,则将原始图像的最低有效位的值换为水印信息的数据。

LSB 算法简单,易于实现,但也有着以下的缺点:

  1. 为满足水印的不可见性,只能嵌入强度较低的水印
  2. 鲁棒性差,尤其是对应空域攻击
  3. 安全性差,仅需对最低比特平面进行编辑即可修改水印信息

基于 DCT 的变换域算法

由离散余弦变换(DCT)我们可将原始图像变换到 DCT 变换域,然后选取 DCT 变换域上的一部分参数值,在选取的参数值上嵌入数字水印信息,最终以离散余弦反变换(IDCT)得到嵌入水印后的图像。

水印嵌入流程:

DCT变换域水印嵌入流程

水印提取流程:

DCT变换域水印提取流程

水印效果示例:

DCT变换域水印示例

相比于空间域算法,频率域算法往往更不易被人眼感知,就基于 DCT 的变换域算法而言,其具有以下优点:

  1. 能有效抵抗压缩攻击。因为现有的国际压缩标准是基于 DCT 的变换,所有不会破坏 DCT 变换后嵌入的水印信息,以实现对压缩图像的水印嵌入。
  2. 由于是在变换域中嵌入的水印信息,可以使得水印信号最终分散到空的所有图像上,有利于保证水印的不可见性。

利用 SVD 分解的 DCT 变换域数字水印算法实现

水印嵌入

SVD-DCT水印嵌入流程

首先,对原始图像做 8×8 的分块 DCT 变换,且对每一分块进行 SVD 分解,得到对应特征向量Si=diagσ1,σ2σ8S_i=diag{σ_1,σ_2…σ_8}

随机生成行置换向量kik_i和列置换向量kjk_j,对水印图像进行置换得加密后水印序列kW=W1,W2Wnk_W={W_1,W_2…W_n} ;将水印信息WiW_i嵌入特征向量SiS_i中:Si=Si(1+αWi)S_i'=S_i ⋅(1+αW_i),其中α\alpha为水印强度。

然后对分块进行 SVD 逆运算以及 DCT 反变换,得到添加水印后的图片,如下图:

SVD-DCT水印图像比较

水印提取

SVD-DCT水印提取流程

分别对原图像和带有水印的图像做分块 DCT 变换,且对每一分块做 SVD 分解,得到所对应的特征向量 S 和 S1,以 S1-S<1 的逻辑值生成水印序列;加载嵌入水印时所使用的置换向量,并计算其反置换向量 di 和 dj,将水印序列转换为相应点阵,即嵌入的水印图片。

SVD-DCT水印图像提取

水印鲁棒性测试
  1. 涂抹攻击

    涂抹攻击

  2. 1/4 裁剪攻击

    裁剪攻击

  3. 中值滤波攻击

    中值滤波攻击

  4. 缩放攻击

    缩放攻击

  5. JPEG 压缩攻击

    JPEG压缩攻击

代码
% 嵌入水印
clear
% 原始图像
I = imread('bridge.bmp');
% 水印图像
W = imread('water.tif');
% 计算图像尺寸
sImage = size(I);
sWater = size(W);
wImage = sImage(1);
hImage = sImage(2);
num = 8;
% 水印强度
alpha = 0.05;
% 随机置换向量
k_i = randperm(sWater(1));
k_j = randperm(sWater(2));
% 保存置换向量作为密钥
save key.mat k_i k_j
% 加密水印图像
k_W = W(k_i,k_j);
% 对原始图像进行分块处理
M = wImage / num;
N = hImage / num;
B = mat2cell(I, num*ones(1, M), num*ones(1, N));
% 嵌入水印后的元组
T = cell(M, N);
for i=1:M
    for j=1:N
        % DCT变换
        c = dct2(B{i,j});
        % SVD分解
        [u,s,v] = svd(c);
        % 从加密后的水印序列中获取信息
        if k_W(i,j) == 0
            tmp = -1;
        else
            tmp = 1;
        end
        % 嵌入水印
        s1 = s * double((1+alpha*tmp));
        % SVD逆运算
        a = u*s1*v';
        % DCT反变换
        T(i, j) = { idct2(a) };
    end
end
% 将分块元组合并为图像矩阵
I1 = cell2mat(T);
% 显示图像
subplot(1,3,1)
imshow(I, [])
title('原始图像')
subplot(1,3,2)
imshow(uint8(I1))
title('添加水印后的图像')
subplot(1,3,3)
imshow(double(I) - I1, [])
title('两图像之间的差')
% 保存嵌入水印后的图像
imwrite(uint8(I1), 'result.bmp', 'bmp')
% 提取水印
clear
% 原始图像
I  = imread('bridge.bmp');
% 嵌入水印后的图像
I1 = imread('result.bmp');
% 计算图像尺寸
sImage = size(I);
wImage = sImage(1);
hImage = sImage(2);
num = 8;
M = wImage / num;
N = hImage / num;
% 将图像分块
B  = mat2cell(I , num*ones(1, M), num*ones(1, N));
B1 = mat2cell(I1, num*ones(1, M), num*ones(1, N));
% 提取的水印序列
W = zeros(M, N);
for i=1:M
    for j=1:N
        % DCT变换
        c  = dct2(B{i,j});
        c1 = dct2(B1{i,j});
        % SVD分解
        [u,s,v] = svd(c);
        [~,s1,~] = svd(c1);
        % 提取水印
        w = s1-s;
        if w < 1
            W(i,j) = 0;
        else
            W(i,j) = 1;
        end
    end
end
% 加载密钥,即置换向量
load key.mat k_i k_j
% 计算反置换向量
d_i = zeros(size(k_i));
for i=1:length(k_i)
    d_i(k_i(i)) = i;
end
d_j = zeros(size(k_j));
for j=1:length(k_j)
    d_j(k_j(j)) = j;
end
% 还原水印图像
d_W = W(d_i, d_j);
% 显示图像
figure
subplot(1,3,1)
imshow(I)
title('原始图像')
subplot(1,3,2)
imshow(I1, [])
title('嵌入水印的图像')
subplot(1,3,3)
imshow(d_W, [])
title('提取的水印')

参考资料

  1. 丁可. 基于变换域的数字图像水印算法研究与实现[D].苏州大学,2013.
  2. 赵红, 王丽萍, 温文雅, et al. 基于 DWT 及 DCT 的数字图像水印综述[J]. 网络新媒体技术, 2008, 29(1):1-5.
支付宝收款码
Copyright © yiluomyt 2020