基于离散傅里叶变换(DFT)的数字水印算法研究

目 录
1 绪论 1
1.1 本文研究的背景及意义 1
1.2 数字水印的国内外研究现状 1
1.3 本文的研究主要内容 2
2 数字水印技术概述 3
2.1 数字水印的基本特点 3
2.2 数字水印的分类 4
2.3 数字水印的鲁棒性问题与攻击行为 5
2.4 数字水印的主要应用领域 6
2.5 数字水印的评价标准 7
3 傅立叶域水印理论基础 9
3.1 傅立叶变换简述 9
3.1.1 一维离散傅立叶变换 9
3.1.2 快速傅立叶变换 10
3.1.3 二维离散傅立叶变换 11
3.2 傅立叶变换性质 12
3.2.1 空间域平移性 12
3.2.2 旋转不变性 12
3.2.3 比例缩放性 13
4 数字图像水印算法的MATLAB 实现 14
4.1数字水印的嵌入 14
4.2数字水印的提取 14
4.3实验结果 15
5 总结与展望 17
参考文献 18
致 谢 20
数字水印是一种有效的数字产品版权保护和数据安全维护技术, 是信息隐藏领域的一个重要分支,也是密码学的一种有益的补充技术。近年来它引起了人们的广泛关注。本课题主要研究基于离散傅里叶变换(DFT)的数字水印算法,通过Matlab软件仿真实现数字图像水印的嵌入和提取。
傅里叶变换是以时间为自变量的“信号”与频域为自变量的“频普”函数之间的某种变换关系。从纯粹的数学意义上看,傅立叶变换是将一个图像函数转换为一系列周期函数来处理的;从物理效果看,傅立叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域。实际上对图像进行二维傅立叶变换得到频谱图,就是图像梯度的分布图,傅立叶频谱图上看到的明暗不一的亮点,实际上图像上某–点与邻域点差异的强弱,即梯度的大小,也即该点的频率大小。如果频谱图中暗的点数更多,那么实际图像是比较柔和的:反之,如果频谱图中亮的点数多,那么实际图像一定是尖锐的,边界分明且边界两边像素差异较大。
4 数字图像水印算法的MATLAB 实现
4.1数字水印的嵌入
下面是利用MATLAB实现数字水印嵌入的步骤:
Step0.设置嵌入强度系数,滤波矩阵,分块大小并保存开始时间。
Step1.读入原始图像cover_object,并读出其尺寸为。
Step2.读入水印图像message,并读出其尺寸为。
Step3.对message进行Arnold置乱,并将置乱后水印图像重新排列为向量message_vector。
Step4.检查水印信息是否过大,如果水印信息过大返回错误信息,“水印信息过大”。
Step5.设置伪随机密钥key,并按照滤波矩阵的1的个数,生成两个不相关的伪随机序列pn_sequence_one,pn_sequence_zero。
Step6.对原始图像进行8×8分块,并对每一分块进行二维傅立叶变换。将低频部分移至中间,计算幅值与相位。如果水印向量元素为零,则将pn_sequence_zero嵌入滤波矩阵为1处所对应的幅值。本文转载自http://www.biyezuopin.vip/onews.asp?id=14251如果水印向量元素为零,则将pn_sequence_one嵌入滤波矩阵为1处所对应的幅值。
Step7.对每一分块进行二维傅立叶逆变换,将图像变换回空域。
Step8.将嵌入水印图像保存,计算运行时间,计算psnr值,显示水印、嵌入水印图像与原始图像。
4.2数字水印的提取
水印提取算法不需要原始图像,但需要原始水印的部分信息(原始水印的尺寸)。下面是水印提取的步骤:
Step0.设置滤波矩阵,分块大小并保存开始时间。
Step1.读入嵌入水印图像watermarked_image,并读出其尺寸为。
Step2.读入原始水印图像orig_watermark,并读出其尺寸为。
Step3.设置与嵌入算法中相同的伪随机密钥key,并按照滤波矩阵的1的个数,生成两个不相关的伪随机序列pn_sequence_one,pn_sequence_zero。
Step4.对嵌入水印图像进行8×8分块,并对每一块进行二维傅立叶变换.将低频部分移至中间,计算幅值。
Step5.分别计算pn_sequence_one,pn_sequence_zero与幅值的相关性,如果pn_sequence_zero与幅值的相关性大于pn_sequece_one与幅值的相关性,那么将提取水印向量message_vector赋‘0’,反之赋‘1’。
Step6.将提取水印向量进行Arnold置乱,并按原始水印尺寸排列。
Step7.计算运行时间,显示提取水印与原始水印。

%基于傅立叶域的数字水印
%注意:水印必须为40*40的二值图像 
%因为40阶的二维arnold置乱周期为30,所以嵌入时置乱8次,提取时置乱22.可以根据自己的需要更改.
%嵌入源码
clc
clear all;

% 保存开始时间
start_time=cputime;
iTimes=8;      %置乱次数
k=1.1;                           % 设置嵌入强度系数
blocksize=8;                    % 块的大小

filter_m=[  1,1,1,1,1,1,1,1;    % 滤波矩阵
            1,1,1,1,1,1,1,1;
            1,1,0,0,0,0,1,1;
            1,1,0,0,0,0,1,1;
            0,0,0,0,0,0,0,0;
            0,0,0,0,0,0,0,0;
            0,0,0,0,0,0,0,0;
            0,0,0,0,0,0,0,0;];
        
% 读入原始图像
file_name='_lena_std_bw.bmp';
cover_object=double(imread(file_name))/255;

% 原始图像矩阵的行数与列数
Mc=size(cover_object,1);	        
Nc=size(cover_object,2);	       

% 最大嵌入信息量
max_message=Mc*Nc/(blocksize^2);

% 读入水印图像
file_name='watermark.bmp';
message=double(imread(file_name));
%水印图像矩阵的行数与列数
Mm=size(message,1);	                
Nm=size(message,2);	                


% 检查水印信息是否过大
if  Mm*Nm>max_message
   error('水印信息过大')
end

%对水印图像进行Arnold置乱
if Mm~=Nm
    error('水印矩阵必须为方阵');
end
if Mm~=40
    error('必须为40*40大小,或者修改置乱次数');
end
tempImg=message;
for n=1:iTimes % 次数
    for u=1:Mm
        for v=1:Nm
          temp=tempImg(u,v);
          ax=mod(u+v,Mm)+1;
          ay=mod(u+2*v,Nm)+1;
          outImg(ax,ay)=temp;
        end
    end
  tempImg=outImg;
end
message_vector=reshape(outImg,1,Mm*Nm);


% 将cover_object(原图矩阵)写入watermarked_image
watermarked_image=cover_object;

%置随机数发生器的状态为1100
key=1100;
rand('state',key);

% 产生伪随机序列
pn_sequence_zero=round(2*(rand(1,sum(sum(filter_m)))-0.5));
pn_sequence_one=round(2*(rand(1,sum(sum(filter_m)))-0.5));   
% 将图像分块
x=1;
y=1;

h=waitbar(0,'嵌入水印,请等待');
for (kk = 1:length(message_vector))

    % 做傅立叶变换
    fft_block=fft2(cover_object(y:y+blocksize-1,x:x+blocksize-1));
    %计算幅值
    abs_block=fftshift(abs(fft_block));
    %计算相位
    angle_block=angle(fft_block);
    % 当message_vector=0且filter_m=1时用伪随机序列pn_sequence_zero叠加abs_block
    % 当message_vector=1且filter_m=1时用伪随机序列pn_sequence_one叠加abs_block
    ll=1;
    if (message_vector(kk)==0)
        for ii=1:blocksize
            for jj=1:blocksize
                if (filter_m(ii,jj)==1)
                    abs_block_o=abs_block(ii,jj);
                    abs_block(ii,jj)=abs_block(ii,jj)*(1+k*pn_sequence_zero(ll));
  abs_block(blocksize-ii+1,blocksize-jj+1)=abs_block(blocksize-ii+1,blocksize-jj+1)+abs_block(ii,jj)-abs_block_o;
                    ll=ll+1;
                end
            end
        end
    else                                     
        for ii=1:blocksize                    
            for jj=1:blocksize
                if (filter_m(ii,jj)==1)
                    abs_block_o=abs_block(ii,jj);
                    abs_block(ii,jj)=abs_block(ii,jj)*(1+k*pn_sequence_one(ll));
  abs_block(blocksize-ii+1,blocksize-jj+1)=abs_block(blocksize-ii+1,blocksize-jj+1)+abs_block(ii,jj)-abs_block_o;
                    ll=ll+1;
                end
            end
        end
    end
    
    % 进行傅立叶逆变换
    abs_block=fftshift(abs_block);
    watermarked_image(y:y+blocksize-1,x:x+blocksize-1)=abs(ifft2(abs_block.*exp(i*angle_block)));    
    
    % 移动到下一块
    if (x+blocksize) >= Nc
        x=1;
        y=y+blocksize;
    else
        x=x+blocksize;
    end
    waitbar(kk/length(message_vector),h);
end
close(h);

% 转换为uint8,并写入
watermarked_image_int=uint8(watermarked_image*255);
imwrite(watermarked_image_int,'dft2_watermarked.bmp','bmp');

% 计算运行时间
elapsed_time=cputime-start_time,

% 计算psnr
PSNR=psnr(cover_object,watermarked_image),

% 显示水印,嵌入水印图像与原始图像
figure(1)
subplot(1,2,1)
imshow(message,[]);
title('原始水印');
subplot(1,2,2);
imshow(tempImg,[]);
title('置乱水印');
figure(2)
subplot(1,2,1)
imshow(watermarked_image,[]);
name='嵌入水印图像';
title(strcat(num2str(name),'   k=',num2str(k),'   PSNR=',num2str(PSNR)));
subplot(1,2,2)
imshow(cover_object,[])
title('原始图像');


基于离散傅里叶变换(DFT)的数字水印算法研究_第1张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第2张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第3张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第4张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第5张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第6张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第7张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第8张图片
基于离散傅里叶变换(DFT)的数字水印算法研究_第9张图片

你可能感兴趣的:(算法,计算机视觉,matlab,离散傅里叶变换,DFT)