一、引言
该篇包括三部分,1)引言、2)图像变化技术简介和代码实现 、3)基于图像变换技术的数字水印技术及代码实现。
数字水印是一种有效的数字产品版权保护和数据安全维护技术, 是信息隐藏领域的一个重要分支, 也是密码学的一种有益的补充技术。近年来它引起了人们的广泛关注。图像隐形水印是其中最主要的研究方向, 按照嵌入位置可分为空间域方法和变换域( DCT, DFT 和DWT 等) 方法。为了使水印信息有更好的鲁棒性(抵抗攻击的能力)众多学者采用变换域中的嵌入方法,前面我有两篇博客涉及到了有关DCT的数字水印方法和算法,接下来将分别介绍基于DCT、DFT、DWT三种基础图像变换技术的数字水印方法及代码实现。
二、DFT、DCT、DWT图像变换技术
图像变换技术是为了能让图像用正交函数或正交矩阵表示而对原图像所作的变换,该变换是二维线性可逆的。一般称原始图像为空间域图像,称变换后的图像为转换域图像(也称为频率域) ,转换域图像可反变换为空间域图像。经过图像变换后,一方面能够更有效地反映图像自身的特征,另一方面也可使能量集中在少量数据上,更有利于图像的存储、传输及处理。从数学角度来说,图像变换是把图像中的像素表达成“另外一种形式”满足实际需求,大多数情况下需要对变换处理后的图.像进行逆变换,从而获取处理以后的图像。这种变换同样可以应用于其他有关物理或数学的各种问题中,并可以采用其他形式的变量。在数字水印领域中,常用的基础图像变换技术有傅里叶变换(DFT)、离散余弦变换(DCT)、小波变换(DWT)。
2.1 图像傅里叶变换(DFT)
傅里叶变换是以时间为自变量的“信号”与频域为自变量的“频普”函数之间的某种变换关系。从纯粹的数学意义上看,傅立叶变换是将一个图像函数转换为一系列周期函数来处理的;从物理效果看,傅立叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域。实际上对图像进行二维傅立叶变换得到频谱图,就是图像梯度的分布图,傅立叶频谱图上看到的明暗不一的亮点,实际上图像上某--点与邻域点差异的强弱,即梯度的大小,也即该点的频率大小。如果频谱图中暗的点数更多,那么实际图像是比较柔和的:反之,如果频谱图中亮的点数多,那么实际图像一定是尖锐的,边界分明且边界两边像素差异较大。
傅里叶变换包括一维连续傅里叶变换、二维连续傅里叶变换、一维离散傅里叶变换、二维离散傅里叶变换。在图像处理领域中常用二维离散傅里叶变换。其定义如下式(1):
(1)
其中u = 0, 1, ... , M-1; v = 0, 1, ... , N-1 。 F(u, v)的二维离散傅里叶反变换定义为下式(2):\ (2)
图像的二维傅里叶结果通常是复数形式,故在进行图像处理的过程将结果进行平方处理,其具体的数学计算公式以及其他三种傅里叶变化的定义式可查阅《数字图像处理》——冈萨雷斯。
定义式是抽象的表达了傅里叶的变换过程,但是落实图像是怎样的呢,接下来我们用MATLAB工具进行图像的傅里叶变换。其代码及结果如下:
html
close all;
clear all;
clc;
I = imread('pepper.bmp');
J = rgb2gray(I);
K_1 = fft2(J);
L_1 = abs(K_1/256);
K_2 = fftshift(K_1);
L_2 = abs(K_2/256);
figure;
subplot(2,2,1);
imshow(I); title('原始图像');
subplot(2,2,2);
imshow(J); title('灰度图像');
subplot(2,2,3);
imshow(uint8(L_1)); title('灰度图像傅里叶频谱');
subplot(2,2,4);
imshow(uint8(L_2)); title('平移后的频谱');
其运行结果如下图:
图1 图像傅里叶变换例
2.2 离散余弦变换(DCT)
离散余弦变换(DCT)是一组不同频率和幅值的余弦函数和来近似一副图像,实际上是傅里叶变换的实数部分。由于离散余弦变量对于一副图像,其大部分可视化信息都集中在少数的变换系数上。因此,离散余弦变量是数据压缩常用的一个变换编码方法,它能将高相关数据能量集中,使得它非常适用于图像压缩,例如国际压缩标准的JPEG格式中就采用了离散余弦变换。
在傅立叶变换过程中,如果被展开的函数是实偶函数,那么其傅立叶变换中只包含余弦项,基于傅立叶变换的这一特点,人们提出了离散余弦变换。DCT变换先将图像函数变换成偶函数形式,再对其进行二维离散傅立叶变换,因此DCT变换可以看成是一种简化的傅立叶变换。离散余弦变换叶分为一维离散余弦变换和二维离散余弦变换,在图像处理中用到二维变化,所以介绍下其二维定义,其他定义可查阅《数字图像处理》——冈萨雷斯。其二维离散余弦变换定义如下式:
(3)
其中,
二维离散余弦反变换定义式:
(4)
用MATLAB工具进行图像的傅里叶变换。其代码及结果如下:
html
close all;
clear all;
clc;
I = imread ('boats.bmp');
J = dct2(I);
figure('Name','离散余弦变换');
subplot(1,2,1);
imshow(I); title('原始图像');
subplot(1,2,2);
imshow(log(abs(J))); title('离散余弦变换系数图像');
其运行结果如下图2:
图2 离散余弦变换例
2.3 小波变换(DWT)
小波变化是对傅里叶变换和短时傅里叶变换的一个突破,其改变就在于,将无限长的三角函数基换成了有限长的会衰减的小波。小波变化的理论较多,更多内容可查阅《数字图像处理》——冈萨雷斯相关章节内容,以下从一个叫简单的角度来解释小波变换。
由上图也可以看出为什么叫小波,其波形较小。
其一维连续小波的定义式为:
(5)
连续小波变换具有如下的重要性质: 线性、平移不变性、 冗余性
在 MATLAB 小波变换工具箱中提供了多个母小波族函数如下表所示,不同的母小波具有不同的特点,其对图像的处理结果也不同。
表1 小波变换母小波
``` function varargout = manit1(varargin) % MANIT1 M-file for manit1.fig % MANIT1, by itself, creates a new MANIT1 or raises the existing % singleton. % % H = MANIT1 returns the handle to a new MANIT1 or the handle to % the existing singleton. % % MANIT1('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in MANIT1.M with the given input arguments. % % MANIT1('Property','Value',...) creates a new MANIT1 or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before manit1OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to manit1OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help manit1
% Last Modified by GUIDE v2.5 14-Jun-2015 10:32:30
% Begin initialization code - DO NOT EDIT guiSingleton = 1; guiState = struct('guiName', mfilename, ... 'guiSingleton', guiSingleton, ... 'guiOpeningFcn', @manit1OpeningFcn, ... 'guiOutputFcn', @manit1OutputFcn, ... 'guiLayoutFcn', [] , ... 'guiCallback', []); if nargin && ischar(varargin{1}) guiState.gui_Callback = str2func(varargin{1}); end
if nargout [varargout{1:nargout}] = guimainfcn(guiState, varargin{:}); else guimainfcn(guiState, varargin{:}); end % End initialization code - DO NOT EDIT
% --- Executes just before manit1 is made visible. function manit1_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to manit1 (see VARARGIN)
% Choose default command line output for manit1 handles.output = hObject;
% Update handles structure guidata(hObject, handles);
% UIWAIT makes manit1 wait for user response (see UIRESUME) % uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line. function varargout = manit1_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes on button press in browsecoverimg. function browsecoverimg_Callback(hObject, eventdata, handles) % hObject handle to browsecoverimg (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname] = uigetfile({'.jpg';'.bmp';'.gif';'.*'}, 'Pick an Image File'); S = imread([pathname,filename]); S=imresize(S,[512,512]); axes(handles.axes1) imshow(S) title('Cover Image') set(handles.text3,'string',filename) handles.S=S; guidata(hObject,handles)
% --- Executes on button press in browsemsg. function browsemsg_Callback(hObject, eventdata, handles) % hObject handle to browsemsg (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname] = uigetfile({'.bmp';'.jpg';'.gif';'.*'}, 'Pick an Image File'); msg = imread([pathname,filename]); axes(handles.axes2) imshow(msg) title('Input Message') set(handles.text4,'string',filename) handles.msg=msg; guidata(hObject,handles)
% --- Executes on button press in DWT. function DWTCallback(hObject, eventdata, handles) % hObject handle to DWT (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) message=handles.msg; coverobject=handles.S; k=10; [watermrkdimg,PSNR,IF,NCC,recmessage]=dwt(coverobject,message,k); axes(handles.axes3) imshow(watermrkd_img) title('Watermarked Image') axes(handles.axes4) imshow(recmessage) title('Recovered Message') a=[PSNR,NCC,IF]'; t=handles.uitable1; set(t,'Data',a) handles.a=a; guidata(hObject,handles)
% --- Executes on button press in DWTDCT. function DWTDCTCallback(hObject, eventdata, handles) % hObject handle to DWTDCT (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) a=handles.a; message=handles.msg; coverobject=handles.S; k=10; [watermrkdimg,recmessage,PSNR,IF,NCC1] = dwtdct(coverobject,message,k); axes(handles.axes3) imshow(watermrkd_img) title('DWT+DCT Watermarked Image') axes(handles.axes4) imshow(recmessage) title('DWT+DCT Recovered Message') b=[PSNR,NCC1,IF]'; t=handles.uitable1; set(t,'Data',[a b]) handles.b=b; guidata(hObject,handles)
% --- Executes on button press in DWTDCTBFO. function DWTDCTBFOCallback(hObject, eventdata, handles) % hObject handle to DWTDCTBFO (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) a=handles.a; b=handles.b; message=handles.msg; coverobject=handles.S; [watermrkdimg,recmessage,PSNR,IF,NCC,pbest] = BG(coverobject,message); axes(handles.axes3) imshow(watermrkd_img) title('DWT+DCT+BFO Watermarked Image') axes(handles.axes4) imshow(recmessage) title('DWT+DCT+BFO Recovered Message') c=[PSNR,NCC,IF]'; t=handles.uitable1; set(t,'Data',[a b c]) handles.c=c; guidata(hObject,handles)
% --- Executes on button press in pushbutton6. function pushbutton6_Callback(hObject, eventdata, handles) % hObject handle to pushbutton6 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) a=handles.a; b=handles.b; c=handles.c; d=handles.d; PSNR=[a(1),b(1),c(1),d(1) ]; NCC=[a(2),b(2),c(2),d(2)]; IF=[a(3),b(3),c(3),d(3)]; figure bar(PSNR) set(gca,'XTickLabel',' '); ylabel('PSNR') text(1,0,'DWT','Rotation',260,'Fontsize',8); text(2,0,'DWT+DCT','Rotation',260,'Fontsize',8); text(3,0,'DWT+DCT+BFO','Rotation',260,'Fontsize',8); text(4,0,'DWT+DCT+PBFO','Rotation',260,'Fontsize',8); [t]=get(gca,'position'); set(gca,'position',[t(1) 0.31 t(3) 0.65]) title('Bar Graph Comparison of PSNR') %%%% figure bar(NCC) set(gca,'XTickLabel',' '); ylabel('NCC') text(1,0,'DWT','Rotation',260,'Fontsize',8); text(2,0,'DWT+DCT','Rotation',260,'Fontsize',8); text(3,0,'DWT+DCT+BFO','Rotation',260,'Fontsize',8); text(4,0,'DWT+DCT+PBFO','Rotation',260,'Fontsize',8); [t]=get(gca,'position'); set(gca,'position',[t(1) 0.31 t(3) 0.65]) title('Bar Graph Comparison of NCC')
% --- Executes on button press in DWTDCTPBFO. function DWTDCTPBFOCallback(hObject, eventdata, handles) % hObject handle to DWTDCTPBFO (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) a=handles.a; b=handles.b; c=handles.c; message=handles.msg; coverobject=handles.S; [watermrkdimg,recmessage,PSNR,IF,NCC,pbest] =BGPSO(coverobject,message); axes(handles.axes3) imshow(watermrkdimg) title('DWT+DCT+PBFO Watermarked Image') axes(handles.axes4) imshow(recmessage) title('DWT+DCT+PBFO Recovered Message') d=[PSNR,NCC,IF]'; t=handles.uitable1; set(t,'Data',[a b c d]) handles.d=d; guidata(hObject,handles) ```