准确的二进制图像分类

时间:2012-04-04 20:10:40

标签: python image-processing opencv ocr simplecv

我正在尝试从游戏板中提​​取项目的信件。目前,我可以检测游戏板,将其分割成各个方块并提取每个方块的图像。

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

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

首先,我计算每个图像的黑色像素数,并将其用作识别不同字母的方法,这对于受控输入图像效果较好。但是,我遇到的问题是,对于与这些图像略有不同的图像,我无法做到这一点。

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

有人知道什么是一个好的算法用于此吗?

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

  • 计算图像与每个字母图像之间的差异,以查看哪一个产生的误差最小。但是,这不适用于大型数据集。
  • 检测角落并比较相对位置。
  • ???

任何帮助将不胜感激!

7 个答案:

答案 0 :(得分:14)

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

功能提取

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

<强>分类

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

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

<强>评价

当然,你需要训练数据,即给出正确字母的图像特征向量。 以及评估流程的流程,例如交叉验证。


在这种情况下,您可能还想查看template matching。在这种情况下,您可以使用训练集中的可用模式对候选图像进行卷积。输出图像中的高值表示图案位于该位置的概率很高。

答案 1 :(得分:5)

这是一个认识问题。我个人使用PCA和机器学习技术(可能是SVM)的组合。这些是相当大的主题,所以我担心我不能真正详细说明,但这是最基本的过程:

  1. 收集你的训练图像(每个字母不止一个,但不要发疯)
  2. 标记它们(可能意味着很多东西,在这种情况下,它意味着将字母分组为逻辑组 - 所有A图像 - > 1,所有B图像 - > 2,等等)
  3. 训练你的分类器
    • 通过PCA分解运行所有内容
    • 将所有训练图像投影到PCA空间
    • 通过SVM运行投影图像(如果它是一个分类器,一次执行一个,否则一次完成。)
    • 保存您的PCA特征向量和SVM培训数据
  4. 运行识别
    • 加载到您的PCA空间
    • 加载SVM培训数据
    • 对于每个新图像,将其投影到PCA空间并要求您的SVM对其进行分类。
    • 如果您得到答案(数字),请将其映射回一封信(1 - > A,2 - > B等)。

答案 2 :(得分:4)

答案 3 :(得分:2)

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

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

以下是链接和代码:

Simple Digit Recognition OCR in OpenCV-Python

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

答案 4 :(得分:0)

答案 5 :(得分:0)

您可以尝试通过将训练数据(约50张1s,2s,3s ...... 9s)上传到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
    }
  ]
}

答案 6 :(得分:0)

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

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

我通过在图像文件名的开头“加盖”标识符来组织我的工作。然后,我可以对文件名(= identifier)进行排序。 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)可能指向多个字母。如果发生这种情况,则需要使用图片的其他属性来区分它们。

相关问题