曲线相似度衡量——曲线距离计算Fréchet distance详解与python计算

弗朗明歇距离(Fréchet distance)论文可以参考:

理论推导
Eiter, Thomas, and Heikki Mannila. “Computing discrete Fréchet distance.” (1994).

便于计算的离散距离求解
Alt, Helmut, and Michael Godau. “Computing the Fréchet distance between two polygonal curves.” International Journal of Computational Geometry & Applications 5.01n02 (1995): 75-91.

含义

这个图能够形象说明Fréchet distance的含义:一个人牵着一条狗,共同走到目的地,尝试求:狗链子的最短值
在这里插入图片描述

算法思路

  1. 首先Fréchet distance是计算两个序列之间的最大差值,因此它是一个值,且是距离的最大值,不考虑曲线走势相似性等指标,公式如下:

    在这里插入图片描述

  2. 一个最简单的方法是遍历两个序列的每一对点,计算最大值即可。但是由于两个序列可能是不对齐的,因此需要先找到一条路径,然后在比较两个序列的每一对点,取最大值。核心就是:对齐序列

  3. Fréchet distance对齐的方法与DTW神似,可以参考:DTW(动态时间归整)算法与DTW,fastDTW的python算例

在这里插入图片描述
4. Fréchet distance认为:在两个不同采样点的序列中,尝试找到一种,能使彼此配对的值的距离的和最小的路径,这条路径就是核心路径,配对的过程是:
- 捏着线段A的一个待匹配的点(如下图的点d)
- 首先判断 min( ab, ac, bd)
- 在上面的min的优胜者与dc比较,选择这两个中的最大的值,作为真实的配对点
- 因此下图中目测配对的是bd(假如bd应该比ac短)

在这里插入图片描述
5. 在计算时,使用递归的方法可以在寻找路径的同时计算距离,代码详解与示例参考下面的内容

示例代码

import numpy as np


def cal_frechet_distance(curve_a: np.ndarray, curve_b: np.ndarray):
    # 距离公式,两个坐标作差,平方,累加后开根号
    def euc_dist(pt1, pt2):
        return np.sqrt(np.square(pt2[0] - pt1[0]) + np.square(pt2[1] - pt1[1]))

    # 用递归方式计算,遍历整个ca矩阵
    def _c(ca, i, j, P, Q):  # 从ca左上角开始计算,这里用堆的方法把计算序列从右下角压入到左上角,实际计算时是从左上角开始
        if ca[i, j] > -1:
            return ca[i, j]
        elif i == 0 and j == 0:  # 走到最左上角,只会计算一次
            ca[i, j] = euc_dist(P[0], Q[0])
        elif i > 0 and j == 0:  # 沿着Q的边边走
            ca[i, j] = max(_c(ca, i - 1, 0, P, Q), euc_dist(P[i], Q[0]))
        elif i == 0 and j > 0:  # 沿着P的边边走
            ca[i, j] = max(_c(ca, 0, j - 1, P, Q), euc_dist(P[0], Q[j]))
        elif i > 0 and j > 0:  # 核心代码:在ca矩阵中间走,寻找对齐路径
            ca[i, j] = max(min(_c(ca, i - 1, j, P, Q),  # 正上方
                               _c(ca, i - 1, j - 1, P, Q),  # 斜左上角
                               _c(ca, i, j - 1, P, Q)),  # 正左方
                           euc_dist(P[i], Q[j]))
        else:  # 非法的无效数据,算法中不考虑,此时 i<0,j<0
            ca[i, j] = float("inf")
        return ca[i, j]

    # 这个是给我们调用的方法
    def frechet_distance(P, Q):
        ca = np.ones((len(P), len(Q)))
        ca = np.multiply(ca, -1)
        dis = _c(ca, len(P) - 1, len(Q) - 1, P, Q)  # ca为全-1的矩阵,shape = ( len(a), len(b) )
        return dis

    # 这里构造计算序列
    curve_line_a = list(zip(range(len(curve_a)), curve_a))
    curve_line_b = list(zip(range(len(curve_b)), curve_b))
    return frechet_distance(curve_line_a, curve_line_b)


if __name__ == '__main__':
    a_array = np.array([2, 4, 6, 8])
    b_array = np.array([2, 3, 4, 6, 5, 7, 8])
    result = cal_frechet_distance(a_array, b_array)
    print(result)  # 打印结果
  • 13
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
离散 Fréchet 距离是用于测量两个离散曲线之间相似程度的一种度量方法。它基于 Fréchet 距离的概念,但适用于离散曲线而不是连续曲线。 在计算离散 Fréchet 距离时,我们考虑两个离散曲线中的每个点对之间的距离。对于每个点对,我们可以通过直线距离、曼哈顿距离或其他距离度量方法来计算它们之间的距离。然后,我们通过计算最小的距离来确定两个曲线之间的 Fréchet 距离。 具体地说,我们通过以下步骤计算离散 Fréchet 距离: 1. 创建一个大小为 m × n 的矩阵 D,其中 m 和 n 分别为两个离散曲线的点数。 2. 初始化矩阵 D 的第一行和第一列,使得 D[i,0] 和 D[0,j] 分别等于曲线1和曲线2的第 i 个点和第 j 个点之间的距离。 3. 对于每个 D[i,j],计算曲线1的第 i 个点和曲线2的第 j 个点之间的距离。这可以使用直线距离、曼哈顿距离或其他距离度量方法来实现。 4. 使用递归的方式填充矩阵 D,直到达到右下角的 D[m,n]。 5. 返回 D[m,n] 的值,它代表了曲线1和曲线2之间的离散 Fréchet 距离。 离散 Fréchet 距离可以用于比较离散曲线的相似性,例如路径规划中的路径匹配、图像处理中的轮廓匹配等。该距离度量方法的优势在于它考虑了曲线上的点对之间的相对位置,因此可以更准确地捕捉到曲线的形状相似程度。但是,离散 Fréchet 距离计算复杂度较高,需要使用动态规划或其他优化算法来加快计算速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值