• 在数据中查找信号


    目录

    查找精确匹配

    寻找匹配度最高的信号

    查找低于某阈值的最接近的匹配

    搜索存在变化偏移量的复信号轨迹

    查找进行时间拉伸后的功率信号


            此示例说明如何使用 findsignal 在数据中查找时变信号。它包括的各示例说明如何使用距离度量找到精确匹配和高度匹配的信号、如何补偿缓慢变化的偏移,以及使用动态时间规整以把采样差异考虑在内。

    查找精确匹配

            当要找到信号在数值上完全一致的匹配项时,可以使用 strfind 来执行匹配。

            例如,如果我们有如下数据向量:

    data = [1 4 3 2 55 2 3 1 5 2 55 2 3 1 6 4 2 55 2 3 1 6 4 2];

    我们想找到以下信号的位置:

    signal = [55 2 3 1];

    我们可以使用 strfind 找到信号在数据中所处位置的起始索引,条件是信号和数据在数值上是完全一致的。

    1. iStart = strfind(data,signal)
    2. iStart = 1×3
    3. 5 11 18

    寻找匹配度最高的信号

            strfind 适用于数值上完全一致的匹配。然而,当信号中可能因存在量化噪声或其他伪影而导致误差时,这种方法会失败。

            例如,如果有以下正弦波:

    data = sin(2*pi*(0:25)/16);

            要找到以下信号的位置:

    signal = cos(2*pi*(0:10)/16);

            strfind 无法在数据中找到从第五个采样开始的正弦波:

    1. iStart = strfind(data,signal)
    2. iStart =
    3. []

            strfind 无法在数据中找到该信号,因为舍入误差使得并非所有值在数值上都相等。要看到这一点,我们从匹配区域的信号中减去数据。

    1. data(5:15) - signal
    2. ans = 1×11
    3. 10-15 ×
    4. 0 0 0 0.0555 0.0612 0.0555 0 0.2220 0 0.2220 0

            存在 1e-15 数量级的数值差异。要解决此问题,可以使用 findsignal,默认情况下它会在数据中扫描该信号,并在每个匹配位置局部计算信号和数据之间的平方差之和,以寻找最小和。

            要生成突出显示最佳匹配位置的信号和数据的图,可以按如下方式调用 findsignal:

    findsignal(data,signal)

            如图所示:

    查找低于某阈值的最接近的匹配

            默认情况下,findsignal 始终返回信号与数据最接近的匹配。要返回多个匹配项,可以指定一个最大平方差总和的界限。

    1. data = sin(2*pi*(0:100)/16);
    2. signal = cos(2*pi*(0:10)/16);
    3. findsignal(data,signal,'MaxDistance',1e-14)

            如图所示:

            findsignal 返回按接近程度进行排序的匹配项 

    1. [iStart, iStop, distance] = findsignal(data,signal,'MaxDistance',1e-14);
    2. fprintf('iStart iStop total squared distance\n')
    3. iStart iStop total squared distance
    4. fprintf('%4i %5i %.7g\n',[iStart; iStop; distance])
    5. 53 63 0
    6. 69 79 0
    7. 85 95 0
    8. 5 15 1.776357e-15
    9. 21 31 1.776357e-15
    10. 37 47 1.776357e-15

    搜索存在变化偏移量的复信号轨迹

            接下来的示例说明如何使用 findsignal 查找一个已知轨迹的信号。cursiveex.mat 文件包含笔尖在一张纸上描绘出 phosphorescence 一词时所记录的 x 和 y 位置。x,y 数据分别编码为复信号的实部和虚部。

    1. load cursiveex
    2. plot(data)
    3. xlabel('real')
    4. ylabel('imag')

            如图所示:

            同一执笔者描绘出字母 p 作为模板信号。 

    1. plot(signal)
    2. title('signal')
    3. xlabel('real')
    4. ylabel('imag')

            如图所示:

             使用 findsignal,可以很轻松地找到数据中的第一个 p。这是因为信号值在数据开始时对齐程度较好。

    findsignal(data,signal)

            如图所示:

            但是,第二个 p 有两个特征导致 findsignal 难以识别它:它与第一个字母相比有显著而持续的偏移,并且该字母的某些部分是以不同于模板信号的速度描绘的。

            如果只对匹配字母的整体形状感兴趣,可以从信号和数据元素中减去经加窗的局部均值。这样可以减轻持续的偏移产生的影响。

            为了减轻描绘字母时的速度变化的影响,可以使用动态时间规整,它会在执行搜索时将信号或数据拉伸到一个共同的时基:

    1. findsignal(data,signal,'TimeAlignment','dtw', ...
    2. 'Normalization','center', ...
    3. 'NormalizationLength',600, ...
    4. 'MaxNumSegments',2)

            如图所示:

    查找进行时间拉伸后的功率信号

            接下来的示例说明如何使用 findsignal 来查找短语语音中某发音单词的位置。

            以下文件包含短语Accelerating the pace of engineering and science 的录音,还包含同一位发音人单独的 engineering 一词的录音。

    1. load slogan
    2. soundsc(phrase,fs)
    3. soundsc(hotword,fs)

            同一位发音人在一个句子或短语中改变单个词的发音是很常见的。此示例中的发音人以两种不同的方式读出 engineering 这个词:发音人在短语中用了大约 0.5 秒读出该单词,重音放在第二个音节 (en-GIN-eer-ing);同一发音人用了 0.75 秒单独读出该单词,重音放在第三个音节 (en-gin-EER-ing)。

            为了补偿时间和音量的这些局部差异,您可以使用频谱图来报告谱功率分布随时间的变化。

            首先,使用一个频率分辨率比较粗糙的频谱图。这样做是为了有意模糊声道的窄带声门脉冲,而让口腔和鼻腔的宽带共振不受干扰。这可以让您锁定一个单词中读出的元音。用频谱图来识别辅音(尤其是爆破音和摩擦音)要困难得多。以下代码用于计算频谱图

    1. Nwindow = 64;
    2. Nstride = 8;
    3. Beta = 64;
    4. Noverlap = Nwindow - Nstride;
    5. [~,~,~,PxxPhrase] = spectrogram(phrase, kaiser(Nwindow,Beta), Noverlap);
    6. [~,~,~,PxxHotWord] = spectrogram(hotword, kaiser(Nwindow,Beta), Noverlap);

            现在已有短语和搜索词的频谱图,可以使用动态时间规整以将局部的单词长度差异考虑在内。同样,可以通过结合使用功率归一化和对称 Kullback-Leibler 距离来将功率差异考虑在内。

    1. [istart,istop] = findsignal(PxxPhrase, PxxHotWord, ...
    2. 'Normalization','power','TimeAlignment','dtw','Metric','symmkl')
    3. istart = 1144
    4. istop = 1575

            绘制和播放识别的单词。

    1. findsignal(PxxPhrase, PxxHotWord, 'Normalization','power', ...
    2. 'TimeAlignment','dtw','Metric','symmkl')

    如图所示:

  • 相关阅读:
    python数据类型的操作与运算符的使用
    Vuex状态管器:Mutations
    SQL编写规范【干货】
    鼠标右键使用VSCode打开文件或文件夹配置
    数据分析相关知识整理_--秋招面试版
    【计算机网络】Linux 内核网络概述
    一心为农,以智取胜——张继群的智慧农业之路
    紫光展锐荣评“5G技术创新力企业”,5G赋能千行百业
    应用集成-在Hexo、Hugo博客框架中使用Gitalk基于Github上仓库项目的issue无后端服务评论系统实践
    【App 抓包提示网络异常怎么破?】
  • 原文地址:https://blog.csdn.net/jk_101/article/details/124795589