首先读入原始图象并设置参数,然后嵌入水印信息,程序代码如下:
clear
%
%读入原图象
trueImage=imread('C:\Documents and Settings\ks001\My Documents\My Pictures\lean.tif')
alfa=.1
LENGTH=2500
subplot(2,2,1)
imshow(trueImage)
title('原始图象')
%
%对原图象进行DCT变换
dctF1=dct2('C:\Documents and Settings\ks001\My Documents\My Pictures\lean.tif')
subplot(2,2,2)
imshow(log(abs(dctF1)),[ ])
title('DCT cofficient matrix')
[m,n]=size(dctF1)
%
%产生水印序列并对其排序
radon('copyright',10)
watermark1=radon(LENGTH,1)
subplot(2,2,3)
title('watermark seqence')
[Y0,I0]=sort(watermark1)
%
%找出水印嵌入位置(幅值较大的n个频域成分)
A=dctF1(:)
[Y1,I1]=sort(A)
x=m*n
k=LENGTH
M=zeros(x,1)
%
%修改幅值较大的n个频域成分的幅值,嵌入水印(因为两个问题不同,所以有两个注释符)
for i=1:x
if k>=1
M(x)=Y1(x)*(1+alfa*Y0(k))
k=k-1
else
M(x)=Y1(x)
end
x=x-1
end
N=zeros(x,1)
x=m*n
for i=1:x
N(I1(i))=M(i)
end
a=1
for j=1:n
for i=1:m
dctF2(i,j)=N(a)
a=a+1
end
end
%
%DCT反变换,得到嵌入水印的图象
idctF1=idct2(dctF2)
subplot(2,2,4)
imshow(idctF1,[ ])
title('嵌入水印后的图象')
end
二、提取恢复水印信息的MATLAB程序
水印提取过程是水印嵌入过程的逆过程,相对嵌入过程来说比较复杂,难度较大,下面是水印提取检测的MATLAB程序代码:
function watermark_detect(image,Y1,I0,waterMark1)
%image:嵌入水印的图象
%Y1:原始图象的序列排序
%I0:原始水印的序列排序
%waterMark1:原始水印序列
%
%对嵌入水印图象进行DCT变化
dctW1=dct2(image)
%
%找出幅值较大的系数
B=dtW1(:)
[Y1,I2]=sort(B)
[m1,n1]=size(dctW1)
y=m1*n1
k=length(waterMark1)
N0=zeros(k,1)
%
%提取水印序列
while k>=1
N0(k)=(Y2(y)-Y1(y))/alfa/Y1(y)
k=k-1
y=y-1
end
k=length(waterMark1)
waterMark2=zeros(k,1)
for i=1:k
waterMark2(I0(i))=N0(i)
end
%
%选取50个测试序列,其中第10个为提取出的水印
figure
for i=150
if i==10
waterMark=waterMark2
else
waterMark=rand(k,1)
end
%计算各个序列与原来水印序列的相关值
c=waterMark'*waterMark1/sqrt(waterMark'*waterMark)
stem(i,c)
hold on
end
%
三、接下来对嵌入水印的图象进行不同的攻击,用以测试水印的鲁棒性。
程序的目的和程序代码如下:
%
%攻击实验
disp('input you choice according to the following
image processing operation:')
disp('0--exit')
disp('1--smoothing patterns')
%添加噪音
disp('2--adding uniorm noise 添加噪音')
%滤波
disp('3--adding filter [10 10] 滤波')
%剪切
disp('4--cutting part of the image 剪切')
%压缩
disp('5--10 quality JPEG compressing 压缩')
%旋转45度
disp('6--rotate 45 旋转')
%
d=input('please input you choice(请输入您的选择):')
while d~=0
switch d
case 1
watermark_detect(idctF1,Y1,I0,waterMark1)
case 2
WImage2=idctF1
noise0=10*rand(size(WImage2))
WImage2=WImage2+noise0
figure
imshow(WImage2,[ ])
title('adding uniform noise 添加噪音')
watemark_detect(WImage2,Y1,I0,waterMark1)
case 3
WImage3=idctF1
H=fspcial('gaussian高斯',[10,10],5)
WImage3=imfilter(WImage3,H)
figure
imshow(WImage3,[ ])
title(through filter [10,10] 滤波')
watemark_detect(WImage3,Y1,I0,waterMark1)
case 4
WImage4=idctF1 WImage4(1:128,1128)=256
figure
imshow(WImage4)
title('cutting part of the image 剪切')
watemark_detect(WImage4,Y1,I0,waterMark1)
case 5
WImage5=idctF1
WImage5=im2double(WImage5)
cnum=10
dctm=dctmtx(8)
p1=dctm
p2=dctm.'
imageDCT=blkproc(WImage5,[8,8],'p1*p2*x',dctm,dctm.')
DCTvar=im2col(imageDCT,[8,8],'distinct').'
n=size(DCTvar,1)
DCTvar=(sum(DCTvar.*DCTvar)-(sum(DCTvar)/n).^2)/n
[dum,order]=sort(DCTvar)
cnum=64-cnum
mask=ones(8,8)
mask(order(1:cnum))=zeros(1,cnum)
im88=zeros(9,9)
im88(1:8,1:8)=mask
im128128=kron(im88(1:8,1:8),ones(16))
dctm=dctmtx(8)
p1=dctm.'
p2=mask(18,1:8)
p3=dctm
Wimage5=bikproc(imageDCT,[8,8],'p1*(x.8p2)*p3',dctm.',mask(1:8,1:8),dctm)
figure
imshow(Wimage5)
title('JPEG Image 压缩')
watemark_detect(WImage5,Y1,I0,waterMark1)
case 6 WImage6=idctF1
WImage6=imrotate(WImage6,45,'bilinear','corp')
figure
imshow(Wimage6)
title('rotate 45 旋转')
watemark_detect(WImage6,Y1,I0,waterMark1)
case 0
break
otherwise
error('you have a valid value(您的输入错误)')
end
d=input('please input you choice(请输入您的选择):')
end
%结束
首先,不知道你会不会用Matlab。如果,你会用,应该有一个简单的DWT水印嵌入程序了。
读取图片,DWT变换着都不用说了吧?
有个不太明白的地方,就是,预处理是在什么时候做? 在原图片上做完后,在做DWT变换后嵌入?
那么,这个字符串的信息量与原图信息量一样多。水印效果就。。。。。。
如果要嵌入,也要与原图一样,做DWT变换。不然,嵌入信息太多了。如果这样做了,就和后一种嵌入方法一样了。
也就是,先做DWT变换,假设最后DWT变换后的4个图片为A,B,C,D.
A图不动,B和C可嵌入,D图压缩就没了.所以,A图做直方图处理,然后与水印一起嵌入到,B和C图.
你要求里面,直方图压缩到[N,255-N]。N=G/2 ?
直方图灰度范围[N,255-N],我们设定 :
Oimg=A图;
WMKimg=水印;
Zimg=直方图调整后的图片;%% 也就是说,色数范围是[ N, 255-N] .
也就是说,[0,255]的图片,现在要用[N,255]的灰色度来显示。(这个直方图变化直接可以做出来)
分析到这里之后,就比较容易了。
Wimg=Oimg与Zimg差值矩阵。
然后,Wimg和WMKimg按照随机密钥做处理,嵌入就可以了
最上面的是A图.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)