Matlab实现简单扩频语音水印算法详解

目录
  • 一、实验背景
    • 1.实验目的
    • 2.实验环境
    • 3.原理简介
  • 二、基础知识
    • 1.PN序列
    • 2.时域到频域变换的原因
    • 3.三种时域到频域变换的区别
  • 三、算法源码
    • 1.PN产生函数
    • 2.隐藏算法
    • 3.提取算法
    • 4.测试脚本
  • 四、运行测试
    • 1.无攻击(误码率0.000976):
    • 2.AU格式转换(误码率0.001921):
    • 3.压缩与解压缩(误码率0.002029):

一、实验背景

1.实验目的

了解扩频通信原理,掌握扩频水印算法的基本原理,设计并实现一种基于音频的扩频水印算法,了解参数对扩频水印算法性能的影响。

2.实验环境

(1) Windows 11 操作系统;

(2) Matlab R2020b 科学计算软件;

(3) WAV音频文件。

3.原理简介

①扩频基本原理

扩频是一种能在高噪声环境下可靠传输数据的重要通信技术,其基本原理是:信号在大于所需的带宽内进行传输,数据的带宽扩展是通过一个与数据独立的码字完成的,并且在接收端需要该码字的一个同步接收,以进行解扩和数据恢复。

②扩频通信的特点

占据频带很宽,每个频段上的能量很低;

即使几个频段的信号丢失,仍可恢复信号;

利用相互正交的扩频码,可以利用这个优点设计水印算法。

③实验算法

本例中设计一种简单的算法:利用正交的PN序列代表0、1信号,并将其叠加到信号DCT域。提取水印时,利用PN序列的正交性可以较为准确地恢复水印。

二、基础知识

1.PN序列

PN序列(Pseudo-noise Sequence),又称伪噪声序列,这类序列具有类似随机噪声的一些统计特性,但和真正的随机信号不同,它可以重复产生和处理,故称作伪随机噪声序列。

PN序列一般用于扩展信号频谱。PN序列的扩频是指用一个 序列去乘以一个信息符号,序列码片的时间远小于信息符号的时间,由信号的时间与频谱的关系,我们可以知道扩频后的序列的频谱是展宽的。

由于PN序列的相关性很低,只有在发送的PN序列和接收的PN序列相同,并且其码片同步时才能得到一个相关峰。当发射时,信号的功率是低于噪声的功率的,如果不知道PN序列,则较难得知码片的信息。因此,扩频通信具有一定的加密性。

2.时域到频域变换的原因

时域是信号在时间轴随时间变化的总体概括,频域是把时域波形的表达式做傅立叶变化,得到复频域的表达式,所画出的波形就是频谱图。是描述频率变化和幅度变化的关系。将时域变换到频域是为了做频谱分析,即在时域中我们研究信号的时间特性,在频域中我们研究信号的频率特性,由于信号往往在频域比在时域更加简单、直观,所以大部分信号分析的工作是在频域进行的。

3.三种时域到频域变换的区别

FTP: 离散傅里叶变换,对于连续信号的静态变换;

DWT:离散小波变换,对短时间(瞬间)信号的动态变换;

DCT:离散余弦变换,对连续信号的动态变换。

三、算法源码

1.PN产生函数

function out =pn_gen(g,init,shift)
format=1;
out_len = 0;
in_len= 0;
out=[];
%check parameter fomat, ether g2 =[100000101]or g1 = [820]
tp = max(g);
if tp==1
    format = 2;% format of parameter
    in_len = length(g) -1;
else
    fommat = 1;
    in_len= g(1);
end
out_len= 2^in_len-1; % length of output
out = zeros(1, out_len);
for n = 1:out_len
    out(n) = init(in_len);
    if fommat==1
        tp=0;
        for m=2:length(g)
           tp = mod((tp+init(g(m) + 1)), 2);%caculate new init(1)
           tp = mod((tp + init(in_len- g(m))),2); %caculate new init(1)
        end
    else
        tp= init .* g(2 : (in_len+1));
        tp = mod(sun(tp), 2);
    end
    init=[tp init(1 : (in_len-1))];
end
for n = (shift- 1):-1:0
    out = [out(2 : out_len),out(1)];
end

2.隐藏算法

function o = hide_ds(fragment, data, s, atten, pn0, pn1)
[row, col] = size(s);
if(row> col)
    s=s';
end
i =1;
n = min( floor(length(s) / fragment), length(data));
o = s;
len = length(pn0);
base = fragment -len + 1;
for i=1 : n
    st =(i- 1) *fragment+1;
    ed = i*fragment;
    tmp = dct(s(st:ed));
    attenl = atten *max(abs(tmp));
    if data(i) == 1
        tmp(base:fragment)=tmp( base:fragment)+ attenl*pn1;
    else
        tmp(base:fragment) = tmp(base:fragment) + attenl*pn0;
    end
    o(st : ed) = idct( tmp);
end

3.提取算法

function out = dh_ds(fragment, in, pn0, pnl)
[row, col] = size(in);
if(row> col)
    in = in';
end
i=1;
len = floor(length(in) / fragment);
out =[];
len_pn = length( pn0);% length of pn
base = fragment - len_pn+1;
for i = 1:len
    st = (i-1) *fragment +1;
    ed = i *fragment;
    p = dct(in(st: ed));
    t0 = sum( p(base:fragment).* pn0);
    t1 = sum( p(base:fragment).* pnl);
    if t1>t0
        out(i) = 1;
    else
        out(i) = 0;
    end
end

4.测试脚本

% 1 select cover audio
[fname, pname] = uigetfile(' *.wav','Select cover audio');
sourcename = strcat(pname, fname) ;
s = audioread( sourcename)';
s_len = length(s);
% 2 generate msg to be embedded
frag = 256;
msg_len = floor(s_len / frag);
msg = randsrc(1, msg_len, [0 1]);
% 3 generate PN
degree = 7;
pn0 = 2*pn_gen([degree 6 0], [zeros(1, degree - 1) 1],0) - 1;
pn1 = 2*pn_gen([degree 6 0],[zeros(1, degree - 1) 1],1) - 1;
%4 embed msg
atten = 0.005;
bld = hide_ds(frag, msg, s, atten, pn0, pn1);
% 5 save the stegoed-audio
audiowrite('hide.wav', bld, 8e+3);
% 6 select stegoed-audio
[fname, pname] = uigetfile('*.wav','Select stegoed-audio');
sourcename = strcat(pname, fname);
steg = audioread(sourcename)' ;
% 7 extract msg
out = dh_ds(frag, steg, pn0, pn1);
% 8 compute ebr
fid = 1;
ebr = sum( abs(msg -out)) / s_len;
fprintf(fid, 'ebr;%f\n', ebr);

四、运行测试

1.无攻击(误码率0.000976):

① 运行test.m,选择提前准备好的wav文件(载体音频):

② 得到携带水印的音频hide.wave, 可利用音频处理软件对音频进行攻击,观察攻击后水印的恢复情况。

③最后提取水印,并计算误码率

2.AU格式转换(误码率0.001921):

(wav->mp3->wav)

3.压缩与解压缩(误码率0.002029):

到此这篇关于Matlab实现简单扩频语音水印算法详解的文章就介绍到这了,更多相关Matlab 扩频语音水印算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Matlab如何实现矩阵复制扩充

    考虑这个问题: 定义一个简单的行向量a 如何复制10行呢?即: 同理,对于一个列向量,如何复制 10 列呢? 关键函数1: repmat( A , m , n ):将向量/矩阵在垂直方向复制m次,在水平方向复制n次. 再举一个例子,对于 a =[1 2;3 4]: 垂直方向复制3次,水平方向复制2次,结果是: 接下来进阶一下,玩点复杂的.对于 a = [1 2;3 4],如何变成下面这样: 关键函数: kron( a , B ) :对 a 的每一个元素 e,都数乘B矩阵,构成新的矩阵.具体用法可

  • MATLAB 如何求取离散点的曲率最大值

    我就废话不多说了,大家还是直接看代码吧~ x0 = linspace(0.1,2,100);%x0,y0验证函数离散点,可以非等间隔 y0 = 1./x0; h1 = abs(diff(x0)) ; h = [h1 h1(end)]; ht = h; yapp1 = gradient(y0)./ht; %matlab数值近似 yapp2 = del2(y0)./ht; %matlab数值近似 k2 = abs(yapp2)./(1+yapp1.^2).^(3/2); figure plot(k2

  • matlab画三维图像的示例代码(附demo)

    当我们学习surface命令时,已经看到了三维作图的一些端倪.在matlab中我么可以调用mesh(x,y,z)函数来产生三维图像. 首先,我们用z=cos(x)sin(y)在-2pi ≤x,y≤ 2pi内的图像来看看: [x,y] = meshgrid(-2*pi:0.1:2*pi); z = cos(x).*sin(y); mesh(x,y,z),xlabel('x'),ylabel('y'),zlabel('z') 显示图像如下: 同样用mesh命令产生z = ye-(x2+y2)的三维图

  • matlab 计算灰度图像的一阶矩,二阶矩,三阶矩实例

    一阶矩,定义了每个颜色分量的平均强度 二阶矩,反映待测区域颜色方差,即不均匀性 三阶矩,定义了颜色分量的偏斜度,即颜色的不对称性 close all;clear all;clc; J = imread('lena.jpg'); K = imadjust(J,[70/255 160/255],[]); figure; subplot(121),imshow(J); subplot(122),imshow(K); [m,n] = size(J); mm = round(m/2); mn = roun

  • Matlab实现简单扩频语音水印算法详解

    目录 一.实验背景 1.实验目的 2.实验环境 3.原理简介 二.基础知识 1.PN序列 2.时域到频域变换的原因 3.三种时域到频域变换的区别 三.算法源码 1.PN产生函数 2.隐藏算法 3.提取算法 4.测试脚本 四.运行测试 1.无攻击(误码率0.000976): 2.AU格式转换(误码率0.001921): 3.压缩与解压缩(误码率0.002029): 一.实验背景 1.实验目的 了解扩频通信原理,掌握扩频水印算法的基本原理,设计并实现一种基于音频的扩频水印算法,了解参数对扩频水印算法

  • matlab中二维插值函数interp2的使用详解

    下面是一段产生log-normal分布的代码,以此进行说明. clear all; clc; for t=1:100 Traffic(t) =curve(t); end MaxTraffic = max(Traffic); w = 0.2; Wmax = 2*pi*w/3000; x=[0:10:300]; y=[0:10:300]; Nx=length(x); Ny=length(y); Sigma = 0.53; t = 0: M = 10*curve(t)/MaxTraffic; sum

  • python算法演练_One Rule 算法(详解)

    这样某一个特征只有0和1两种取值,数据集有三个类别.当取0的时候,假如类别A有20个这样的个体,类别B有60个这样的个体,类别C有20个这样的个体.所以,这个特征为0时,最有可能的是类别B,但是,还是有40个个体不在B类别中,所以,将这个特征为0分到类别B中的错误率是40%.然后,将所有的特征统计完,计算所有的特征错误率,再选择错误率最低的特征作为唯一的分类准则--这就是OneR. 现在用代码来实现算法. # OneR算法实现 import numpy as np from sklearn.da

  • python中实现k-means聚类算法详解

    算法优缺点: 优点:容易实现 缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢 使用数据类型:数值型数据 算法思想 k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近的就会放到同一个类别中去. 1.首先我们需要选择一个k值,也就是我们希望把数据分成多少类,这里k值的选择对结果的影响很大,Ng的课说的选择方法有两种一种是elbow method,简单的说就是根据聚类的结果和k的函数关系判断k为多少的时候效果最好.另一种则是根据具体的需求确定,比如说进行衬衫尺寸的聚

  • Java语言实现快速幂取模算法详解

    快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程 缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增大,非常的占用我们的计算资源(主要是时间,还有空间) 缺点2:我们计算的中间过程数字大的恐怖,我们现有的计算机是没有办法记录这么长的数据的,所以说我们必须要想一个更加高效的方法来解决这个问题 当我们计算AB%C的时候,最便捷的方法就是调用Ma

  • Java垃圾回收之分代收集算法详解

    概述 这种算法,根据对象的存活周期的不同将内存划分成几块,新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法.可以用抓重点的思路来理解这个算法. 新生代对象朝生夕死,对象数量多,只要重点扫描这个区域,那么就可以大大提高垃圾收集的效率.另外老年代对象存储久,无需经常扫描老年代,避免扫描导致的开销. 新生代 在新生代,每次垃圾收集器都发现有大批对象死去,只有少量存活,采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集:可以参看我之前写的Java垃圾回收之复制算法详解 老年代

  • Js面试算法详解

    素数 Q:你将如何验证一个素数? A:一个素数只能被它自己和1整除.所以,我将运行一个while循环并加1.(看代码示例,如果你无法理解,那这不是你的菜.先回去学习javaScript基础知识然后再回来吧.) 方法1 function isPrime(n){ var divisor = 2; while (n > divisor){ if(n % divisor == 0){ return false; } else divisor++; } return true; } isPrime(137

  • Java垃圾回收机制算法详解

    概述 Java GC(Garbage Collection,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢.这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制.概括地说,该机制对JVM中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息的保证JVM中的内存空间,防止出现内存泄露和溢出问题. 在真实工作中的项目中,时不时的会发生内存溢

  • python里反向传播算法详解

    反向传播的目的是计算成本函数C对网络中任意w或b的偏导数.一旦我们有了这些偏导数,我们将通过一些常数 α的乘积和该数量相对于成本函数的偏导数来更新网络中的权重和偏差.这是流行的梯度下降算法.而偏导数给出了最大上升的方向.因此,关于反向传播算法,我们继续查看下文. 我们向相反的方向迈出了一小步--最大下降的方向,也就是将我们带到成本函数的局部最小值的方向. 图示演示: 反向传播算法中Sigmoid函数代码演示: # 实现 sigmoid 函数 return 1 / (1 + np.exp(-x))

  • Python自然语言处理之切分算法详解

    一.前言 我们需要分析某句话,就必须检测该条语句中的词语. 一般来说,一句话肯定包含多个词语,它们互相重叠,具体输出哪一个由自然语言的切分算法决定.常用的切分算法有完全切分.正向最长匹配.逆向最长匹配以及双向最长匹配. 本篇博文将一一介绍这些常用的切分算法. 二.完全切分 完全切分是指,找出一段文本中的所有单词. 不考虑效率的话,完全切分算法其实非常简单.只要遍历文本中的连续序列,查询该序列是否在词典中即可.上一篇我们获取了词典的所有词语dic,这里我们直接用代码遍历某段文本,完全切分出所有的词

随机推荐