【问题标题】:Shape Recognition形状识别
【发布时间】:2012-07-25 08:13:31
【问题描述】:

我需要实现一个简单的 Android 应用程序,它允许用户在他们的手机上绘制一个“简单”的形状(圆形、三角形等),然后询问服务器所绘制的形状是否与其数据库中的一个形状相匹配,其中包括数量较少的形状(假设

A.重新调整大小并裁剪输入图像,使其与数据库中的图像具有相同的比例

B.将输入图像旋转一个小角度(比如 15 度)x 次(在本例中为 24),并尝试将这些旋转中的每一个与 DB 中的每个形状进行匹配。

问题:

  1. 对于 A,最好的方法是什么?在将数据发送到服务器之前,我正在考虑在 Android 应用程序中实现这一步。
  2. 对于 B,比较仅包含一个形状的 2 个黑白像素图像的体面算法是什么?
  3. 有没有更好/更简单的实现方式?一个也有实现的解决方案是可取的。

PS:我可以看到很多人在这里讨论过类似的话题,但我似乎找不到足够符合我要求的东西。

【问题讨论】:

标签: android image-processing shapes image-recognition


【解决方案1】:

机器学习方法

你选择一些描述轮廓的特征,选择一些分类方法,准备一个标记轮廓的训练集,训练分类器,在程序中使用它。

轮廓特征。给定轮廓(在图像中检测或根据用户输入构造),您可以计算旋转不变矩。最古老最广为人知的是一组Hu moments

您还可以考虑诸如偏心率、面积、凸度缺陷、质心距离函数的 FFT 变换等轮廓特征。

分类器。现在您需要训练分类器。支持向量机、神经网络、决策树、贝叶斯分类器是一些流行的方法。有many methods to choose from。如果您选择 SVM,LIBSVM 是一个免费的 SVM 库,它也适用于 Java,也适用于 Android。

临时规则方法

您还可以使用多边形曲线近似轮廓(请参阅Ramer-Douglas-Peucker algorithm,OpenCV 库中有一个免费的实现,现在可在 Android 上使用)。对于某些简单的形式,如三角形或矩形,您可以轻松发明一些特别的启发式规则来“识别”它们(例如,如果闭合轮廓可以仅用三段和小误差来近似,那么它很可能是三角形;如果质心距离函数几乎为常数,且凸度缺陷为零,则很可能是圆形)。

【讨论】:

  • P.S.如果您选择使用轮廓,最好将用户输入保持为矢量形式(作为点序列)。有轮廓提取算法(一种在 OpenCV 库中实现),但您可以避免此过程并保留原始输入数据。
  • 感谢您抽出宝贵时间为我提供这么多选择。我将在下周进行这项工作,我会看看进展如何。我将首先根据您的建议尝试一些简单的启发式方法,如果结果令人失望,我会尝试 libsvm,因为我以前使用过它。
  • @MihaiTodor 我通常在 PC 上试验 OpenCV、libsvm 和 Python,找到最有效的方法和功能,然后将训练好的模型放入 Android 资源中,只计算相同Java 中的功能。
【解决方案2】:

您可以使用supervised learning 方法。对于您要解决的问题,我认为像Naive BayesKNN 等简单的分类器应该会给您带来很好的结果。

您需要从每个图像中提取特征。对于每个图像,您可以将它们保存在矢量中。让我们称之为特征向量。对于数据库中的图像,您已经知道形状的类型,因此您可以在特征向量中包含类型的 id。这将作为训练集。

一旦你有了训练集,你就可以训练你的分类器,每次你想对一个新的形状进行分类时,你只需要得到它的特征向量并用它来查询分类器。

我建议您使用比例和大小不变的功能,这样您就不必重新调整每个图像的大小,您只需比较一次而不是旋转它。

您可以快速搜索缩放/旋转不变特征并尝试它们。

【讨论】:

    【解决方案3】:

    由于这与手写识别非常相关,您可以使用简单的 hmm 算法将形状与预先学习的 db 进行比较。

    但对于更简单的方法,您可以检测图像中的角点,然后计算角点以检测形状。

    第一种方法可用于任何复杂的形状,而第二种方法仅适用于基本形状。

    【讨论】:

    • 计算角的想法很有趣。我会看看我能不能找到一个图书馆。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2012-02-26
    • 2011-07-29
    • 2016-04-22
    • 1970-01-01
    相关资源
    最近更新 更多