准确的二进制图像分类

14
我正在尝试从游戏板上提取字母以供项目使用。目前,我可以检测到游戏板,将其分割成单个正方形,并提取每个正方形的图像。
我得到的输入如下(这些是单个字母): enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here 起初,我是通过计算每个图像中黑色像素的数量来识别不同字母的方法,对于控制输入图像,这种方法效果还不错。然而,我的问题在于,这种方法无法处理与这些图像略有不同的图像。
我有大约5个用于训练的每个字母样本,这应该足够了。
有人知道应该使用什么好的算法吗?
我的想法是(在归一化图像之后):
- 计算每个字母图片与所有字母图片之间的差异,以查看哪一个产生的误差最小。但这对于大型数据集不起作用。 - 检测角落并比较相对位置。 - ???
任何帮助将不胜感激!

嘿,我尝试在一些测试图像上使用Tessearact,并对它们进行了轻微的膨胀处理,但它失败得很惨(即使将分割模式设置为“一个单词”)。在我看来,OCR对于这种情况来说有点过度杀伤力,因为每个图像都非常相似。 - Blender
1
缩放和旋转不变性怎么样? - moooeeeep
旋转可以忽略不计,不会比水平压缩更扭曲字母。至于比例,我将每个图像归一化到固定大小。 - Blender
7个回答

14
我认为这是一种监督式学习。您需要对图像进行某些特征提取, 然后根据您为每个图像计算的特征向量进行分类。
特征提取: 乍一看,特征提取部分似乎是 Hu-Moments 的一个好场景。只需计算 image moments, 然后从中计算 cv :: HuMoments。然后你就有了一个7维实值特征空间 (每个图像一个特征向量)。 或者,您可以省略此步骤,并将每个像素值用作单独的特征。我认为 this answer 中的建议是走这个方向,但添加了PCA压缩以减少特征空间的维数。
分类:
关于分类部分,您可以使用几乎任何您喜欢的分类算法。您可以为每个字母使用SVM(二元是-否分类),您可以使用NaiveBayes(什么是最大可能的字母),或者您可以使用k-NearestNeighbor(kNN,特征空间中的最小空间距离)方法,例如flann
特别是对于基于距离的分类器(例如kNN),您应该考虑对特征空间进行归一化处理(例如将所有维度值缩放到某个范围以进行欧几里得距离,或使用诸如马氏距离之类的东西)。这是为了避免在分类过程中过度表示具有大差异值的特征。
评估
当然,您需要训练数据,即给出正确字母的图像特征向量。还需要一个过程来评估您的过程,例如交叉验证。
在这种情况下,您可能还想查看模板匹配。 在这种情况下,您将使用训练集中可用的模式卷积候选图像。 输出图像中的高值表示该位置存在该模式的良好概率。

非常感谢您的帮助!我已经计算出了每个图像的Hu矩,但是分类过程中出现了很多错误,让我感到困惑。希望在接下来的一天左右能够解决问题,并看看它的表现如何! - Blender
刚刚让分类器正常工作了!它对我的训练数据有100%的准确率(当然),但在处理新输入时有些困难。我打算使用更准确的样本再进行一些训练。 - Blender
仅作为状态更新,我发现拥有高质量的训练数据和图像并不是一个好主意。当我将我的图像调整为(奇怪的是)5px x 5px 时,我的准确性提高到了100%。 - Blender
1
@Blender 这是一个相当奇怪的结果。你是如何计算准确度的?无论如何,如果这是一个研究项目,而你又不能解释为什么它能够工作,那可能会成为你的问题。 - Simon Bergot
这不是一个正式的研究项目,而是我在业余时间尝试学习机器学习和图像处理。我认为计算出的Hu矩对于不同的图像类别来说不够明显,这降低了K-means算法正确分类输入图像的能力。我目前将图像转换为15x15的1和0矩阵(1代表黑色),然后将它们展平为255个元素的列表。这使得我可以更准确地处理任意输入。非常感谢您的帮助! - Blender

5
这是一个识别问题。我个人会使用PCA和机器学习技术(可能是SVM)的组合。这些都是相当大的主题,所以我恐怕不能详细解释太多,但以下是非常基本的过程:
1. 收集训练图像(每个字母至少一个,但不要太多)。 2. 对它们进行标记(可能意味着很多事情,在这种情况下,它意味着将字母分组成逻辑组--所有A图像-> 1,所有B图像-> 2等)。 3. 训练分类器 - 运行所有内容通过PCA分解。 - 将所有训练图像投影到PCA空间中。 - 将投影后的图像通过SVM运行(如果它是单类分类器,则逐个运行,否则一次性运行所有)。 - 保存PCA特征向量和SVM训练数据。 4. 进行识别 - 加载PCA空间。 - 加载SVM训练数据。 - 对于每个新图像,将其投影到PCA空间中,并要求SVM对其进行分类。 - 如果得到答案(一个数字),则将其映射回一个字母(1-> A,2-> B等)。

4

我已经阅读了第二个链接,似乎我已经在做这件事情了(比较不同的像素并找到最小化误差的图像)。第一个链接有点隐晦,没有很好地解释发生了什么,但是感谢提供链接!我会研究一下第一个链接的工作原理。 - Blender

3

我几天前遇到了一个类似的问题,不过是数字识别,而不是字母。

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

以下是链接和代码:

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

将其用于字母。希望它能起作用。


这个答案在我实际编写算法时非常有帮助。谢谢! - Blender

1
你可以尝试通过上传训练数据(约50张 1 到 9 的数字图片)到 demo.nanonets.ai 来构建模型(免费使用)。
1)在这里上传你的训练数据:

demo.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
    }
  ]
}

0

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),可能指向多个字母。如果发生这种情况,您需要使用图像的另一个属性来区分它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接