global I ; global W; global P; global Iw; ntimes=23; % 秘钥1,Arnold置乱次数 rngseed=59433; % 秘钥2,随机数种子 flag=1; %是否显示图像,0 不显示,1 显示
嵌入水印模块:setdwtwatermark.m
matlabfunction [Iw,psnr]=setdwtwatermark(I,W,ntimes,rngseed,flag) %基于小波变换数字水印嵌入 %I:载体图像,灰度图 %W:水印图像,二值图,且长宽相等 %ntimes: 秘钥1,Arnold置乱次数 I=imcrop(I,[00size(I,2) size(I,1)-1]); type=class(I); I=double(I); W=logical(W); [mI,nI]=size(I); [mW,nW]=size(W); if mW~=nW error('SETDWTWATERMARK:ARNOLD','ARNOLD置乱要求水印图像长宽必须相等!') end [ca1,ch1,cv1,cd1]=dwt2(I,'haar'); [ca2,ch2,cv2,cd2]=dwt2(ca1,'haar'); if flag figure('Name','载体小波分解') subplot(121) imagesc([wcodemat(ca1),wcodemat(ch1);wcodemat(cv1),wcodemat(cd1)]) title('一级小波分解') subplot(122) imagesc([wcodemat(ca2),wcodemat(ch2);wcodemat(cv2),wcodemat(cd2)]) title('二级小波分解') end Wa=W; H=[1,1;1,2]^ntimes; fori=1:nW forj=1:nW idx=mod(H*[i-1;j-1],nW)+1; Wa(idx(1),idx(2))=W(i,j); end end flag=1; if flag figure('Name','水印置乱与嵌入') subplot(221) imshow(W) title('原始水印') subplot(222) imshow(Wa) title(['置乱水印,变换次数=',num2str(ntimes)]); end %数字水印嵌入 ca2w=ca2; rng(rngseed); idx=randperm(numel(ca2),numel(Wa)); fori=1:numel(Wa) c=ca2(idx(i)); z=mod(c,nW); if Wa(i) if z<nW/4 f=c-nW/4-z; else f=c+nW*3/4-z; end else if z<nW*3/4 f=c+nW/4-z; else f=c+nW*5/4-z; end end ca2w(idx(i))=f; end ca1w=idwt2(ca2w,ch2,cv2,cd2,'haar'); Iw=idwt2(ca1w,ch1,cv1,cd1,'haar'); Iw=Iw(1:mI,1:nI); mn=numel(I); Imax=max(I(:)); psnr=10*log10(mn*Imax^2/sum((I(:)-Iw(:)).^2)); I=cast(I,type); Iw=cast(Iw,type); if flag subplot(223) imshow(I); title('原始图像') subplot(224); imshow(Iw); title(['添加水印,PSNR=',num2str(psnr)]); end
提取水印模块:getdwtwatermark.m
function[Wg,nc]=getdwtwatermark(Iw,W,P,ntimes,rngseed,flag) [mW,nW]=size(W); if mW~=nW error('GETDWTWATERMARK:ARNOLD','ARNOLD置乱要求水印图像长宽必须相等!') end Iw=double(Iw); W=logical(W); ca1w=dwt2(Iw,'haar'); ca2w=dwt2(ca1w,'haar'); Wa=W; rng(rngseed); idx=randperm(numel(ca2w),numel(Wa)); fori=1:numel(Wa) c=ca2w(idx(i)); z=mod(c,nW); if z<nW/2 Wa(i)=0; else Wa(i)=1; end end Wg=Wa; H=[2-1;-1,1]^ntimes; fori=1:nW forj=1:nW idx=mod(H*[i-1;j-1],nW)+1; Wg(idx(1),idx(2))=Wa(i,j); end end nc=sum(Wg(:).*W(:))/sqrt(sum(Wg(:).^2))/sqrt(sum(W(:).^2)); flag=1; if flag figure('Name','数字水印提取结果') subplot(121) W=imcrop(W,[00size(P,2) size(P,1)]); imshow(W) title('原始水印') subplot(122) Wg=imcrop(Wg,[00122107]); imshow(Wg) title(['提取水印,NC=',num2str(nc)]); end
GUI 调用模块 watermatk.m
functionvarargout = watermark(varargin) gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @watermark_OpeningFcn, ... 'gui_OutputFcn', @watermark_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end functionwatermark_OpeningFcn(hObject, eventdata, handles, varargin) movegui( hObject,'center' ); handles.output = hObject;%移动窗口到屏幕中心 guidata(hObject, handles); functionvarargout = watermark_OutputFcn(hObject, eventdata, handles) varargout{1} = handles.output % --- Executes on button press in pushbutton1. functionpushbutton1_Callback(hObject, eventdata, handles) main [filename pathname]=uigetfile({'*.jpg;*.bmp';'*.*'},'请选择底图文件'); %%打开图像 I=imread(filename); %读取原始图像 [filename pathname]=uigetfile({'*.png;*.tif';'*.*'},'请选择水印文件'); helpdlg('选择完毕,您可点击查看以确认是否需要重新选择','提示'); I = rgb2gray(I);%转换为灰度图 W = imread(filename);%读取水印图像 if strcmp(filename(end-3:end),'tif') W= rgb2gray(W); W=imbinarize(W);%转化成二值图像 end P=W; Mm=size(W,1); %水印的行数 Nm=size(W,2); %水印的列数 %将图像扩展为长宽相等 if Mm<Nm Max=Nm; Min=Mm; fori=Min:Max forj=1:Max W(i,j)=1; end end else Max=Mm; Min=Nm; fori=1:Max forj=Min:Max W(i,j)=1; end end end functionpushbutton2_Callback(hObject, eventdata, handles) main figure('Name','载体图像与水印图像') subplot(211); imshow(I); title('载体图像') subplot(212); imshow(P); title('水印图像') functionpushbutton3_Callback(hObject, eventdata, handles) main [Iw,psnr]=setdwtwatermark(I,W,ntimes,rngseed,0); functionpushbutton4_Callback(hObject, eventdata, handles) main [Wg,nc]=getdwtwatermark(Iw,W,P,ntimes,rngseed,0);