13

我正在尝试从一个项目的游戏板上提取字母。目前,我可以检测游戏板,将其分割成单独的方块并提取每个方块的图像。

我得到的输入是这样的(这些是单独的字母):

在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述

起初,我计算了每张图像的黑色像素数量,并将其用作识别不同字母的方法,这对于受控输入图像来说效果不错。但是,我遇到的问题是,我无法对与这些略有不同的图像进行这项工作。

每个字母我有大约 5 个样本用于训练,这应该足够了。

有人知道为此使用什么好的算法吗?

我的想法是(在标准化图像之后):

  • 计算图像和每个字母图像之间的差异,看看哪个产生的错误最少。不过,这不适用于大型数据集。
  • 检测角点并比较相对位置。
  • ???

任何帮助,将不胜感激!

4

7 回答 7

14

我认为这是某种监督学习。您需要对图像进行一些特征提取,然后根据您为每个图像计算的特征向量进行分类。

特征提取

乍一看,特征提取部分看起来像是Hu-Moments的一个很好的场景。只需计算图像矩,然后从中计算cv::HuMoments。然后你有一个 7 维实值特征空间(每个图像一个特征向量)。或者,您可以省略此步骤并将每个像素值用作单独的特征。我认为这个答案中的建议是朝着这个方向发展的,但是增加了 PCA 压缩来降​​低特征空间的维度。

分类

至于分类部分,你几乎可以使用任何你喜欢的分类算法。您可以对每个字母使用 SVM(二进制是 - 否分类),您可以使用 NaiveBayes(最大可能字母是什么),或者您可以使用 k-NearestNeighbor(kNN,特征空间中的最小空间距离)方法,例如弗兰

特别是对于基于距离的分类器(例如 kNN),您应该考虑对特征空间进行归一化(例如,将所有维度值缩放到欧几里德距离的某个范围,或使用诸如马氏距离之类的东西)。这是为了避免在分类过程中过度表示具有较大值差异的特征。

评估

当然,您需要训练数据,即给定正确字母的图像特征向量。还有一个过程,用于评估您的过程,例如交叉验证。


在这种情况下,您可能还想看看模板匹配。在这种情况下,您会将候选图像与训练集中的可用模式进行卷积。输出图像中的高值表示图案位于该位置的可能性很大。

于 2012-04-04T20:55:28.047 回答
5

这是一个识别问题。我个人会结合使用PCA和机器学习技术(可能是SVM)。这些都是相当大的话题,所以恐怕我不能详细说明,但这是非常基本的过程:

  1. 收集你的训练图像(每个字母不止一张,但不要发疯)
  2. 给它们贴上标签(可能意味着很多东西,在这种情况下,这意味着将字母分组为逻辑组——所有 A 图像 -> 1,所有 B 图像 -> 2 等)
  3. 训练你的分类器
    • 通过 PCA 分解运行一切
    • 将所有训练图像投影到 PCA 空间中
    • 通过 SVM 运行投影图像(如果它是一类分类器,一次做一个,否则一次做所有。)
    • 节省您的 PCA 特征向量和 SVM 训练数据
  4. 运行识别
    • 加载到您的 PCA 空间
    • 加载您的 SVM 训练数据
    • 对于每个新图像,将其投影到 PCA 空间并要求您的 SVM 对其进行分类。
    • 如果您得到答案(一个数字),请将其映射回一个字母(1 -> A、2 -> B 等)。
于 2012-04-04T20:28:36.837 回答
4
于 2012-04-04T21:02:09.473 回答
3

几天前我遇到了类似的问题。但这是数字识别。不适用于字母。

我使用 OpenCV 中的 kNearestNeighbour 为此实现了一个简单的 OCR。

以下是链接和代码:

OpenCV-Python 中的简单数字识别 OCR

为字母实现它。希望它有效。

于 2012-04-05T05:42:42.633 回答
1

您可以尝试通过将训练数据(约 50 张 1s、2s、3s....9s 的图像)上传到demo.nanonets.ai(免费使用)来构建模型

1) 在此处上传您的训练数据:

演示.nanonets.ai

2)然后使用以下(Python代码)查询API:

import requests
import json
import urllib
model_name = "Enter-Your-Model-Name-Here"
url = "http://images.clipartpanda.com/number-one-clipart-847-blue-number-one-clip-art.png"
files = {'uploadfile': urllib.urlopen(url).read()}
url = "http://demo.nanonets.ai/classify/?appId="+model_name
r = requests.post(url, files=files)
print json.loads(r.content)

3)响应看起来像:

{
  "message": "Model trained",
  "result": [
    {
      "label": "1",
      "probability": 0.95
    },
    {
      "label": "2",
      "probability": 0.01
    },

     ....

    {
      "label": "9",
      "probability": 0.005
    }
  ]
}
于 2016-12-13T11:33:34.150 回答
0

请看这两个与OCR相关的答案

使用 OpenCV 进行记分牌数字识别

和这里

屏幕截图中低分辨率文本的 OCR

于 2012-04-05T05:38:08.717 回答
0

由于您的图像来自棋盘游戏的计算机屏幕,因此变化不能“太疯狂”。我刚刚得到了解决同一类型问题的方法。我通过裁剪到“核心”来标准化我的图像。

每个字母 5 个样本,您可能已经拥有完整的覆盖范围。

我通过在图像文件名的开头“标记”标识符来组织我的工作。然后我可以对文件名(=标识符)进行排序。Windows 资源管理器允许您在打开中图标的情况下查看目录。我将通过“假重命名”操作获取标识符并将其复制到 Python 程序中。

这是一些可以针对任何这些问题进行修改的工作代码。

def getLetter(im):
    area = im.height * im.width
    white_area = np.sum(np.array(im))
    black_area = area - white_area
    black_ratio = black_area / area           # between 0 and 1
    if black_ratio == .740740740740740 or \
       black_ratio == .688034188034188 or \
       black_ratio == .7407407407407407:  
       return 'A'
    if black_ratio == .797979797979798:
       return 'T'
    if black_ratio == .803030303030303:
       return 'I'
    if black_ratio == .5050505050505051 or \
       black_ratio == .5555555555555556:
       return 'H'
    ############ ... etc.

    return '@' # when this comes out you have some more work to do

注意:同一个标识符(这里我们使用black_ratio)可能指向多个字母。如果发生这种情况,您需要使用图像的另一个属性来区分它们。

于 2019-02-05T02:20:06.607 回答