繁体   English   中英

基于离散点的手势检测算法

[英]Gesture detection algorithm based on discrete points

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

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

接收输入

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


存储模式和输入

模式(预期输入)

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

输入(从用户收到)

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

想象一下,用户可以非常快速地执行一些手势(并在输入阅读器只读取三帧时完成它)。 无法可靠地比较模式和输入:

输入速度太快,无法读取

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

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

考虑一下:完成一个手势会给你一半的输入帧,就像模式包含的那样。 用户已经以“正常”速度移动,因此,为了简化算法,您可以将模式“哑”下2倍,然后直接将输入坐标与模式坐标进行比较。

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


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

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

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

输入点与模式点不匹配

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

图案比输入更密集

现在,你不必妥协,因为3r基本上肯定是在手势模式上。 图案密度略有下降,因此可以很好地匹配输入。


定位

相对定位

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

将输入与坐标系相关联

正常化

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

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

  1. 按照前面的项目符号将输入与坐标系相关联
  2. 找到任意两个输入点之间的最大水平和垂直距离(称为RecMaxHRecMaxV
  3. 找到任意两个模式点之间的最大水平和垂直距离(称为ExpMaxHExpMaxV
  4. 将所有输入点的x坐标乘以ExpMaxH/RecMaxH
  5. 通过ExpMaxV/RecMaxV多个所有输入点的y坐标

标准化输入以匹配模式的大小

您现在有两组可以比较的更相似的点。 规范化可以比这更详细; 例如,您可以一次标准化3个点的集合以获得令人难以置信的相似图像(但您可能必须为每个模式执行此操作,然后比较所有差异的总和以找到最可能的匹配模式)。

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


何时测量输入

用户驱动

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

优点:

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

缺点:

  • 用户不太友好。 用户必须走出他/她的方式来触发手势录制。

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

不变

您的程序会以指定的间隔记录手势坐标(这可以缩小为“记录是否有移动,否则不存储坐标”)。 您必须做出决定:在决定当前存储的动作不是可识别的手势之前,您将记录多少“帧”?

将坐标存储在缓冲区中:队列1.5或2(要谨慎),只要您愿意记录的最大帧数。

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

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

  • 如果确定缓冲区中的前x个帧可能无法匹配模式(由于它们的顺序或定位),请将它们从队列中删除。

优点:

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

缺点:

  • 更复杂的算法
  • 更重的计算

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


算法

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

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

如果您正在使用恒定测量:

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


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM