一、离散小波变换的音频信号数字水印技术简介

0 引言
近年来, 数字水印技术的作用越来越重要。数字水印技术是将一些标识信息直接嵌入数字载体当中, 或间接表示在信号载体中, 且不影响原载体的使用价值。通过隐藏在载体中的这些信息, 可以判断信息是否被篡改, 具有防伪溯源、保护信息安全、版权保护等作用。对于广播转播台站而言, 是广播音频的中转站, 在广播信号发送至千家万户之前务必保证信号的安全可靠, 但现在的大部分台站只是利用人耳的判断, 以及不同信源之间的比较, 具有较大的局限性。若利用数字水印的特性, 应用于广播节目中可以有效地防止信号插播, 可靠地保护信号安全, 保障广播的安全播出。

1 音频数字水印技术分类
根据数字水印在音频信号中的处理技术, 可将数字水印分为时域、变换域、压缩域数字水印。

1.1 时域数字水印
在时域数字水印技术中, 直接将水印信息嵌入至音频信号中, 通常会选择隐藏在信号不重要部位, 以保证其嵌入水印不影响原音频信号的监听效果。时域水印技术的实现较为容易且运算量小, 简单直接, 但是鲁棒性差, 容易被破解, 抵抗力较差。

1.2 变换域数字水印
在变换域数字水印中, 音频信号需经过时域至变换域的转换, 通常的变换域有离散余弦变换 (DCT, Discrete Cosine Transform) 、离散傅立叶变换 (DFT, Discrete Fourier transform) 、离散小波变换 (DWT, Discrete Wavelet Transform) 等。在变换域中嵌入水印信息, 通过反变换得到嵌入水印的音频时域信号。变换域水印技术较时域水印技术复杂, 但变换域嵌入的水印信息较时域而言, 不可见性更强, 隐蔽性更好, 鲁棒性更好。本文的研究主要基于DWT的音频信号的水印信息的嵌入与提取。

1.3 压缩域数字水印
在时域和变换域的水印技术, 都是直接将水印信号嵌入未压缩的音频格式中, 但是通常在音频信号的传输或存储中需要对音频信号进行压缩编码 (例如WMA、MP3等) , 因此压缩域数字水印也是水印技术也具有较大的实用价值。压缩域数字水印技术大致可分为三类: (1) 在非压缩域嵌入水印, 将音频信号与水印信息一起压缩; (2) 在压缩域中, 直接将水印信息嵌入压缩的音频信号中; (3) 将压缩后的信号进行解压缩, 然后嵌入水印信息, 最后将水印信息和解压后的音频信号一起压缩。总的来说, 压缩域水印技术的编解码系统过于复杂, 受压缩编码格式限制大, 压缩后的音频信号已经去除了冗余, 因此加入水印的难度大, 压缩域水印技术有待进一步研究。

2 基于DWT的音频水印算法
2.1 水印嵌入
本文研究的音频水印算法是基于离散小波变换 (DWT) , 音频信号通过DWT变换, 在变换域中嵌入水印信息, 再经过逆变换 (IDWT) 从而得到嵌入水印的音频信号。水印嵌入原理框图如图1所示。

假定水印为M1×M2的二维图像bw, 由于音频信号通常为一维向量, 故水印信息在嵌入音频信号之前需要将二维降至一维向量w, 即M=M1×M2。通常我们也可以将图像进行打乱加密, 增强水印隐蔽性。

假定语音信号为s, 长度为N, 则s={s1, s2, s3, …, sN}由于语音信号较长在处理中一般需要进行分段, 每段长度设为N1, 故该语音信号分为K=fix (N/N1) 段进行处理, 每段语音均嵌入一个水印信息。

小波变换是为了解决傅立叶变换的不足而提出的一种分析变换, 傅立叶变换的基函数是铺满整个时域的正弦信号, 对于突变信号以及变化的频率成分信息均不能较准确地表示。而小波变换是时间和频率的局部变换, 更能准确地表示音频信号的频域特征, 常用的小波基有Haar小波、Daubechies (db N) 小波、Marr小波等。本文采用的小波基是Haar小波, 它是支撑域在t∈[0, 1]范围内的矩形波, 定义如下:

图1 音频信号水印嵌入原理框图

图2 音频信号水印提取原理框图

取定Haar小波基后, 则语音信号s可以表示为:

其中Cj, k为离散小波系数, 将音频信号分解为低频的近似部分和高频的细节部分, 我们在水印信息的嵌入处理中, 主要针对代表低频近似部分的系数向量处理, 即将水印信号放入低频近似部分, 高频细节部分不变, 以保证语音质量基本不变。由于嵌入的水印为二值图像, 因此如果水印信息的值为1, 则将对应的低频系数增大, 相反如果值为0, 则将对应的低频系数降低。在DWT域嵌入水印信息后, 然后通过IDWT变换, 将语音信号变换成时域信号。

2.2 水印提取
为了保证信息安全, 在发送端发送嵌入水印的音频信号, 而在接收端为了确定音频信息的准确性, 我们通常需要提取水印以确保来源的真实性, 因此水印的提取技术也尤为重要。在水印提取过程中, 需要原始音频信号与嵌入水印的音频信号同时进行DWT, 再将两者参数进行分析比较提取出水印信息。水印提取原理框图如图2所示。

在前面所述的水印嵌入过程中, 将水印信息嵌入高频的细节部分, 因此在提取水印过程中, 我们也只需比较原始语音信号S的低频小波系数向量c A与嵌入水印的音频信号s1的低频小波系数向量c A1作比较, 若c A1>c A, 则水印信息为1;反之则为0, 再通过向量平均, 如此得到水印信息的一维向量, 最后通过升维得到二值图像。

二、部分源代码

function varargout = main(varargin)
% MAIN MATLAB code for main.fig
%      MAIN, by itself, creates a new MAIN or raises the existing
%      singleton*.
%
%      H = MAIN returns the handle to a new MAIN or the handle to
%      the existing singleton*.
%
%      MAIN('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MAIN.M with the given input arguments.
%
%      MAIN('Property','Value',...) creates a new MAIN or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before main_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to main_OpeningFcn 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 main% Last Modified by GUIDE v2.5 05-Apr-2021 22:33:40% Begin initialization code - DO NOT EDIT
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 && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});
endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
elsegui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT% --- Executes just before main is made visible.
function main_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 main (see VARARGIN)% Choose default command line output for main
handles.output = hObject;% Update handles structure
guidata(hObject, handles);% UIWAIT makes main wait for user response (see UIRESUME)
% uiwait(handles.figure1);% --- Outputs from this function are returned to the command line.
function varargout = main_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 pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%% 选择音频
[file1,pathname]=uigetfile('*.wav','请选择要识别的样本');%跳出对话框
fname=fullfile(pathname,file1);
[X,fs,bits]=wavread(fname); %读入音频文件sound(X,fs); %播放声音
handles.axes1
subplot(2,2,1);
plot(X);     %显示音频文件波形
title('原始音频信号');
handles.X=X;
handles.fs=fs;
guidata(hObject, handles);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%% 选择水印
[file1,pathname]=uigetfile('*.bmp','请选择要识别的样本');%跳出对话框
fname=fullfile(pathname,file1);
key=35;
%Arnold置换次数,作为密钥
Orignalmark=double(imread(fname));  %读入64*64的水印图片
[wrow,wcol]=size(Orignalmark);
if wrow~=wcol error('wrow~=wcol error');
end
%--- 测试密钥key是否超出范围---------
n=check_arnold(wrow);
if (key+1)>nerror('arnold key error');
endsubplot(2,2,2); hold on
imshow(Orignalmark),title('原始图像');
handles.Orignalmark=Orignalmark;
handles.n=n;
guidata(hObject, handles);
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%% 嵌入水印
%水印嵌入--------------------------------------------------
X=handles.X;%读取音频
Orignalmark=handles.Orignalmark;%读取水印图像
fs=handles.fs;%频率
[wrow,wcol]=size(Orignalmark);
key=35;
Arnoldw=arnold(Orignalmark,wrow,key); %对水印图像进行Arnold转化
[c,l]=wavedec(X,2,'db4'); %用db4小波对读入的声音文件进行2级小波分解
ca2=appcoef(c,l,'db4',2); %提取2级小波分解的低频系数和高频系数
cd2=detcoef(c,l,2);
cd1=detcoef(c,l,1);
lca=length(ca2);  %低频长度
blocksize=fix(lca/(wrow*wcol)); %每块的大小
water_vector=reshape(Arnoldw,1,wrow*wcol);  %将置乱后的水印转化为一维的
wlength=wrow*wcol;  %水印的长度
a=0.25;  %量化步长
j=1;
for i=1:wlengthBlock=ca2(j:j+blocksize-1);[U,S,V]=svd(double(Block)); cc=floor(S(1,1)/a);  if(Arnoldw(i)==1)           %嵌入奇数倍if(mod(cc,2)==0)cc=cc+1;endS(1,1)=a*cc;endif(Arnoldw(i)==0)            %嵌入偶数倍if(mod(cc,2)==1)  cc=cc+1;endS(1,1)=a*cc;endBlockw=U*S*V';          %SVD 逆变换还原 ca2(j:j+blocksize-1)=Blockw; j=j+blocksize;
end
c1=[ca2',cd2',cd1']';
MarkedX=waverec(c1,l,'db4');%b为量化嵌入水印后的音频数据
subplot(2,2,3);
plot(MarkedX);
title('嵌入水印后音频');
sound(MarkedX,fs);
handles.MarkedX=MarkedX;
handles.key=key;
guidata(hObject, handles);% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%水印嵌入--------------------------------------------------
[c,l]=wavedec(X,2,'db4'); %用db4小波对读入的声音文件进行2级小波分解
ca2=appcoef(c,l,'db4',2); %提取2级小波分解的低频系数和高频系数
cd2=detcoef(c,l,2);
cd1=detcoef(c,l,1);
lca=length(ca2);  %低频长度
blocksize=fix(lca/(wrow*wcol)); %每块的大小
water_vector=reshape(Arnoldw,1,wrow*wcol);  %将置乱后的水印转化为一维的
wlength=wrow*wcol;  %水印的长度
a=0.25;  %量化步长
j=1;
for i=1:wlengthBlock=ca2(j:j+blocksize-1);[U,S,V]=svd(double(Block)); cc=floor(S(1,1)/a);  if(Arnoldw(i)==1)           %嵌入奇数倍if(mod(cc,2)==0)cc=cc+1;endS(1,1)=a*cc;endif(Arnoldw(i)==0)            %嵌入偶数倍if(mod(cc,2)==1)  cc=cc+1;endS(1,1)=a*cc;endBlockw=U*S*V';          %SVD 逆变换还原 ca2(j:j+blocksize-1)=Blockw; j=j+blocksize;
end

三、运行结果

四、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
[1]韩纪庆,张磊,郑铁然.语音信号处理(第3版)[M].清华大学出版社,2019.
[2]柳若边.深度学习:语音识别技术实践[M].清华大学出版社,2019.

【语音隐写】基于matlab GUI DWT音频数字水印【含Matlab源码 712期】相关推荐

  1. 【语音去噪】基于FIR滤波器实现音频去噪含Matlab源码

    1 简介 结合数字滤波器的理论基础和设计方法,在MATLAB程序语言环境下,设计出有限长单位脉冲响应(FIR)数字滤波器,同时利用GUI界面设计FIR数字滤波器人机交互平台,该系统平台界面直观.操作简 ...

  2. 【Matlab语音隐写】DWT音频数字水印【含GUI源码 712期】

    一.代码运行视频(哔哩哔哩) [Matlab语音隐写]DWT音频数字水印[含GUI源码 712期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1]韩纪庆,张磊, ...

  3. 【光学】基于matlab GUI杨氏双缝干涉【含Matlab源码 001期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[光学]基于matlab GUI杨氏双缝干涉[含Matlab源码 001期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费 ...

  4. 【语音隐写】基于matlab GUI DCT音频数字水印嵌入提取【含Matlab源码 837期】

    一.离散小波变换的音频信号数字水印技术简介 0 引言 近年来, 数字水印技术的作用越来越重要.数字水印技术是将一些标识信息直接嵌入数字载体当中, 或间接表示在信号载体中, 且不影响原载体的使用价值.通 ...

  5. 【人脸识别】基于matlab GUI人数统计【含Matlab源码 2121期】

    ⛄一.人数统计简介(附课程作业报告) 1 课题背景 本课题为基于matlab的人数统计系统.近年来,很多行业对人流信息有极大的需求,如汽车公交站,地铁站台,商场出入口等.通过人数统计系统可以方便.可靠 ...

  6. 基于SSM的仓库管理系统(含完整源码+论文)

    后端框架:SSM 数据库:MySQL 开发工具:IDEA/Eclipse 系统介绍:本系统是基于SSM框架进行设计,MySQL作为底层数据库,前端采用bootstrap 模块大致介绍:包括库存管理.出 ...

  7. 【条形码识别】基于matlab GUI二维条形码识别【含Matlab源码 607期】

    ⛄一.二维条形码识别简介 采用数字图像处理技术对二维条码进行识别, 是二维条形码识别中较常用的方法, 它在处理污损的条形码方面有光电识别方法无法比拟的优势.另外图像式识别方法对识别角度的要求没有光电识 ...

  8. 【心电信号】基于matlab GUI心电信号预处理【含Matlab源码 938期】

    ⛄一.心电信号预处理方法简介 理论知识参考文献:心电信号预处理方法研究 ⛄二.部分源代码 function varargout = kaishi(varargin) gui_Singleton = 1 ...

  9. matlab svm 语音识别,【情感识别】基于matlab支持向量机(SVM)的语音情感识别【含Matlab源码 543期】...

    一.简介 支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本.非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数 ...

  10. 【Matlab语音隐写】DCT+DWT音频数字水印嵌入提取【含GUI源码 836期】

    一.代码运行视频(哔哩哔哩) [Matlab语音隐写]DCT+DWT音频数字水印嵌入提取[含GUI源码 836期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1 ...

最新文章

  1. JSP自定义标签渲染时报Illegal to flush错误
  2. Nrf51822中设置128bit UUID service
  3. 选择 GCD 还是 NSTimer ?
  4. polkit 重新安装_不折腾,为U-NAS安装一个清爽的桌面,把小U打造成双面高手
  5. PHP 与go 通讯,Golang和php通信
  6. Linux命令(三)
  7. php swoole udp,基于Swoole如何搭建UDP服务?
  8. 大数据之-Hadoop3.x_MapReduce_outputformat案例需求分析---大数据之hadoop3.x工作笔记0121
  9. c# 正则表代式的分组和批评模式 .
  10. Array.prototype.slice.apply(arguments)和[].slice.apply(arguments)解析
  11. SylixOS armv8 任务切换
  12. Intersecting Lines - POJ 1269(判断平面上两条直线的关系)
  13. 收集的一些FLASHRIA作品集(附源文件下载)
  14. Windows10安装Matlab 2018b教程
  15. linux怎么让cpu不自动降频,Win10 CPU自动降频怎么办?Win10下让CPU不降频设置方法
  16. pyecharts 在地图上根据经纬度和量值,画出散点图/热力图
  17. Typora+图床详解(小白都能学得会)
  18. 博文推荐|深入解析 BookKeeper 多副本协议(一)
  19. 前端工程化----Node.js基础篇
  20. 云游戏学习与实践(一)——云游戏概述

热门文章

  1. python threading之条件变量同步(condition)
  2. iOS之内存管理(ARC)
  3. python - 安装/解释器/变量
  4. MVC采用Jquery实现局部刷新
  5. Hibernate【3】——Service层
  6. SAP安装前应准备的事项
  7. ARM编译中的RO、RW和ZI DATA区段[转]
  8. 190326每日一句
  9. 181023词霸有道扇贝每日一句
  10. Atitit 提升效率 声明式编程 约束式编程 目录 1. 。 在约束编程中,问题被视为对可能是有效解决方案的一系列限制。 1 2. 常见的约束式编程 2 2.1. 数据库约束 注解 2 2.2.