阅读 28

【图像隐写】基于matlab GUI DWT+SVD数字水印 【含Matlab源码 939期】

一、简介

随着互联网普及,信息通讯技术的飞速发展,多媒体技术得到了充分的应用。但是开放的互联网使这些多媒体信息的传输变得不安全,而数字水印技术恰恰能保护这些多媒体信息的传输。数字水印技术通过一定的嵌入算法将一些可以用来标识多媒体数据的来源、版本、作者等标志性信息嵌入到多媒体数据中来保护多媒体数据的版权,但是不影响原始数据的使用和价值,并且不易被人察觉 。根据嵌入位置的不同,数字水印算法分为空域和变换域水印算法。一般而言,变换域水印算法稳健性较好,主要的变换域有离散余弦变换 ( discrete cosine transform DCT)、离散小波变换 ( discrete wavelet transform DWT)和离散傅立叶变换 ( discrete fourier transform DFT)。在变换域中奇异值分解(singular value decomposition SVD) 是一种将矩阵对角化的方法。图像的奇异值有较好的稳定性,利用这个原理可将水印信息嵌入到图像经过奇异值变换后的系数。
1 离散余弦变换和奇异值分解
1.1 离散余弦变换
离散余弦变换(Discrete Cosine Transform, DCT)是 一组不同 频率和幅值的余弦函数和来近似衣服图像,实际上是傅里叶变换的实数部分。由于离散余弦变量对于衣服图像,其大部分可视化信息都集中在少数的变换系数上。因此,离散余弦变量是数据压缩常用的一个变换编码方法,它能将高相关数据能量集中,使得它非常适用于图像压缩。一维离散信号f(x) 的离散余弦正变换为:
在这里插入图片描述
二维离散信号 f(x) 的离散余弦正变换为:
在这里插入图片描述
1.2 奇异值分解( SVD)

矩阵经过SVD 分解得到 1个奇异值矩阵 2个正交矩阵。图像的奇异值有很强的稳定性,图像受到轻微的扰动时不会有显著改变。利用奇异值的这种特性,如果将水印嵌入在载体图像 SVD 分解后的奇异值上,当攻击者对含水印图像进行攻击扰乱时,我们仍能从分解的奇异值中提取出水印信息。并且,奇异值对应于图像的亮度特性,而非视觉特性,因此,在奇异值上嵌入水印能保证水印的透明性,保障了水印算法的隐蔽性与安全性。奇异值表征图像矩阵元素的相互关系,在轻微扰动时不会发生变化,因此,在奇异值上嵌入水印不会损害图像的几何特性。 SVD 分解是线性代数中一种非常重要的分解方式其定义如 下。设矩阵 A RRm×n,R表示实数域, m×n表示矩阵大小, A进行 SVD 处理的公式为
A = USVT (3)
式中: U V 都是正交矩阵,S是对角矩阵,奇异值就是矩阵 S 的对角线元素 且这些对角线元素满足 : σ1≥σ2≥σ3≥…σr≥σr+1 =…= σm =0 (其中 ,r表示 A的秩 )。
2 打印和扫描的应用分析
图像水印应用这种应用的挑战包括建立一种鲁棒的水印技术,以从印刷媒体中提取水印。该技术应该能够抵抗由于打印过程而发生的数字到模拟转应该能够抵抗由于打印过程而发生的数字到模拟转换,然后是扫描打印的水印图像时发生的模拟换,然后是扫描打印的水印图像时发生的模拟 - 数数字转换。字转换。 在打印过程中,带水印的图像是模拟格式。在打印过程中,带水印的图像是模拟格式。 为了提取水印,应使用打印扫描过程中的扫描仪或为了提取水印,应使用打印扫描过程中的扫描仪或打印凸轮过程中的相机(移动相机或数码相机)通打印凸轮过程中的相机(移动相机或数码相机)通过捕获过程将模拟数据数字化过捕获过程将模拟数据数字化。。由于引入的攻击,由于引入的攻击,包括几何攻击(例如旋转,缩放,切割和剪切)以包括几何攻击(例如旋转,缩放,切割和剪切)以及由设备引起的扭曲,打印和捕获过程可能具有挑及由设备引起的扭曲,打印和捕获过程可能具有挑战性。战性。 这些失真通常是由在移动电话中存储图像时这些失真通常是由在移动电话中存储图像时的打印和压缩过的打印和压缩过程引起的。一些研究已经研究了这程引起的。一些研究已经研究了这些仍处于初期阶段的应用些仍处于初期阶段的应用。

3 基 于 D C T —SV D 压缩量化的数字 水印
3.1 水印算法
由于具有以下主要特性,SVD能应用于数字水印算法中。 ① 图像的奇异值具有良好的稳定性,即当图像发生微小变化时,其奇异值不会显著变化;② 图像奇异值发生较小改变时,原图像也不会发生较大的变化。因此,在图像的奇异值上嵌入水印,不会对原图像的质量产生太大的影响。 SVD 嵌入水印能有效抵抗几何攻击,但传统 SVD 数字水印算法在提取水印时需要原始载体图像,增加了载体图像在传输时的不安全性,降低了算法的效率。本文算法在嵌入水印过程中没有用到原图 SVD 分解后的正交矩阵,所以,提取水印时不需要原始载体图像。同时,DCT 变换能很好地适应人眼的视觉特性,本文先对载体图像分块,可以将原图的变化集中在每一块中,对每一块 DCT 变换得到近似分量 ;再将近似分量 进行 SVD 分解求得其奇异值矩阵。最后用量化方法得到含水印图像。

3.2 水印的嵌入过程
基于 DCT 和 SVD 的鲁棒性数字水印算法的水印嵌入 算法 过程 ,具体步骤如下
(1) 选取 尺寸为 512˟512大小的图片 颜色模式为 RGB模式的图像 I。
(2) 分离出图像的绿色通道 A。
(3) 对绿色通道进行 DCT变换 ADCT。并对ADCT进行 SVD分解:
在这里插入图片描述
(4) 读取水印图片,进行灰度化处理。
(5) 对水印图片进行 DCT变换得矩阵 W。
(6) 将水印嵌入到矩阵 S中,即;
在这里插入图片描述
(7) 对 图像 𝑰𝑫𝑪𝑻 进行逆 DCT变换,将图像从频率域转换到空间域,进而显示 嵌入水印得图像,完成水印嵌入过程,即:
在这里插入图片描述
3.3 水印提取过程
本文所述提取含水印图片是经过打印扫描攻击之后的图片 ,𝑰𝒘𝒎. 本文采用数字水印盲 检测的方法,提取水印时之需要嵌入强度 𝛂的值。 具体步骤如下
(1) 读取 含水印图片 𝑰𝒘𝒎. 分离图像 RGB颜色通道中的绿色通道,得图像 𝑰𝒘𝒎_𝒈.
(2) 对图像 𝑰𝒘𝒎_𝒈. 进行 DCT变换,并对其进行SVD分解。
在这里插入图片描述
(3) 计算图像 D
在这里插入图片描述
(4) 计算水印 𝑊∗
在这里插入图片描述

二、源代码

function varargout = main(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @main_OpeningFcn, ...
                   'gui_OutputFcn',  @main_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin & isstr(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

function main_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = main_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function axes1_ButtonDownFcn(hObject, eventdata, handles)
function popupmenu1_CreateFcn(hObject, eventdata, handles)
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end
function pushbutton1_Callback(hObject, eventdata, handles)
f1=uigetfile('*.bmp','打开载体图像');
guidata(hObject, handles);
global cover_object;
cover_object=imread(f1);
axes(handles.axes1);
imshow(cover_object);
title('载体图像');
function pushbutton3_Callback(hObject, eventdata, handles)
f2=uigetfile('*.jpg','打开原始水印图像');
guidata(hObject, handles);
global watermark;
watermark=imread(f2);
watermark=im2bw(watermark);
axes(handles.axes4);
imshow(watermark);
title('水印图像');
function pushbutton2_Callback(hObject, eventdata, handles)
global watermark;
global watermark_en;
Mm=size(watermark,1);               
Nm=size(watermark,2); 
N=Mm*Nm;
key=0.2345;
m(1)=key;
for i=1:N-1
    m(i+1)=4*m(i)-4*m(i)^2;
end
m=mod(1000*m,256);
m=uint8(m);m=im2bw(m);
n=1;
for i=1:Mm
    for j=1:Nm
        watermark_en(i,j)=bitxor(m(n),watermark(i,j));
        n=n+1;
    end
end
axes(handles.axes6);
imshow(watermark_en);
title('加密水印');
global watermark_en;
function pushbutton4_Callback(hObject, eventdata, handles)
global cover_object watermark_en CWI Temp;
[mm,nn]=size(cover_object); 
[mm1,nn1]=size(watermark_en);
[LL HL LH HH]=dwt2(cover_object,'haar');
[U,S,V]=svd(LL);
af=0.03;
[lm,ln]=size(LL);
WW=zeros(lm,ln);
for i=1:mm1
    for j=1:nn1
            WW(i,j)=watermark_en(i,j);
    end
end
Temp=S+af*WW;
[U1,S1,V1]=svd(Temp);
CW=U*S1*V';
I1=idwt2(CW,HL,LH,HH,'haar');
CWI=uint8(I1);
axes(handles.axes2);
imshow(CWI);
title('含水印信息的载体图像');
global CWI;
global Temp;
function pushbutton8_Callback(hObject, eventdata, handles)
global CWI;
global attackf;
f=CWI;
attackd=get(handles.popupmenu1,'Value');
while attackd~=0
switch attackd
    case 1,
    attackf=f;
    att='未攻击';
break;
  case 2,
f(20:180,20:180)=256;
attackf=f;
att='剪切图像';
break;
  case 3,
attackf=imadjust(f,[],[0.4,1]);
att='图像增亮';
break;
case 4,
attackf=imadjust(f,[],[0,0.95]);
att='图像变暗';
break;
case 5,
复制代码

三、运行结果

在这里插入图片描述

四、备注

版本:2014a

完整代码或代写加1564658423

文章分类
人工智能
文章标签