本文是对 HIT 课程信息隐藏技术基础中出现的诸多算法的概括性总结。

若无特殊说明,仅对灰度图像进行讨论。

在此说明,因为嵌入算法和提取算法成对存在,所以本文在介绍二者时有意模糊其先后关系,相比在当初设计算法之时二者诞生并无先后,甚至有些嵌入算法会调用提取算法作为子步骤,在仅有载体和嵌入信息为先的现实面前实在是一对有趣的矛盾。

BMP 图像和 JPEG 图像隐写

BMP 图像由位图文件头(14 字节,包含文件类型,大小,偏移字节),位图信息头(40 字节,包括图像尺寸,通道,颜色位数),彩色表(即调色板,可选)和位图数据四部分组成。

JPEG 图像压缩过程如下:
第一步,分块,一般分为 8 * 8 块
第二步,对每小块进行正向 DCT 变换(为了减少直流系数表示位数,变换前所有像素值减 128,由于结果四舍五入故不可逆)
第三步,量化,即 DCT 系数除以量化表系数(不同量化表代表不同压缩率,不可逆)
第四步,熵编码(去冗余,可逆)

JPEG 图像隐写一般在量化之后,熵编码之前。

LSB 隐写

最低有效位(Least Significant Bit,简称 LSB)隐写遵循以下原理:图像的不同位平面虽然所占空间相等,但对图像视觉效果的贡献不等。高位平面贡献大,扰动后对图像影响大;而低位平面反之。LSB 隐写在维持高位平面不变的条件下,允许以嵌入信息替代载体图像的最低比特位平面,嵌入前后对于图像每个位置的灰度值不变或差值为 1。

提取算法:对于嵌入后图像的每个像素值,取其最低比特位,即可得出嵌入信息。

嵌入算法:对于载体图像的每个像素值,将其最低比特位替换成嵌入信息的对应位即可。

例如,将信息 [1 1 0 0 0] 嵌入载体 [77 78 81 79 80] 中,将载体以二进制表示为 [01001101 01001110 01010001 01001111 01010000],以信息替换最低位得 [01001101 01001111 01010000 01001110 01010000],转回十进制得 [77 79 80 78 80]。

单从提取算法来看,对于上面的例子,你可以给出其它不同的结果,如 [77 77 82 78 80],这个结果与载体在每个位置的灰度值差值至多为 1,这意味着这个结果在视觉效果上与标准 LSB 隐写得出的结果不相上下,并且也可以提取出嵌入信息。关于这部分内容的讨论在下文随机翻转嵌入隐写中。

Jsteg 隐写

Jsteg 隐写是将 LSB 隐写扩展到 JPEG 格式图片的一种隐写算法。由于载体为 DCT 系数矩阵,故对于负数看作其绝对值进行处理。由于 DCT 系数矩阵中长串 0 保证压缩效率,故对于 0 及会被替换成 0 的 1 和 -1,Jsteg 隐写均跳过。其余按绝对值下的 LSB 隐写规则,并保证嵌入前后正负号相同,DCT 矩阵每个系数不变或差值为 1。

提取算法:对于嵌入后图像的每个 DCT 系数,如果不是 1, 0, -1 中的一个,则取其绝对值的最低比特位,即可得出嵌入信息。

嵌入算法:对于载体图像的每个 DCT 系数,如果是 1, 0, -1 中的一个则跳过,否则按 LSB 隐写对其绝对值嵌入,而后补上嵌入前的正负号。

例如,将信息 [0 0 1 1 0] 嵌入 DCT 系数矩阵
[970−1−10000−3−2400000−2−1000000−1000000000000000000000000000000000000000] \begin{bmatrix} 97 & 0 & -1 & -1 & 0 & 0 & 0 & 0 \\ -3 & -2 & 4 & 0 & 0 & 0 & 0 & 0 \\ -2 & -1 & 0 & 0 & 0 & 0 & 0 & 0 \\ -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \end{bmatrix} 97321000002100000140000001000000000000000000000000000000000000000
具体来说就是 0 嵌入 97 得 96,0 嵌入 -3 得 -2,1 嵌入 -2 得 -3,1 嵌入 4 得 5,0 嵌入 -2 得 -2,最终结果
[960−1−1⋯−2−350⋯−2−100⋯−1000⋯⋮⋮⋮⋮⋱] \begin{bmatrix} 96 & 0 & -1 & -1 & \cdots \\ -2 & -3 & 5 & 0 & \cdots \\ -2 & -1 & 0 & 0 & \cdots \\ -1 & 0 & 0 & 0 & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix} 96221031015001000
(注:JPG 格式中 DCT 系数矩阵以 Z 字形存储,故一般也以 Z 字形顺序隐写,这里为了说明方便而采用逐行顺序隐写)

将负数看作补码再以 LSB 隐写也是一种变体,这样可以对 -1 隐写增大嵌入率,在此不表。

F3 隐写

F3 隐写相对 Jsteg 隐写将 1 和 -1 也进行嵌入,增大了嵌入率,同时不再依赖传统的 LSB 隐写。嵌入后 DCT 矩阵每个系数或者不变,或者与嵌入前相比绝对值小 1。

提取算法:对于嵌入后图像的每个 DCT 系数,如果不是 0,则取其绝对值的最低比特位,即可得出嵌入信息。

嵌入算法:对于载体图像的每个 DCT 系数,如果是 0 则跳过,如果当前系数 LSB 与待嵌信息位相同则不变,不同则取绝对值减 1,而后补上嵌入前的正负号。特别的,当当前系数为 1 或 -1 且待嵌信息位为 0 时,将其归 0 并视作无效嵌入,下一位仍嵌入 0。

例如,对于上文 Jsteg 中的例子,第一位 0 嵌入 97 得 96,第二位 0 嵌入 -1 得 0 无效,第二位 0 嵌入 -1 得 0 无效,第二位 0 嵌入 -3 得 -2,第三位 1 嵌入 -2 得 -1,第四位 1 嵌入 4 得 3,第五位 0 嵌入 -2 得 -2,最终结果
[96000⋯−2−130⋯−2−100⋯−1000⋯⋮⋮⋮⋮⋱] \begin{bmatrix} 96 & 0 & 0 & 0 & \cdots \\ -2 & -1 & 3 & 0 & \cdots \\ -2 & -1 & 0 & 0 & \cdots \\ -1 & 0 & 0 & 0 & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix} 96221011003000000

可以发现,对载体 2 嵌入信息 1,LSB 隐写和 Jsteg 隐写的结果为 3,而 F3 隐写的结果为 1。这种不遵循 LSB 隐写规则的结果之一是使得针对 LSB 的隐写分析技术对其收效甚微。

基于视觉特性的隐写

BPCS 隐写

位平面复杂度分割(Bit-Plane Complexity Segmentation,简称 BPCS)隐写遵循以下原理:图像中各个大小相等的区域虽然所占空间相等,但人眼对其的敏感程度不同,图像像素值变化越剧烈,嵌入信息前后人眼视觉对其变化越不敏感。相对于 LSB 隐写而言,BPCS 隐写中信息不再局限于最低比特位构成的位平面,而可以嵌入多个位平面,扩大了容量。不仅是空间域,小波压缩域等变换域亦可应用。

由于其过于复杂,基本不会在大题出现。

为了衡量位平面块复杂度,定义一个位平面块复杂度为所有值不同的像素对的数量(包括上下相邻的和左右相邻的),对于 8 * 8 块,最大值 Cmax=2∗7∗8=112C_{max} = 2 * 7 * 8 = 112Cmax=278=112。注意这里是取某个位平面计算,所以像素值只能取 0 或 1。

提取算法:
第一步,将嵌入后图像的每个位平面分块,一般分为 8 * 8 块,计算每个位平面块的复杂度 C′C'C
第二步,取 a<0.5a < 0.5a<0.5,对于每个位平面块,若其复杂度 C′>aCmaxC' > aC_{max}C>aCmax 则提取信息;否则跳过。
第三步,提取记录经过共轭处理的块信息的位平面块信息。
第四步,对于第二步提取信息的位平面块,若记录得出经过共轭处理的则再共轭一次后提取,否则直接提取。

嵌入算法:
第一步,同提取算法第一步,得出每个位平面的复杂度 CCC
第二步,取与提取算法相同的 aaa,对于每个位平面块,若其复杂度 C>aCmaxC > aC_{max}C>aCmax 则嵌入信息;否则跳过,不嵌入信息。
第三步,将嵌入信息构成同样大小的块,计算其复杂度 C′C'C,若 C′>aCmaxC' > aC_{max}C>aCmax,则直接替换原位平面;否则共轭处理再替换。
第四步,记录经过共轭处理的块信息(位置,位平面),将其作为信息嵌入载体中。

以 8 * 8 块为例,所谓共轭处理,即将位平面块每个元素分别与
[0101010110101010010101011010101001010101101010100101010110101010] \begin{bmatrix} 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 \end{bmatrix} 0101010110101010010101011010101001010101101010100101010110101010
块中对应元素异或,得到位平面块的共轭块。由于在原位平面块值相同的相邻像素对,共轭后值不同,反之亦然,故若原平面块复杂度为 CCC,则共轭后平面块复杂度为 Cmax−CC_{max} - CCmaxC

其中,参数 aaa 越大,嵌入率越低,安全性越好。若 a≥0.5a \geq 0.5a0.5,则对于复杂度 C′∈[(1−a)Cmax,aCmax]C' \in [(1 - a)C_{max}, aC_{max}]C[(1a)Cmax,aCmax] 的嵌入信息块,无论其本身还是共轭后复杂度都低于 aCmaxaC_{max}aCmax,就算强行嵌入后提取时也会跳过,最终得到缺失的嵌入信息。不过,实际工程中 aaa 可以取大于 0.50.50.5 的值,不过需要特殊的技巧,在此不表。

PVD 隐写

像素值差异(Pixel-Value Differencing,简称 PVD)隐写不再关注像素值本身,而是着眼于相邻像素值间的差值,依赖差值嵌入信息。

提取算法:
第一步,将亮度范围 [0,255][0, 255][0,255] 分为 KKK 个区域 Rk(k∈[0,K−1])R_k (k \in [0, K-1])Rk(k[0,K1]),每个区域宽度均为 2 的整数幂,记每个区域的上界,下界和宽度分别为 lk,uk,wkl_k, u_k, w_klk,uk,wk,以下均以 [0,7],[8,15],[16,31],[32,63],[64,127],[128,255][0, 7], [8, 15], [16, 31], [32, 63], [64, 127], [128, 255][0,7],[8,15],[16,31],[32,63],[64,127],[128,255] 六个区域的划分为例
第二步,将嵌入后图像分成不相交的像素对 (p0′,p1′),⋯ ,(pi′,pi+1′),⋯(p'_0, p'_1), \cdots, (p'_i, p'_{i+1}), \cdots(p0,p1),,(pi,pi+1),,对于每个像素对 (pi′,pi+1′)(p'_i, p'_{i+1})(pi,pi+1),计算灰度差值 d′=pi+1′−pi′d' = p'_{i+1} - p'_id=pi+1pi
第三步,判断 ∣d′∣\left| d' \right|d 所处区域 RkR_kRk,即若 ∣d′∣∈[lk,uk]\left| d' \right| \in [l_k, u_k]d[lk,uk],则计算 b=∣d′∣−lkb = \left| d' \right| - l_kb=dlk 的二进制形式即为嵌入信息,长度为 log⁡2wk\log_2 w_klog2wk

嵌入算法:
第一步,同提取算法第一步
第二步,同提取算法第二步划分方式,将载体图像分成不相交的像素对 (p0,p1),⋯ ,(pi,pi+1),⋯(p_0, p_1), \cdots, (p_i, p_{i+1}), \cdots(p0,p1),,(pi,pi+1),,对于每个像素对 (pi,pi+1)(p_i, p_{i+1})(pi,pi+1),计算灰度差值 d=pi+1−pid = p_{i+1} - p_id=pi+1pi
第三步,判断 ∣d∣\left| d \right|d 所处区域 RkR_kRk,即若 ∣d∣∈[lk,uk]\left| d \right| \in [l_k, u_k]d[lk,uk],则将嵌入信息 log⁡2wk\log_2 w_klog2wk 个比特位转化为数 bbb,并计算
d′={lk+bd≥0−(lk+b)d<0 d' = \begin{cases} l_k + b & d \geq 0 \\ -(l_k + b) & d < 0 \end{cases} d={lk+b(lk+b)d0d<0
第四步,计算嵌入后像素值
rc=⌈d′−d2⌉,rf=⌊d′−d2⌋(pi′,pi+1′)=f[(pi,pi+1),d′]={(pi−rc,pi+1+rf)d mod 2=1(pi−rf,pi+1+rc)d mod 2=0 r_c = \lceil \frac{d' - d}2 \rceil , r_f = \lfloor \frac{d' - d}2 \rfloor \\ (p'_i, p'_{i+1}) = f[(p_i, p_{i+1}), d'] = \begin{cases} (p_i - r_c, p_{i+1} + r_f) & d \ mod \ 2 = 1 \\ (p_i - r_f, p_{i+1} + r_c) & d \ mod \ 2 = 0 \end{cases} rc=2dd,rf=2dd(pi,pi+1)=f[(pi,pi+1),d]={(pirc,pi+1+rf)(pirf,pi+1+rc)d mod 2=1d mod 2=0
(这个公式的结果可能会不在 [0,255][0, 255][0,255] 区间内,遇到这种情况要整体偏移)

例如,将信息 [1 1 1 0 1 0 1] 嵌入载体 [105 113 118 101] 中。
计算 d=113−105=8,∣d∣∈[8,15]d = 113 - 105 = 8, \left| d \right| \in [8, 15]d=113105=8,d[8,15],嵌入 3 位 [1 1 1],得 b=7,d′=8+7=15,d′−d=7,rc=4,rf=3b = 7, d' = 8 + 7 = 15, d' - d = 7, r_c = 4, r_f = 3b=7,d=8+7=15,dd=7,rc=4,rf=3,由 ddd 为偶数,用公式 (pi−rf,pi+1+rc)(p_i - r_f, p_{i+1} + r_c)(pirf,pi+1+rc) 得 (102, 117);
计算 d=101−118=−17,∣d∣∈[16,31]d = 101 - 118 = -17, \left| d \right| \in [16, 31]d=101118=17,d[16,31],嵌入 4 位 [0 1 0 1],得 b=5,d′=−(16+5)=−21,d′−d=−4,rc=rf=−2b = 5, d' = -(16 + 5) = -21, d' - d = -4, r_c = r_f = -2b=5,d=(16+5)=21,dd=4,rc=rf=2,由 ddd 为奇数,用公式 (pi−rc,pi+1+rf)(p_i - r_c, p_{i+1} + r_f)(pirc,pi+1+rf) 得 (120, 99);
结果 [102 117 120 99]。

接下来的内容纯属笔者一家之言,读者可略过,直至调色板图像隐写部分。

上面的公式看起来十分麻烦,这里来分情况讨论。当 d 与 d’ 奇偶性相同,即 d’ - d 结果为偶数时,rc−rf=0r_c - r_f = 0rcrf=0,上面两个公式结果相同。当 d 与 d’ 奇偶性相反,即 d’ - d 结果为奇数时,rc−rf=1r_c - r_f = 1rcrf=1,上面两个公式结果不同。但为何要有两个公式呢?

笔者在这里给出一个数学上自洽的解释,定义像素值中点 m=pi+pi+12,m′=pi′+pi+1′2m = \frac{p_i + p_{i+1}}2, m' = \frac{p'_i + p'_{i+1}}2m=2pi+pi+1,m=2pi+pi+1,则无论是两个公式的任一个,都能保证 ∣m′−m∣≤0.5\left| m' - m \right| \leq 0.5mm0.5,即保证直流系数基本不变,达到在整体灰度上令人眼无法察觉的效果。下面想象一种操作,其为重复使用 PVD 隐写对同一像素对进行嵌入(先不论该操作是否有意义),其结果自然为后嵌入的信息覆盖前嵌入的,虽然每次嵌入都能保证 ∣m′−m∣≤0.5\left| m' - m \right| \leq 0.5mm0.5,但若只使用单一公式,如相对下方的公式 (pi−rf,pi+1+rc)(p_i - r_f, p_{i+1} + r_c)(pirf,pi+1+rc),则由 m′=m+rc−rf2m' = m + \frac{r_c - r_f}2m=m+2rcrf,像素值中点必然只增不减,最终累积造成直流系数视觉上无法忽视的巨大偏移。而两个公式均使用的情况下,若某次使用了下方公式造成了中点 0.50.50.5 的增大,则像素值的差 ddd 必然由偶数变成了奇数,若中点不偏移则差 ddd 不改变奇偶性,那么下次造成偏移时必然是上方公式造成中点 0.50.50.5 的减小而且差 ddd 由奇数变为偶数,巧妙地化解了偏移。这样无论隐写多少次,结果的像素值中点 mmm 与最初像素值中点 m0m_0m0 都满足关系 ∣m−m0∣≤0.5\left| m - m_0 \right| \leq 0.5mm00.5,保证了直流系数一定程度的不变性。

以上的解释看似完美,实际上却忽略了两个问题。第一,由于结果可能会超出区间 [0,255][0, 255][0,255] 而进行整体偏移操作无疑会不可逆地改变像素值中点,从而对直流系数产生不可估量的影响;第二,也是最本质的问题,PVD 隐写只需对每个像素对进行一次修改,不存在也不需要多次操作。下面笔者将给出个不太完美但更合理的解释。由于整个载体图像有很多个这样的像素对,只使用单一公式会使得整个图像的直流系数产生累积偏移。而从概率的角度来说,使用两个公式的概率是相等的,可以在统计学上保证约有一半偏移是加 0.50.50.5,一半偏移是减 0.50.50.5,从而保证整个图像的直流系数基本不变。至于结果超出区间引起的整体偏移,由于概率很小可以忽略不计。这个解释的问题在于,一旦引入了概率,整个问题就玄乎其玄了起来,似乎就不太像是能在这里讨论完的内容了。

调色板图像隐写

调色板图像均指彩色图像(灰度图像谈调色板无意义),反之不然(彩色图像亦可为 BMP 或 JPEG 图像)。

Gifshuffle

Gifshuffle 算法不改变图像本身,而是通过改变调色板中颜色与索引间的对应关系传递信息,类似密码本的方法。理论上,颜色数为 MMM 的调色板图像按 Gifshuffle 算法可容纳 ⌊log⁡2(M!)⌋\lfloor \log_2(M!) \rfloorlog2(M!) 比特信息。

由于其性质特殊,基本不会在大题出现。

EZStego 隐写

提取算法:将调色板中颜色按亮度排序得到索引值,对于嵌入后图像的每个像素,取其亮度索引值的最低比特位,即可得出嵌入信息。

嵌入算法:将调色板中颜色按亮度排序得到索引值,对于载体图像按亮度索引值进行 LSB 隐写即可。

隐写分析

由于隐写分析算法计算复杂,均基本不会在大题出现。

χ2\chi^2χ2 隐写分析

χ2\chi^2χ2 隐写分析基于以下原理:设嵌入信息后图像灰度值为 j 的像素数为 hjh_jhj,若信息完全替代最低位平面,由于信息经过压缩去冗余,则 h2ih_{2i}h2ih2i+1h_{2i+1}h2i+1 的值会比较接近,而未经密写的图像 h2ih_{2i}h2ih2i+1h_{2i+1}h2i+1 的值会相差较远。由于 LSB 隐写不改变 h2i+h2i+1h_{2i} + h_{2i+1}h2i+h2i+1,故令
h2i∗=h2i+h2i+12 h_{2i}^* = \frac{h_{2i} + h_{2i+1}}2 h2i=2h2i+h2i+1
h2i∗h_{2i}^*h2i 值在隐写前后不变,于是:
r=∑i=1k(h2i−h2i∗)2h2i∗ r = \sum_{i = 1}^k \frac{(h_{2i} - h_{2i}^*)^2}{h_{2i}^*} r=i=1kh2i(h2ih2i)2
服从 χ2\chi^2χ2 分布,其中 kkkh2ih_{2i}h2ih2i+1h_{2i+1}h2i+1 所组成数对的数量。

RS 隐写分析

RS 隐写分析分以下几步:
第一步,分块,一般分为 8 * 8 块,计算每个小图像块的像素相关性。
第二步,对每个小图像块进行非负翻转和非正翻转。
第三步,计算翻转后每个小图像块的像素相关性,判断是否增大或减小。

像素相关性计算:将小图像块所有像素按 Z 字形顺序排列成向量 (x1,x2,⋯ ,xn)(x_1, x_2, \cdots, x_n)(x1,x2,,xn) (nnn 表示像素个数,分成 8 * 8 块时为 64,xix_ixi 表示像素值),定义像素相关性函数
f(x1,x2,⋯ ,xn)=∑i=1n−1∣xi−xi−1∣ f(x_1, x_2, \cdots, x_n) = \sum_{i = 1}^{n - 1} |x_i - x_{i-1}| f(x1,x2,,xn)=i=1n1xixi1

将非负翻转后像素相关性增大的图像块比例记为 RmR_mRm,像素相关性减小的图像块比例记为 SmS_mSm
将非正翻转后像素相关性增大的图像块比例记为 R−mR_{-m}Rm,像素相关性减小的图像块比例记为 S−mS_{-m}Sm
若图像未经 LSB 隐写,则满足 Rm≈R−m,Sm≈S−mR_m \approx R_{-m}, S_m \approx S_{-m}RmRm,SmSmRm>Sm,R−m>S−mR_m > S_m, R_{-m} > S_{-m}Rm>Sm,Rm>Sm
随着隐写率上升,R−mR_{-m}RmSmS_mSm 增大,RmR_mRmS−mS_{-m}Sm 减小,并始终满足 R−m>(Rm,Sm)>S−mR_{-m} > (R_m, S_m) > S_{-m}Rm>(Rm,Sm)>SmRmR_mRmSmS_mSm 相比大小取决于嵌入信息和载体图像。

F3 隐写分析

简单来说,若 JPEG 图像未经 F3 隐写,则 DCT 系数分布直方图服从 Laplace 分布,否则不服从。

抗隐写分析的隐写

由于直方图补偿隐写(针对 χ2\chi^2χ2 隐写分析)过于宏观,随机翻转嵌入隐写(针对 RS 隐写分析)本质随机化,F5 隐写(针对 F3 隐写分析)高度数学化,均基本不会在大题以实例出现。

直方图补偿隐写

直方图补偿隐写基于 LSB 隐写将载体分为隐写部分与补偿部分,补偿部分不嵌入信息,而是保证将灰度直方图恢复至嵌入前的水平,从而抗隐写分析。设 fif_ifi 为原始图像灰度值为 iii 的像素数目,α\alphaα 为信息嵌入率,不妨设 f2i>f2i+1f_{2i} > f_{2i+1}f2i>f2i+1,由于嵌入后隐写部分灰度值为 2i2i2i2i+12i+12i+1 的像素值数量相等,故有不等式
(1−α)f2i+1≥α2(f2i−f2i+1) (1 - \alpha)f_{2i+1} \geq \frac{\alpha}{2}(f_{2i} - f_{2i+1}) (1α)f2i+12α(f2if2i+1)
不等式右项表示隐写部分从灰度值 2i2i2i 变成 2i+12i+12i+1 的像素数量,左项表示补偿部分从灰度值 2i+12i+12i+1 变成 2i2i2i 的像素数量。整理得
α≤2f2i+1f2i+f2i+1 \alpha \leq \frac{2f_{2i+1}}{f_{2i} + f_{2i+1}} αf2i+f2i+12f2i+1

随机翻转嵌入隐写

提取算法:同 LSB 隐写的提取。

嵌入算法:基本同 LSB 隐写的嵌入,当当前位需要改变且像素值不为 0 或 255 时随机选择 +1 或 -1。

F5 隐写

F5 隐写算法使用混洗技术与矩阵编码技术,混洗技术即打乱 DCT 系数顺序,使得嵌入信息分散于整个载体中;而矩阵编码技术保证了 F5 算法在使用 2k−12^k-12k1 个载体数据嵌入 kkk bit 信息时,至多改变其中一个载体数据。

提取算法:将嵌入后图像数据的最低比特位编号 a1,a2,⋯ ,a2k−1a_1, a_2, \cdots, a_{2^k-1}a1,a2,,a2k1,对于 i∈[0,k−1],yi=⊕j Bitwise AND 2i=2iaji \in [0, k-1], y_i = \oplus_{j \ Bitwise \ AND \ 2^i = 2^i} a_ji[0,k1],yi=j Bitwise AND 2i=2iaj,其中 ⊕\oplus 表示异或,这里由于参数不定故采用前缀表示,Bitwise ANDBitwise \ ANDBitwise AND 表示按位与,条件 j Bitwise AND 2i=2ij \ Bitwise \ AND \ 2^i = 2^ij Bitwise AND 2i=2i 表示 jjj 二进制下权值为 2i2^i2i 的二进制位为 1。这样得出 y0,y1,⋯ ,yk−1y_0, y_1, \cdots, y_{k-1}y0,y1,,yk1 即为嵌入信息。

嵌入算法:将载体图像数据的最低比特位编号 a1,a2,⋯ ,a2k−1a_1, a_2, \cdots, a_{2^k-1}a1,a2,,a2k1,将嵌入信息编号 x0,x1,⋯ ,xk−1x_0, x_1, \cdots, x_{k-1}x0,x1,,xk1,对载体本身用提取算法得出序列 b0,b1,⋯ ,bk−1b_0, b_1, \cdots, b_{k-1}b0,b1,,bk1,对于 i∈[0,k−1],ci=xi⊕bii \in [0, k-1], c_i = x_i \oplus b_ii[0,k1],ci=xibi,这样得出序列 c0,c1,⋯ ,ck−1c_0, c_1, \cdots, c_{k-1}c0,c1,,ck1,再由 c=∑i∈[0,k−1]ci∗2ic = \sum_{i \in [0, k-1]} c_i * 2^ic=i[0,k1]ci2i 得出 ccc,修改载体数据 aca_cac 的值(即最低比特位取反)即嵌入完成,当 c=0c = 0c=0 时无需修改即完成嵌入。

例如:将信息 [0 1] 嵌入载体 [123 124 125] 中,由
c0=x0⊕a1⊕a3=0⊕1⊕1=0c1=x1⊕a2⊕a3=1⊕0⊕1=0 c_0 = x_0 \oplus a_1 \oplus a_3 = 0 \oplus 1 \oplus 1 = 0 \\ c_1 = x_1 \oplus a_2 \oplus a_3 = 1 \oplus 0 \oplus 1 = 0 c0=x0a1a3=011=0c1=x1a2a3=101=0
得出 c = 0,无需修改,结果 [123 124 125]。

例如:将信息 [1 0 1] 嵌入载体 [13 17 16 16 19 21 20] 中,由
c0=x0⊕a1⊕a3⊕a5⊕a7=1⊕1⊕0⊕1⊕0=1c1=x1⊕a2⊕a3⊕a6⊕a7=0⊕1⊕0⊕1⊕0=0c2=x2⊕a4⊕a5⊕a6⊕a7=1⊕0⊕1⊕1⊕0=1 c_0 = x_0 \oplus a_1 \oplus a_3 \oplus a_5 \oplus a_7 = 1 \oplus 1 \oplus 0 \oplus 1 \oplus 0 = 1 \\ c_1 = x_1 \oplus a_2 \oplus a_3 \oplus a_6 \oplus a_7 = 0 \oplus 1 \oplus 0 \oplus 1 \oplus 0 = 0 \\ c_2 = x_2 \oplus a_4 \oplus a_5 \oplus a_6 \oplus a_7 = 1 \oplus 0 \oplus 1 \oplus 1 \oplus 0 = 1 c0=x0a1a3a5a7=11010=1c1=x1a2a3a6a7=01010=0c2=x2a4a5a6a7=10110=1
得出 c=2∗(2∗(0+c2)+c1)+c0=5c = 2 * (2 * (0 + c_2) + c_1) + c_0 = 5c=2(2(0+c2)+c1)+c0=5,修改 19 为 18,结果 [13 17 16 16 18 21 20]。

数字水印

以下仅讨论基于单伪随机序列的扩频技术数字水印嵌入。

数字水印嵌入遵循以下公式
X′=X+(αb−λs′)ws′=1N∑i=1NXiwi X' = X + (\alpha b - \lambda s')w \\ s' = \frac1N \sum_{i = 1}^N X_i w_i X=X+(αbλs)ws=N1i=1NXiwi
其中 X′X'X 表示含水印图像,XXX 表示原始图像,α\alphaα 表示嵌入强度,bbb 表示水印信息,λ\lambdaλ 一般取 1,www 表示扩频序列,s′s's 表示原始图像与扩频序列的相关性,NNN 表示扩频序列长度。以上公式保证提取水印信息时四舍五入后得到的值为 αb\alpha bαb

由于其为本门课重点,一定会在大题出现。

提取算法:取含水印图像像素值向量与 1 的扩频序列向量点乘,结果大于 0 则水印信息为 1,否则为 -1。

嵌入算法:利用以上公式计算即可。

例如,水印信息 [-1 1 -1 1],扩频序列 1 -> [1 -1 -1 1],-1 -> [-1 1 1 -1],α=4\alpha = 4α=4,原始图像像素值
[139144149153155155155155144151153156159156156156] \begin{bmatrix} 139 & 144 & 149 & 153 & 155 & 155 & 155 & 155 \\ 144 & 151 & 153 & 156 & 159 & 156 & 156 & 156 \end{bmatrix} [139144144151149153153156155159155156155156155156]
计算含水印图像像素值。

解答如下,确定 www = [1 -1 -1 1],算出相关性系数 s′s's 分别为 -1/4, 0, -1, 3/4,分别得出
[139 144 149 153] + -4 [1 -1 -1 1] = [135 148 153 149]
[155 155 155 155] + 4 [1 -1 -1 1] = [159 151 151 159]
[144 151 153 156] + -3 [1 -1 -1 1] = [141 154 156 153]
[159 156 156 156] + 3 [1 -1 -1 1] = [162 153 153 159]
结果
[135148153149159151151159141154156153162153153159] \begin{bmatrix} 135 & 148 & 153 & 149 & 159 & 151 & 151 & 159 \\ 141 & 154 & 156 & 153 & 162 & 153 & 153 & 159 \end{bmatrix} [135141148154153156149153159162151153151153159159]

还有另一种思路,www 依据水印信息而定,如上例,在 [139 144 149 153] 中嵌入水印 -1,令 www 为 -1 的扩频序列 [-1 1 1 -1],得出相关性系数 s′s's = 1/4,于是 [139 144 149 153] + (4 * |-1| - 1/4)[-1 1 1 -1] = [135 148 153 149]。整个过程中需注意 bbb 取绝对值再代入计算,这点与上面思路不同。如果 bbb 不取绝对值,那么在 [155 155 155 155] 嵌入水印 -1 得 [155 155 155 155] + (4 * -1)[-1 1 1 -1] = [159 151 151 159],与嵌入水印 1 结果相同,这显然是错误的。

不论何种思路,计算相关性时的扩频序列和计算嵌入水印后像素值向量的扩频序列一定要相同,不能出现一者固定另一者随水印信息变化的情况,否则无法保证提取水印信息时四舍五入后得到的值为 αb\alpha bαb

直方图平移可逆水印

嵌入算法:统计图像像素灰度值得出直方图,判断峰值点 aaa 和零点 bbb(若不存在零点则此算法失效),不妨设 a<ba < ba<b,对于灰度值为 iii 的像素,若 i∈(a,b)i \in (a, b)i(a,b),将其灰度值修改为 i+1i + 1i+1,这样零点变成 a+1a + 1a+1,便可在灰度值为 aaa 的像素中嵌入信息(选峰值点是为了嵌入更多信息),若最低比特位不同则改为 a+1a + 1a+1 即可。这样保证嵌入前后对于图像每个像素灰度值差值至多为 1。

提取算法:嵌入的逆过程,aaabbb 的值需额外传递。

由于其在期末考试中出现,故列之于此。隐写及水印算法多以提取较嵌入简单,故本文大多先介绍提取算法后介绍嵌入算法,而此算法例外。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐