计算机视觉中的形状/图案匹配方法

问题描述 投票:0回答:3

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

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

Pattern 1 Pattern 3

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

Picture

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

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

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

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

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

新年快乐。

opencv computer-vision pattern-recognition
3个回答
7
投票

一些简单的技巧可以发挥作用:

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

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

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


1
投票

MatchTemplate 似乎很适合您描述的问题。它在哪些方面对你来说是失败的?如果您实际上像示例图像中显示的那样很好地掩盖了拇指向上/拇指向下/拇指中间的标志,那么您已经完成了最困难的部分。

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

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

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

有关更高级的内容,请查看 SIFTHaar 基于特征的分类器OpenCV 中提供的其他分类器之一


1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.