3.1 图像数字水印的技术方案
在数据库中存储在国际互联网上传输的水印图像一般会被压缩,有时达到很高的压缩比。因此,数字水印算法所面临的第一个考验就是压缩。JPEG和EZW(Embedded Zero-Tree Wavelet)压缩是最常见的两种压缩方法。JPEG是基于离散余弦变换域的压缩方法,而EZW是基于小波变换域的压缩方法。前人的研究证明采用与压缩算法相同的变换域水印方法,对于压缩的稳健性较强。因此,我研究图像文件水印算法主要集中在变换域算法及利用人眼视觉特性上。
数字水印的嵌入要求即要考虑视觉透明性,又要保证嵌入水印后图像的稳健性,这两个方面存在着矛盾。保证视觉透明性,就要将水印嵌入到人眼不敏感区,也就是嵌入到图像的高频分量中。而多数图像处理方法对于图像高频部分的损坏程度较高,如有损压缩、高频滤波等。水印很容易在经历图像处理的过程中丢失。这样,则无法保证图像数字水印的稳健性。如果要获得很好的稳健性,数字水印应加在人眼敏感的低频部分,图像的大部分能量集中在低频部分,如果对于低频部分进行处理,水印固然会失去,而图像也没有了利用价值,然而,水印的嵌入会对图像的质量有非常大的影响,这又无法保证视觉透明性。
数字水印算法的实现基本分为三个部分:宿主图像的变换,水印的嵌入和水印的检测,分别描述如下。
3.2 基于DCT域的图像数字水印技术
离散余弦变换(Discrete Cosine Transform)属于正交变换图像编码方法中的一种。正交变换图像编码始于1968年。当时安德鲁斯(Andrews)等人发现大多数自然图像的高频分量相对幅度较低,可完全舍弃或者只用少数码字编码,提出不对图像本身编码,只对其二维傅立叶(DFT)系数进行编码和传输。但DFT是一种正交变换,运算量很大,常常使实时处理发生困难,第二年他们就用Walsh-Hadamard变换(WHT)取代DFT可以使运算量明显减少,这是因为WHT变换只有加减法而无需乘法。但是更有意义的是离散余弦变换和离散正旋变换的出现,它们具有快速算法,精确度高。其中最重要的是1974年提出的DCT,因为其变换矩阵的基向量很近似于托伯利兹矩阵的特征向量,而托伯利兹矩阵又体现了人类语言及图像信号的相关性。因此,DCT常常被认为是语音与图像信号变换的准最佳变换。
图像是二维的,所以在研究时主要用到二维DCT,
第四章: 图像数字水印技术的实现
4.1 基于离散余弦变法(DCT)实现数字水印技术
① 打开原始及水印图像:
subplot(2,2,1)
I=uigetfile('*.bmp','打开原始彩色图像文件');
RGB=imread(I);
image(RGB);
title('原始彩色图像');
subplot(2,2,2)
I=uigetfile('*.bmp','打开水印灰度图像文件');
imshow(I);
title('灰度水印图像');
subplot(2,2,3)
H=imread(I);
J=dct2(H);
imshow(log(abs(J)),[]),colorbar;
title('水印图像经DCT变换后能量分布情况')
运行结果:
② 水印全过程:
0%水印加入程序
Q=input('请输入放缩因子的值(建议小于1):Q=')
subplot(2,3,1)
RGB=imread('南京邮电大学','jpg');
imshow(RGB);
title('原始图像');
subplot(2,3,2)
N=dct2(RGB(:,:,3));
imshow(log(abs(N)),[]),colorbar;
title('Y分量能量分布');
subplot(2,3,4)
I=imread('lena1','bmp');
imshow(I);
title('灰度水印图像');
subplot(2,3,5)
M=dct2(I);
imshow(log(abs(M)),[]),colorbar;
title('水印能量分布');
subplot(2,3,6)
J=M(1:128,1:128);
J(128:364,128:400)=0;
J=rot90(J);
J=rot90(J);
J(365:600,401:750)=0;
J=rot90(J);
J=rot90(J);
N=N+Q*J;
K=idct2(N);
RGB(:,:,3)=K;
imshow(RGB);
title('加入水印后图像');
%水印提取程序
subplot(2,3,3)
RGB1=imread('南京邮电大学','jpg');
N=dct2(RGB(:,:,3));
M=dct2(RGB1(:,:,3));
M=(N-M)/Q;
B=idct2(M(236:365,350:401));
Y=mat2gray(B);
imshow(Y);
title('提取的水印图像')
运行结果:
③ 水印全过程(经剪切检测水印)
%水印加入程序
Q=input('请输入放缩因子的值(建议小于1):Q=')
subplot(3,3,1)
RGB=imread('MM','jpg');
imshow(RGB);
title('原始图像');
subplot(3,3,2)
imshow(RGB(:,:,3));
title('B分量');
subplot(3,3,3)
N=dct2(RGB(:,:,3));
imshow(log(abs(N)),[]),colorbar;
title('B分量能量分布');
subplot(3,3,4)
I=imread('lena1','bmp');
imshow(I);
title('灰度水印图像');
subplot(3,3,5)
M=dct2(I);
imshow(log(abs(M)),[]),colorbar;
title('水印能量分布');
subplot(3,3,7)
J=M(1:128,1:128);
J(128:464,128:364)=0;
J=rot90(J);
J=rot90(J);
J(465:800,365:600)=0;
J=rot90(J);
J=rot90(J);
N=N+Q*J;
K=idct2(N);
RGB(:,:,3)=K;
imshow(RGB);
title('加入水印后图像');
subplot(3,3,8)
I=imcrop(RGB,[1 1 598 798]);
imshow(I);
subplot(3,3,9)
%水印提取程序
subplot(3,3,6)
RGB1=imread('MM','jpg');
J=RGB1(:,:,3);
X=J(1:799,1:599);
N=dct2(I(:,:,3));
M=dct2(X);
M=(N-M)/Q;
B=idct2(M(337:464,237:364));
Y=mat2gray(B);
imshow(Y);
title('经放缩后提取的水印图像')
运行结果:
④ 水印全过程(经空域压缩检测水印)
程序源代码
%水印加入程序
Q=input('请输入放缩因子的值(建议小于1):Q=')
P=input('请输入您所希望的图像放缩系数值(建议取值不要小于0.5):P=')
subplot(3,3,1)
RGB=imread('南京邮电大学','jpg');
imshow(RGB);
title('原始图像');
subplot(3,3,2)
imshow(RGB(:,:,3));
title('B分量');
subplot(3,3,3)
N=dct2(RGB(:,:,3));
imshow(log(abs(N)),[]),colorbar;
title('B分量能量分布');
subplot(3,3,4)
I=imread('lena1','bmp');
imshow(I);
title('灰度水印图像');
subplot(3,3,5)
M=dct2(I);
imshow(log(abs(M)),[]),colorbar;
title('水印能量分布');
subplot(3,3,7)
J=M(1:128,1:128);
J(128:364,128:400)=0;
J=rot90(J);
J=rot90(J);
J(365:600,401:750)=0;
J=rot90(J);
J=rot90(J);
N=N+Q*J;
K=idct2(N);
RGB(:,:,3)=K;
imshow(RGB);
title('加入水印后图像');
subplot(3,3,8)
I=imresize(RGB,P,'nearest');
imshow(I);
title('压缩P倍图像');
subplot(3,3,9)
J=imresize(I,1/P,'nearest');
imshow(J);
title('再放大P倍还原图像')
%水印提取程序
subplot(3,3,6)
RGB1=imread('浙江台州学院','jpg');
N=dct2(J(:,:,3));
M=dct2(RGB1(:,:,3));
M=(N-M)/Q;
B=idct2(M(236:365,350:401));
Y=mat2gray(B);
imshow(Y);
title('经放缩后提取的水印图像'):
运行结果:
4.2 图像水印的dwt算法
%以下是水印提取算法
clear all;
clc;
%保存时间
start_time=cputime;
figure(1);
%读出原始图像
subplot(1,2,1);
input=imread('2.jpg');
imshow(input);
title('原始图像');
%读出水印图像
subplot(1,2,2);
watermarked_image=imread('watermarked.bmp');
imshow(watermarked_image,[]);
title('水印图像');
%三色分离
input=double(input);
watermarked_image=double(watermarked_image);
inputr=input(:,:,1);
watermarked_imager=watermarked_image(:,:,1);
inputg=input(:,:,2);
watermarked_imageg=watermarked_image(:,:,2);
inputb=input(:,:,3);
watermarked_imageb=watermarked_image(:,:,3);
%水印图像R的分解
[Cwr,Swr]=WAVEDEC2(watermarked_imager,2,'haar');
%图像R的分解
[Cr,Sr]=WAVEDEC2(inputr,2,'haar');
%水印图像G的分解
[Cwg,Swg]=WAVEDEC2(watermarked_imageg,2,'haar');
%图像R的分解
[Cg,Sg]=WAVEDEC2(inputg,2,'haar');
%水印图像B的分解
[Cwb,Swb]=WAVEDEC2(watermarked_imageb,2,'haar');
%图像B的分解
[Cb,Sb]=WAVEDEC2(inputb,2,'haar');
%提取水印小波系数
%提取水印R的小波系数
r=0.06;
for k=0:3
whr(k+1,:)=Cwr(1+size(Cwr,2)/4+k*size(Cwr,2)/16:...
size(Cwr,2)/4+(k+1)*size(Cwr,2)/16)-...
Cr(1+size(Cr,2)/4+k*size(Cr,2)/16:...
size(Cr,2)/4+(k+1)*size(Cr,2)/16);
wvr(k+1,:)=Cwr(1+size(Cwr,2)/2+k*size(Cwr,2)/16:...
size(Cwr,2)/2+(k+1)*size(Cwr,2)/16)-...
Cr(1+size(Cr,2)/2+k*size(Cr,2)/16:...
size(Cr,2)/2+(k+1)*size(Cr,2)/16);
wdr(k+1,:)=Cwr(1+3*size(Cwr,2)/4+k*size(Cwr,2)/16:...
3*size(Cwr,2)/4+(k+1)*size(Cwr,2)/16)-...
Cr(1+3*size(Cr,2)/4+k*size(Cr,2)/16:...
3*size(Cr,2)/4+(k+1)*size(Cr,2)/16);
end
whr=(whr(1,:)+whr(2,:)+whr(3,:)+whr(4,:))/(4*r);
wvr=(wvr(1,:)+wvr(2,:)+wvr(3,:)+wvr(4,:))/(4*r);
wdr=(wdr(1,:)+wdr(2,:)+wdr(3,:)+wdr(4,:))/(4*r);
war=(Cwr(1:size(Cwr,2)/16)-Cr(1:size(Cr,2)/16))/r;
%提取水印小波系数
%提取水印G的小波系数
g=0.03;
for k=0:3
whg(k+1,:)=Cwg(1+size(Cwg,2)/4+k*size(Cwg,2)/16:...
size(Cwg,2)/4+(k+1)*size(Cwg,2)/16)-...
Cg(1+size(Cg,2)/4+k*size(Cg,2)/16:...
size(Cg,2)/4+(k+1)*size(Cg,2)/16);
wvg(k+1,:)=Cwg(1+size(Cwg,2)/2+k*size(Cwg,2)/16:...
size(Cwg,2)/2+(k+1)*size(Cwg,2)/16)-...
Cg(1+size(Cg,2)/2+k*size(Cg,2)/16:...
size(Cg,2)/2+(k+1)*size(Cg,2)/16);
wdg(k+1,:)=Cwg(1+3*size(Cwg,2)/4+k*size(Cwg,2)/16:...
3*size(Cwg,2)/4+(k+1)*size(Cwg,2)/16)-...
Cg(1+3*size(Cg,2)/4+k*size(Cg,2)/16:...
3*size(Cg,2)/4+(k+1)*size(Cg,2)/16);
end
whg=(whg(1,:)+whg(2,:)+whg(3,:)+whg(4,:))/(4*g);
wvg=(wvg(1,:)+wvg(2,:)+wvg(3,:)+wvg(4,:))/(4*g);
wdg=(wdg(1,:)+wdg(2,:)+wdg(3,:)+wdg(4))/(4*g);
wag=(Cwg(1:size(Cwg,2)/16)-Cg(1:size(Cg,2)/16))/g;
%提取水印小波系数
%提取水印B的小波系数
b=0.12;
for k=0:3
whb(k+1,:)=Cwb(1+size(Cwb,2)/4+k*size(Cwb,2)/16:...
size(Cwb,2)/4+(k+1)*size(Cwb,2)/16)-...
Cb(1+size(Cb,2)/4+k*size(Cb,2)/16:...
size(Cb,2)/4+(k+1)*size(Cb,2)/16);
wvb(k+1,:)=Cwb(1+size(Cwb,2)/2+k*size(Cwb,2)/16:...
size(Cwb,2)/2+(k+1)*size(Cwb,2)/16)-...
Cb(1+size(Cb,2)/2+k*size(Cb,2)/16:...
size(Cb,2)/2+(k+1)*size(Cb,2)/16);
wdb(k+1,:)=Cwb(1+3*size(Cwb,2)/4+k*size(Cwb,2)/16:...
3*size(Cwb,2)/4+(k+1)*size(Cwb,2)/16)-...
Cb(1+3*size(Cb,2)/4+k*size(Cb,2)/16:...
3*size(Cb,2)/4+(k+1)*size(Cb,2)/16);
end
whb=(whb(1,:)+whb(2,:)+whb(3,:)+whb(4,:))/(4*b);
wvb=(wvb(1,:)+wvb(2,:)+wvb(3,:)+wvb(4,:))/(4*b);
wdb=(wdb(1,:)+wdb(2,:)+wdb(3,:)+wdb(4,:))/(4*b);
wab=(Cwb(1:size(Cwb,2)/16)-Cb(1:size(Cb,2)/16))/b;
%重构水印图像
cwr=[war,whr,wvr,wdr];
swr(:,1)=[sqrt(size(war,2)),sqrt(size(war,2)),2*sqrt(size(war,2))];
swr(:,2)=[sqrt(size(war,2)),sqrt(size(war,2)),2*sqrt(size(war,2))];
wr = waverec2(cwr,swr,'haar');
cwg=[wag,whg,wvg,wdg];
swg(:,1)=[sqrt(size(wag,2)),sqrt(size(wag,2)),2*sqrt(size(wag,2))];
swg(:,2)=[sqrt(size(wag,2)),sqrt(size(wag,2)),2*sqrt(size(wag,2))];
wg=waverec2(cwg,swg,'haar');
cwb=[wab,whb,wvb,wdb];
swb(:,1)=[sqrt(size(wab,2)),sqrt(size(wab,2)),2*sqrt(size(wab,2))];
swb(:,2)=[sqrt(size(wab,2)),sqrt(size(wab,2)),2*sqrt(size(wab,2))];
wb=waverec2(cwb,swb,'haar');
%将R,G,B叠加
temp=size(wr);
pic=zeros(temp(1),temp(2),3);
for i=1:temp(1);
for j=1:temp(2);
pic(i,j,1)=wr(i,j);
pic(i,j,2)=wg(i,j);
pic(i,j,3)=wb(i,j);
end
end
output=uint8(round(pic));
%转化为uint8
watermark_image_uint8=uint8(output);
imwrite(watermark_image_uint8,'watermark.bmp','bmp');
figure(2);
imshow(watermark_image_uint8);
title('提取出的水印');
原始图像
加入小波的图像
小波 提取的小波
以及二维IDCT来对图像进行处理。