DEW是采用改变图像区域能量关系来实现特定的水印嵌入的方法,方法流程如下:
1. 对于一个含有n个8*8像素块的区域,将其平均分为两部分。
2. 对于每一部分的每一个8*8块,做离散余弦变换。
3. 对于每一部分求该部分的能量(能量求法在下面介绍),并得到能量差Ea - Eb。
4. 若能量差为正,则表示嵌入1。否则表示嵌入0。
通过对于DCT变换后的结果进行处理,可由此改变能量差从而控制对于特定比特的嵌入。
能量差计算方法:
在上图右下角圆圈中,是8*8的DCT变换后的结果。该点的能量为其Zigzag序列后方的所有值的平方和。
公式为:
若Zigzag后的数列为A,长度为n。则能量
给一个实际的例子:
怎样调整能量
首先需要设置一个阀值,在上图中就是D,D = 500。
如果要A的能量大于B(嵌入1),则要找到最大的i,使得EA(i) > D且EB(i)>D。上图中i = 35。
然后,将B的Zigzag序列的第i(图中为35)项后面的所有项清零。
同理,如果要嵌入0,则清除A后方的所有项。
在处理结束后,还需要还原为原图,做zigzag和dct的逆向操作。
下面给出其MATLAB实现代码:
%a:原图,灰度图或彩图的一维
%w:水印,此处为二值图像,如为彩图则需自行处理为比特流
%D:阀值
function pic = MarkInsert(a, w, D)
sw = size(w);
s = sw(1) * sw(2);
sa = size(a);
a = reshape(a,8,8,[]);
w = reshape(w,1,[]);
for i=1:s
a1 = zigzag(dct2(a(:,:,2*i -1)));
a2 = zigzag(dct2(a(:,:,2*i)));
%wipe函数用以将指定Zigzag序列后端置零
[a1, a2] = wipe(a1, a2, D, w(:,i));
a(:,:,2*i -1) = idct2(izigzag(a1));
a(:,:,2*i) = idct2(izigzag(a2));
end
pic = reshape(a, sa);
其中wipe函数的实现方法:
function [a1, a2] = wipe(a1, a2, D, n)
a3 = a1.*a1;
a4 = a2.*a2;
for index = 64:-1:1
if(sum(a3(:,index:64)) > D && sum(a4(:,index:64)) > D)
break;
end
end
if n == 0
a1(index:64) = 0;
elseif n == 1
a2(index:64) = 0;
end