【问题标题】:Gesture detection algorithm based on discrete points基于离散点的手势检测算法
【发布时间】:2013-12-29 01:54:23
【问题描述】:

我正在尝试解决将人类生成的手势与已知手势相匹配的问题。人类生成的手势将由一系列点表示,这些点需要插入到路径中并与现有路径进行比较。下图显示了我要比较的内容

您能否用我可以阅读的资源或概念来帮助我指出正确的方向,以构建匹配这两条路径的算法?我以前没有这样做的经验,所以任何见解都会受到赞赏。

【问题讨论】:

  • 这些路径是如何存储的?
  • 存储它们的最佳方式是什么?作为许多点的序列,或者作为一个函数,或者其他方式?
  • 看看here。他用代码和东西做了一个很酷的演示。

标签: algorithm gesture gesture-recognition


【解决方案1】:

接收输入

在某个时间间隔测量输入。每 xx 毫秒,测量用户手/手指/触控笔的坐标。


存储模式和输入

模式(预期输入)

修改图案。它目前是一个连续的“功能”,但很难测量输入。在某个间隔使用离散点。此间隔可以非常短,具体取决于您要求手势的准确程度。事实上,它应该很短;比较的点越多越好(我将在下一节中更好地解释这一点)。

输入(来自用户)

在测量输入时,输入测量间隔需要足够短,以便接收到的每对连续输入点足够接近以与预期点进行比较。

假设用户非常快速地执行了某个手势(并在您的输入阅读器仅读取三帧时完成)。无法可靠地比较模式和输入:

为避免这种情况,您的输入阅读器必须有一个相对较短的间隔。不过,这可能不是一个大问题,因为大多数硬件甚至可以读取最快的人类手势。

回到模式:它们应该总是足够详细,以包含比任何可能的输入更多的点。更多的预期点可以提高准确性。如果用户移动缓慢,输入将有更多的点;如果他们移动得很快,输入就会减少。

考虑一下:完成一个手势可以为您提供模式所包含的输入帧的一半。用户以“正常”速度移动,因此,为了简化算法,您可以将图案“缩小”2 倍,然后直接将输入坐标与图案坐标进行比较。

这种方法比想到的替代方法更容易(见下一节)。


模式“密度”(坐标频率)

如果您的预期点数较少,则必须进行近似以匹配输入。

这是一个“极端”的例子,但它证明了这个概念。鉴于这种模式和输入:

无法可靠地将点 3r 与点 2 或点 3 进行比较,因此您必须使用点 2、3 和 3r 的某些功能来确定 3r 是否在正确的路径上。现在考虑相同的输入,但模式的密度更高:

现在,您不必妥协,因为 3r 本质上是肯定在手势模式上的。模式密度的轻微降低会使其与输入匹配得很好。


定位

相对定位

您可能希望在某个空间平面的任何位置都允许该手势,而不是比较绝对位置(例如在触摸屏上)。为此,您必须将输入的起点与某个坐标系相关联。

标准化

为了方便用户,允许在“大小”范围内完成手势。您不想比较原始数据,因为输入平面的大小可能与模式平面的大小不匹配。

在 x 和 y 方向标准化输入以匹配模式的大小。 不要保持纵横比。

  1. 将输入与坐标系相关联,如上一个项目符号所述
  2. 找出任意两个输入点之间的最大水平和垂直距离(称它们为RecMaxHRecMaxV
  3. 找出任意两个模式点之间的最大水平和垂直距离(称它们为ExpMaxHExpMaxV
  4. 将所有输入点的 x 坐标乘以 ExpMaxH/RecMaxH
  5. 将所有输入点的 y 坐标乘以 ExpMaxV/RecMaxV

您现在有两组更相似的点可以进行比较。规范化可以比这更详细;例如,您可以一次归一化 3 个点的集合以获得非常相似的图像(但您可能必须对每个模式都这样做,然后比较所有差异的总和以找到最可能匹配的模式)。

我建议将所有手势的模式存储为相同大小的图形;在测量输入与可能的模式匹配的接近度时减少计算量。


何时测量输入

用户驱动

想象一个按钮,当单击/激活时,会导致您的程序开始测量输入。这类似于谷歌的语音搜索,它不会不断地记录和搜索;相反,您可以说“Ok Jarvis”或点击方便的麦克风图标并开始说出您的问题。

好处:

  • 简化算法
  • 防止用户无意触发事件。想象一下,如果您所说的每个单词都经过分析并作为搜索查询的一部分发送给 Google。有时你只是不想做任何事情。

缺点:

  • 对用户不太友好。用户必须不遗余力地触发手势录制。

例如,如果您正在编写手势搜索(荒谬的示例),这可能是更好的实现方法。没有人希望他们所做的每一个动作都被解释为您的应用程序中的一个动作。但是,如果您正在编写 Kinect 风格或基于手势的游戏,您可能希望不断记录和寻找手势。

常数

您的程序以指定的时间间隔不断地记录手势坐标(这可以简化为“如果有运动则记录,否则不存储坐标”)。您必须做出决定:在确定当前存储的动作不是可识别的手势之前,您将记录多少“帧”?

将坐标存储在缓冲区中:队列长度是您愿意记录的最大帧数的 1.5 或 2 倍(谨慎起见)。

  • 一旦您确定此缓冲区中存在与模式匹配的帧序列,执行该手势的结果并清除队列。

  • 如果下一个手势有可能是最近手势的“选项”,请将应用程序状态记录为“当前等待____手势的选项”,然后等待选项出现。

  • 如果确定缓冲区中的前 x 帧不可能匹配模式(因为它们的顺序或位置),则将它们从队列中删除。

好处:

  • 允许更动态地处理手势
  • 自动识别用户输入

缺点:

  • 更复杂的算法
  • 计算量更大

如果您正在编写基于实时输入运行的游戏,这可能是正确的选择。


算法

如果您使用的是用户驱动的识别:

  1. 在允许的时间范围内记录所有输入(或直到用户表示他们已完成)
  2. 要评估输入,请降低模式的密度以匹配输入的密度
  3. 将输入与坐标系相关联
  4. 标准化输入
  5. 使用函数比较的方法(此计算的松散程度取决于您:标准差、方差、值的总差等),并选择差异最小的可能性。
  6. 如果没有足够相似的可能性来满足您要求的阈值(您必须决定这一点),请不要接受输入。

如果您使用恒定测量:

在您的缓冲区中,将从 frame_multiples 的每个倍数(您决定)开始的 max_sequence_size(您决定)序列视为可能的手势。例如,如果我所有可能的手势最长为 20 帧,并且我相信每 5 帧就会开始一个新手势(并且我不会丢失这 5 帧中的任何关键数据),我将比较每个部分缓冲区的所有可能手势(0-19、5-24、10-29 等部分)。当 frame_multiples 减少时,这是更繁重的计算。对于完美的测量,frame_multiples 为 1(但这可能不合理)。


希望您喜欢阅读这个答案,就像我喜欢写它一样。我以前从未这样做过,但你以一种不常见的方式激起了我的兴趣。 编辑并改进我的答案!如果有部分看起来不完整,请添加。我对(尤其是更有经验的)回应和批评非常好奇。

【讨论】:

  • 你的最后一段让我很困惑。您的整个答案是猜测,还是您以前在这方面做过工作?
  • @stackoverflowuser2010 我没做过这方面的工作,所以我猜你会认为这是猜测。
猜你喜欢
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2015-08-25
  • 2019-01-09
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多