【问题标题】:Basics of Normalizing Cross-Correlation with a View to Comparing Signals从比较信号的角度来规范互相关的基础知识
【发布时间】:2019-06-15 00:27:18
【问题描述】:

我试图了解如何使用互相关来确定两个信号的相似性。 This tutorial 提供了非常清晰的基础解释,但我仍然不明白如何有效地使用归一化来防止强信号在具有不同能量水平的信号时主导互相关测量。同一位导师 David Dorran 讨论了归一化问题here,并解释了如何使用点积对相关性进行归一化,但我仍有一些疑问。

我编写了这个 python 例程来对一组信号中的每对信号进行互相关:

import numpy as np
import pandas as pd

def mycorrelate2d(df, normalized=False):
    # initialize cross correlation matrix with zeros
    ccm = np.zeros(shape=df.shape, dtype=list)
    for i, row_dict1 in enumerate(
                        df.to_dict(orient='records')):
        outer_row = list(row_dict1.values())    
        for j, row_dict2 in enumerate(
                            df.to_dict(orient='records')):
            inner_row = list(row_dict2.values())   
            x = np.correlate(inner_row, outer_row)
            if normalized:
                n = np.dot(inner_row, outer_row)                
                x = x / n
            ccm[i][j] = x
    return ccm

假设我有 3 个幅度增加的信号: [1, 2, 3], [4, 5, 6] 和 [7, 8, 9]

我想交叉关联这三个信号以查看哪些信号对是相似的,但是当我将这三个信号传递到我编写的例程中时,我似乎没有得到相似度的度量。互相关值的大小只是能量信号的函数。时期。甚至一个信号与其自身的互相关产生的值也低于同一信号与另一个更高能量信号的互相关。

df_x3 = pd.DataFrame(
        np.array([[1, 2, 3], 
                  [4, 5, 6], 
                  [7, 8, 9]]).reshape(3, -1))
mycorrelate2d(df_x3)

这会产生:

array([[array([ 3,  8, 14,  8,  3]), 
        array([12, 23, 32, 17,  6]),
        array([21, 38, 50, 26,  9])],
       [array([ 6, 17, 32, 23, 12]), 
        array([24, 50, 77, 50, 24]),
        array([ 42,  83, 122,  77,  36])],
       [array([ 9, 26, 50, 38, 21]), 
        array([ 36,  77, 122,  83,  42]),
        array([ 63, 128, 194, 128,  63])]], dtype=object)

现在,我传入相同的 3 个信号,但这次我表示我想要标准化结果:

mycorrelate2d(df_x3, normalized=True)

这会产生:

array([[array([ 0.2142, 0.5714,  1., 0.5714, 0.2142]),
        array([ 0.375,  0.71875, 1., 0.5312, 0.1875]),
        array([ 0.42,   0.76,    1., 0.52,   0.18])],
       [array([ 0.1875, 0.5312,  1., 0.7187, 0.375]),
        array([ 0.3116, 0.6493,  1., 0.6493, 0.3116]),
        array([ 0.3442, 0.6803,  1., 0.6311, 0.2950])],
       [array([ 0.18,   0.52,    1., 0.76,   0.42]),
        array([ 0.2950, 0.6311,  1., 0.6803, 0.3442]),
        array([ 0.3247, 0.6597,  1., 0.6597, 0.3247])]],
        dtype=object)

现在所有的最大值都是 1!!因此,我们从具有基于虚假差异的最大值变为完全没有最大值之间的差异!我欣然承认,我不明白如何使用互相关来检测信号之间的相似性。将信号与互相关进行比较的人的分析工作流程是什么?

【问题讨论】:

    标签: python matlab signal-processing normalization cross-correlation


    【解决方案1】:

    看看Compute Normalized Cross-Correlation in Python

    因此,您用于规范化的公式并不完全正确。归一化发生在我们在 NCC 中关联之前,然后我们将答案除以向量长度,如维基百科公式 https://en.wikipedia.org/wiki/Cross-correlation#Zero-normalized_cross-correlation_(ZNCC)

    所示

    所以你需要类似的东西

    import numpy as np
    
    
    def mycorrelate2d(df, normalized=False):
        # initialize cross correlation matrix with zeros
        ccm = np.zeros((3,3))
        for i in range(3):
            outer_row = df[i][:]
            for j in range(3):
                inner_row = df[j][:]
                if(not normalized):
                    x = np.correlate(inner_row, outer_row)
                else:
                    a = (inner_row-np.mean(inner_row))/(np.std(inner_row)*len(inner_row))
                    #print(a)
                    b = (outer_row-np.mean(outer_row))/(np.std(outer_row))
                    #print(b)
                    x = np.correlate(a,b)
                ccm[i][j] = x
        return ccm
    
    df_x3 =np.array([[1, 2, 3],
                      [4, 5, 6],
                      [7, 8, 9]]).reshape(3, -1)
    print(mycorrelate2d(df_x3,True))
    df_x3 =np.array([[1, 2, 3],
                      [9, 5, 6],
                      [74, 8, 9]]).reshape(3, -1)
    print(mycorrelate2d(df_x3,True))
    

    输出是

    [[1. 1. 1.]
     [1. 1. 1.]
     [1. 1. 1.]]
    [[ 1.         -0.72057669 -0.85933941]
     [-0.72057669  1.          0.97381599]
     [-0.85933941  0.97381599  1.        ]]
    

    【讨论】:

    • 我得到了同样的东西!所有的!但是,我看不出代码有什么问题。至于点积,我使用点积进行归一化,因为这是 David Dorran 在他的教程中使用的公式。显然,关于什么构成“标准化”互相关存在一些模糊性。顺便说一句,非常感谢您快速而冗长的回复。
    • 好的,我知道发生了什么。所以 [1,2,3]、[4,5,6] 和 [7,8,9] 是完全相同的分布,它们归一化为 [-1.22474487 0. 1.22474487],因此由于它们完全相关,所以得到所有 1。如果您提供不同的输入,则不会发生这种情况。我正在用一些例子更新答案
    • 啊,是的。当然!我应该抓住它。非常感谢您的跟进。
    • 为什么要除以向量长度?我在您链接到的 ZNCC 的维基百科解释中没有看到这一点。为什么只有两个向量之一?
    • 是求和之外的1/n
    猜你喜欢
    • 1970-01-01
    • 2013-07-31
    • 2015-05-29
    • 2012-06-08
    • 1970-01-01
    • 2017-10-23
    • 2013-01-25
    • 2014-04-03
    • 2023-04-02
    相关资源
    最近更新 更多