小波数字水印

https://blog.csdn.net/weixin_39707121/article/details/79407070

https://www.jiamisoft.com/blog/2914-shuzishuiyinjiamisuanfa.html

%
% 音频水印技术 教学版演示程序
%
% 车生兵 著
%
% 采用一级小波变换低频系数量化嵌入方式
%
% 变量说明:
%
% delt:  量化步长;   w:      水印图像;   rem:    量化后余数;
% p:      攻击概率;   w1:     提取水印;   LL1:   调整后的低频量化系数;
% I0:    原始音频;   I1:    载体音频;   I11:   嵌入水印后的局部块;
% [m,n]:  水印尺寸;   n0:     量化系数;   p:      攻击概率;
% [LL LH HL HH]: 小波变换后得到的低频、中频、高频系数;
%
% Step 1: 数据准备
delt=2;                 %选取大规模实验获得的最佳值
p=0.5;                  %选取大规模实验获得的最佳值

[Y,fs,nbits]=wavread('oriaud.wav');
Y1=Y;
tmp1=(Y(1:256*256,1)+1)*128;
I0=reshape(tmp1,256,256);

I1=I0;                  %载体音频初始值
w=imread('w.bmp');      %获取水印图像
[m,n]=size(w);          %获取水印图像的尺寸
% Step 2: 水印嵌入
for i=1:1:m                                 %按照从上到下,从左至右顺序嵌入水印信息
    for j=1:1:n
        I=I0(2*i-1:2*i,2*j-1:2*j);          %获取嵌入w(i,j)水印值的原始图像块I
        [LL,LH,HL,HH]=dwt2(I,'haar');       %获得haar小波变化系数
        n0=floor(LL/delt);                  %获得小波变换低频系数的量化系数
        rem=LL-n0*delt;                     %获得小波变换低频系数量化后的余数
        if (mod(n0,2)==w(i,j))              %判断:量化系数与待嵌入水印系数的奇偶性是否吻合?
            LL1=n0*delt+p*delt;             %吻合:量化系数不变,调整低频系数值
        else                                %不吻合:量化系数修改
            if(rem>p*delt)                  %判断:余数大于攻击最佳调整值p*delt?
                LL1=(n0+1)*delt+p*delt;     %是:量化系数增加1,调整低频系数值
            else
                LL1=(n0-1)*delt+p*delt;     %否:量化系数减少1,调整低频系数值
            end
        end
        I11=idwt2(LL1,LH,HL,HH,'haar');     %逆小波变换,获得初始载体数据
        I1(2*i-1:2*i,2*j-1:2*j)=I11;        %获得整形后的载体数据,这里是用round()进行整形
    end
end
% Step 3:提取水印
[M,N]=size(I1);     %获得载体音频尺寸
m=M/2;              %计算提取水印图像行数
n=N/2;              %计算提取水印图像列数
w1=w;               %提取水印图像赋初始值
for i=1:1:m         %按照从上到下,从左至右顺序提取水印信息
    for j=1:1:n
        I=I1(2*i-1:2*i,2*j-1:2*j);      %获取载体数据块
        [LL,LH,HL,HH]=dwt2(I,'haar');   %做haar小波变换
        n0=floor(LL/delt);              %提取量化系数
        if (mod(n0,2)==0)               %判断:量化系数奇偶性是否为0?
            w1(i,j)=0;                  %是:提取出的水印值为0
        else
            w1(i,j)=1;                  %否:提取出的水印值为1
        end
    end
end
% Step 4:显示结果
tmp1=(I1./128-1);
Y1(1:256*256,1)=reshape(tmp1,256*256,1);
imwrite(w1,'w1.bmp');
wavwrite(Y1,fs,nbits,'embeded.wav');

figure,subplot(2,2,1);plot(Y);title('原始音频');
subplot(2,2,2);plot(Y1);title('载体音频');
subplot(2,2,3);imshow(w);title('水印图像');
subplot(2,2,4);imshow(w1);title('提取水印');
% 程序结束
%
% 视频水印 演示程序
%
% 车生兵 著
%
% 截取视频中的图像
clc;
clear;
close all;
% 将电影转成图片序列 
mov=aviread('avi\search.avi'); 
fi = AVIINFO('avi\search.avi');
% [m,n]=size(mov(1).cdata);
fnum=size(mov,2);                                           % 读取电影的帧数,“2”表示返回的为列数
for i=1:fnum 
     strtemp_rgb=strcat('oringalframe\',int2str(i),'.bmp'); % 将每帧转成bmp的图片
     imwrite(mov(i).cdata,mov(i).colormap,strtemp_rgb);     % 写入真彩图像
end
%
% 把Index类型图像转换成RGB图像
%
for i=1:fnum 
     strtemp_rgb=strcat('oringalframe\',int2str(i),'.bmp'); % 将每帧转成bmp的图片
     strtemp_rgb1=strcat('rgbframe\',int2str(i),'.bmp');    % 将每帧转成bmp的图片
     [X,MAP]=imread(strtemp_rgb);
     RGB = ind2rgb(X,MAP);
     imwrite(RGB,strtemp_rgb1);                             % 写入真彩图像
end
% 创建文件夹
% 文件夹"FlowerGarden_rgb_embed"存放写入了水印的视频帧图像
mkdir('rgb_embed');
copyfile('rgbframe','rgb_embed');
% 设置用来选择待嵌入视频帧keyframe的随机数key,注意,关键帧的选择要随机,而且1<=key<=fi.NumFrames
key=5;
strtemp_rgb2=strcat('rgb_embed\',int2str(key),'.bmp');
keyframe=imread(strtemp_rgb2);
I0=rgb2ycbcr(keyframe);
[m,n]=size(I0(:,:,1));
%
I11=I0(:,:,1);
%
% Step 1: 数据准备
delt=12;                %选取大规模实验获得的最佳值
p=0.5;                  %选取大规模实验获得的最佳值
I1=I11;                 %载体图像初始值
w=imread('w.bmp');      %获取水印图像
[m,n]=size(w);          %获取水印图像的尺寸
% Step 2: 水印嵌入
for i=1:1:m                                 %按照从上到下,从左至右顺序嵌入水印信息
    for j=1:1:n
        I=I0(2*i-1:2*i,2*j-1:2*j);          %获取嵌入w(i,j)水印值的原始图像块I
        [LL,LH,HL,HH]=dwt2(I,'haar');       %获得haar小波变化系数
        n0=floor(LL/delt);                  %获得小波变换低频系数的量化系数
        rem=LL-n0*delt;                     %获得小波变换低频系数量化后的余数
        if (mod(n0,2)==w(i,j))              %判断:量化系数与待嵌入水印系数的奇偶性是否吻合?
            LL1=n0*delt+p*delt;             %吻合:量化系数不变,调整低频系数值
        else                                %不吻合:量化系数修改
            if(rem>p*delt)                  %判断:余数大于攻击最佳调整值p*delt?
                LL1=(n0+1)*delt+p*delt;     %是:量化系数增加1,调整低频系数值
            else
                LL1=(n0-1)*delt+p*delt;     %否:量化系数减少1,调整低频系数值
            end
        end
        I11=idwt2(LL1,LH,HL,HH,'haar');     %逆小波变换,获得初始载体数据
        I1(2*i-1:2*i,2*j-1:2*j)=round(I11); %获得整形后的载体数据,这里是用round()进行整形
    end
end
% Step 3:提取水印
% 应该从载体视频帧中获取嵌入帧数据,在这里直接从嵌入程序中直接获取,由于写入质量fi.Quality为100,所以从载体视频中读取出来也是一样的
[M,N]=size(I1);     %获得载体图像尺寸
m=M/2;              %计算提取水印图像行数
n=N/2;              %计算提取水印图像列数
w1=w;               %提取水印图像赋初始值
for i=1:1:m         %按照从上到下,从左至右顺序提取水印信息
    for j=1:1:n
        I=I1(2*i-1:2*i,2*j-1:2*j);      %获取载体数据块
        [LL,LH,HL,HH]=dwt2(I,'haar');   %做haar小波变换
        n0=floor(LL/delt);              %提取量化系数
        if (mod(n0,2)==0)               %判断:量化系数奇偶性是否为0?
            w1(i,j)=0;                  %是:提取出的水印值为0
        else
            w1(i,j)=1;                  %否:提取出的水印值为1
        end
    end
end
% Step 4:显示结果
imwrite(w1,'w1.bmp');
figure,subplot(1,2,1);imshow(w);title('水印图像');
subplot(1,2,2);imshow(w1);title('提取水印');
%
%I12(:,:,1)=I11;
I12(:,:,1)=I1;
I12(:,:,2)=I0(:,:,2);
I12(:,:,3)=I0(:,:,3);
I1=ycbcr2rgb(I12);
%  写入嵌入水印的帧
imwrite(I1,strtemp_rgb2);
% 将嵌入水印的视频帧序列转换成avi视频
% 定义一个avi文件
aviobj=avifile('avi\rgb_embed.avi'); 
aviobj.Quality =fi.Quality;
aviobj.compression='None';
aviobj.colormap=gray(256);
aviobj.Fps=fi.FramesPerSecond;
% 使用addframe把图片写入视频
for i=1:fnum
    picdata=imread(strcat('rgb_embed','\',num2str(i),'.bmp')); % 获得一帧图像
    aviobj=addframe(aviobj,uint8(picdata));                    % 加到电影剪辑文件中
end
aviobj=close(aviobj); % 关闭文件,结束数值仿真模拟过程
%
% 数字图像水印技术 教学版演示程序
%
% 车生兵 著
%
% 采用一级小波变换低频系数量化嵌入方式
%
% 变量说明:
%
% delt:  量化步长;   w:      水印图像;   rem:    量化后余数;
% p:      攻击概率;   w1:     提取水印;   LL1:   调整后的低频量化系数;
% I0:    原始图像;   I1:    载体图像;   I11:   嵌入水印后的局部块;
% [m,n]:  水印尺寸;   n0:     量化系数;   p:      攻击概率;
% [LL LH HL HH]: 小波变换后得到的低频、中频、高频系数;
%
% Step 1: 数据准备
delt=12;                %选取大规模实验获得的最佳值
p=0.5;                  %选取大规模实验获得的最佳值
II=imread('lena.jpg');  %获取原始图像
I0=rgb2gray(II);        %只对灰度图像做水印嵌入与提取
I1=I0;                  %载体图像初始值
w=imread('w.bmp');      %获取水印图像
[m,n]=size(w);          %获取水印图像的尺寸
% Step 2: 水印嵌入
for i=1:1:m                                 %按照从上到下,从左至右顺序嵌入水印信息
    for j=1:1:n
        I=I0(2*i-1:2*i,2*j-1:2*j);          %获取嵌入w(i,j)水印值的原始图像块I
        [LL,LH,HL,HH]=dwt2(I,'haar');       %获得haar小波变化系数
        n0=floor(LL/delt);                  %获得小波变换低频系数的量化系数
        rem=LL-n0*delt;                     %获得小波变换低频系数量化后的余数
        if (mod(n0,2)==w(i,j))              %判断:量化系数与待嵌入水印系数的奇偶性是否吻合?
            LL1=n0*delt+p*delt;             %吻合:量化系数不变,调整低频系数值
        else                                %不吻合:量化系数修改
            if(rem>p*delt)                  %判断:余数大于攻击最佳调整值p*delt?
                LL1=(n0+1)*delt+p*delt;     %是:量化系数增加1,调整低频系数值
            else
                LL1=(n0-1)*delt+p*delt;     %否:量化系数减少1,调整低频系数值
            end
        end
        I11=idwt2(LL1,LH,HL,HH,'haar');     %逆小波变换,获得初始载体数据
        I1(2*i-1:2*i,2*j-1:2*j)=round(I11); %获得整形后的载体数据,这里是用round()进行整形
    end
end
% Step 3:提取水印
[M,N]=size(I1);     %获得载体图像尺寸
m=M/2;              %计算提取水印图像行数
n=N/2;              %计算提取水印图像列数
w1=w;               %提取水印图像赋初始值
for i=1:1:m         %按照从上到下,从左至右顺序提取水印信息
    for j=1:1:n
        I=I1(2*i-1:2*i,2*j-1:2*j);      %获取载体数据块
        [LL,LH,HL,HH]=dwt2(I,'haar');   %做haar小波变换
        n0=floor(LL/delt);              %提取量化系数
        if (mod(n0,2)==0)               %判断:量化系数奇偶性是否为0?
            w1(i,j)=0;                  %是:提取出的水印值为0
        else
            w1(i,j)=1;                  %否:提取出的水印值为1
        end
    end
end
% Step 4:显示结果
imwrite(w1,'w1.bmp');
imwrite(I1,'I1.bmp');
figure,subplot(2,2,1);imshow(I0);title('原始图像');
subplot(2,2,2);imshow(I1);title('载体图像');
subplot(2,2,3);imshow(w);title('水印图像');
subplot(2,2,4);imshow(w1);title('提取水印');
% 程序结束
 

% 水印嵌入过程

I=rgb2gray(imread('lena.jpg'));
W=imread('water.bmp');
[m,n]=size(I);
[h,l]=size(W);
delta=12.0;
n=0.0;
rem=0.0;
p=0.5;
I1=I;
for (i=1:1:h)
    for (j=1:1:l)
        I0=double(I(((i-1)*2+1):(i*2),((j-1)*2+1):(j*2)));
        [LL LH HL HH]=dwt2(I0,'haar');
        n=floor(LL/delta);
        rem=mod(LL,delta);
        if (W(i,j)==mod(n,2))
            LL1=n*delta+p*delta;
        else
            if (rem>p*delta)
                LL1=(n+1)*delta+p*delta;
                if (LL1>(510-delta))
                    LL1=(n-1)*delta+p*delta;
                end
            else
                LL1=(n-1)*delta+p*delta;
                if (LL1<delta)
                    LL1=(n+1)*delta+p*delta;
                end
            end
        end
        I01=idwt2(LL1,LH,HL,HH,'haar');
        I11=floor(I01);
        I12=mod(I01,1);
        xsh=round(sum(sum(I12)));
        
        xx=reshape(I11,1,4);
        [yy,ii]=sort(xx);
        max=4;
        for (r=xsh:-1:1)
            for (s=1:1:4)
                if (ii(1,s)==max)
                    break;
                end
            end
            xx(1,s)=xx(1,s)+1;
            max=max-1;
        end
        
        xxx=reshape(xx,2,2);
        I1(((i-1)*2+1):(i*2),((j-1)*2+1):(j*2))=xxx;
    end
end
I1=uint8(I1);
imwrite(I,'lena.bmp');
imwrite(I1,'embded.bmp');
figure,subplot(2,2,1),imshow(I);title('Original');
subplot(2,2,2),imshow(I1);title('Embeded');
subplot(2,2,3),imshow(W);title('Water');



% 水印提取过程

x=imread('lena.jpg');
I=imread('embded.bmp');
W=imread('water.bmp');
[m,n]=size(I);
[h,l]=size(W);
delta=12.0;
n=0.0;
p=0.5;
W1=W;
for (i=1:1:h)
    for (j=1:1:l)
        I0=double(I(((i-1)*2+1):(i*2),((j-1)*2+1):(j*2)));
        [LL LH HL HH]=dwt2(I0,'haar');
        n=floor(LL/delta);
        W1(i,j)=mod(n,2);
    end
end
figure,subplot(2,2,1),imshow(x);title('Original');
subplot(2,2,2),imshow(I);title('Embeded');
subplot(2,2,3),imshow(W);title('Water');
subplot(2,2,4),imshow(W1);title('Extract');