6

在我看来,我目前面临一个相当普遍的问题,应该很容易解决,但到目前为止我所有的方法都失败了,所以我向你寻求帮助。

我认为这个问题最好用一些插图来解释。我有一些像这两个这样的模式:

模式 1 模式 3

我也有一张像(可能更好,因为这张照片的来源照片光线很差)这样的图片:

图片

(注意模板是如何缩放到适合图像大小的)

最终目标是确定用户是否显示拇指向上/拇指向下手势以及介于两者之间的一些角度的工具。所以我想将图案与图像进行匹配,看看哪一个最像图片(或者更准确地说,是手所显示的角度)。我知道拇指在图案中显示的方向,所以如果我找到看起来相同的图案,我也有角度。

我正在使用 OpenCV(使用 Python 绑定)并且已经尝试过 cvMatchTemplate 和 MatchShapes 但到目前为止它并不能真正可靠地工作。

我只能猜测为什么 MatchTemplate 失败了,但我认为带有较小白色的较小图案完全适合图片的白色区域,从而创建了最佳匹配因子,尽管很明显它们看起来并不相同。

是否有一些隐藏在 OpenCV 中的方法我还没有找到,或者对于那些我应该重新实现的问题是否有已知的算法?

新年快乐。

4

3 回答 3

7

一些简单的技术可以奏效:

  1. 在二值化和分割之后,找到 Feret 的 blob 直径(也就是点之间的最远距离,或长轴)。
  2. 找到点集的凸包,对其进行泛洪填充,并将其视为连通区域。用拇指减去原始图像。不同之处在于拇指和拳头之间的区域,并且该区域相对于重心的位置应该为您提供旋转指示。
  3. 对每个点到斑点边缘的距离使用分水岭算法。这可以帮助识别连接的薄区域(拇指)。
  4. 将最大的圆(或最大的内接多边形)拟合到 blob 中。扩大这个圆形或多边形,直到其边缘的一部分与背景重叠。从原始图像中减去这个膨胀的图形;只剩下拇指。
  5. 如果手的大小一致(或相对一致),那么您还可以执行 N 次形态侵蚀操作,直到拇指消失,然后进行 N 次扩张操作以将拳头恢复到其原始近似大小。从原始 blob 中减去这个只有拳头的 blob 以获得拇指 blob。然后使用拇指斑点方向(费雷特直径)和/或相对于拳头斑点质心的质心来确定方向。

寻找临界点(强烈方向变化的区域)的技术比较棘手。最简单的情况是,您也可以使用角检测器,然后检查从一个角到另一个角的距离,以确定拇指内缘与拳头相遇的位置。

对于更复杂的方法,请查看 Kimia、Siddiqi 和 Xiaofing Mi 等作者关于形状分解的论文。

于 2011-12-30T17:06:36.450 回答
1

MatchTemplate似乎很适合您描述的问题。它以什么方式对您不利?如果您实际上像在示例图像中显示的那样很好地掩盖了竖起大拇指/拇指向下/中间拇指标志,那么您已经完成了最困难的部分。

MatchTemplate 不包括搜索空间中的旋转和缩放,因此您应该在您想要检测的所有旋转中从参考图像生成更多模板,并且您应该缩放模板以匹配找到的大拇指/大拇指的一般大小下降迹象。

[编辑] MatchTemplate 的结果数组包含一个整数值,该值指定图像中模板在该位置的拟合程度。如果使用 CV_TM_SQDIFF,则结果数组中的最小值是最佳拟合位置,如果使用 CV_TM_CCORR 或 CV_TM_CCOEFF,则它是最大值。如果您的缩放和旋转模板图像都具有相同数量的白色像素,那么您可以比较所有不同模板图像的最佳拟合值,并且总体上最佳拟合的模板图像就是您要选择的那个。

可以想象,有大量的旋转/缩放独立检测功能可以帮助您,但是规范您的问题以使用 MatchTemplate 是迄今为止最简单的。

对于更高级的东西,请查看SIFT基于 Haar 特征的分类器OpenCV 中可用的其他分类器之一

于 2011-12-27T14:56:11.083 回答
1

我认为如果你只计算通过白色的最短路径最短的两个点,你可以获得很好的结果。拇指指向的方向就是连接两点的线的方向。

您可以通过在白色区域上采样点并使用Floyd-Warshall轻松完成此操作。

于 2011-12-29T23:57:38.057 回答