使用 OpenCV 进行记分牌数字识别
Posted
技术标签:
【中文标题】使用 OpenCV 进行记分牌数字识别【英文标题】:Scoreboard digit recognition using OpenCV 【发布时间】:2011-12-25 14:22:18 【问题描述】:我正在尝试从您可以在高中体育馆找到的典型记分牌中提取数字。我将每个数字都放在数字“闹钟”字体中,并设法从视频源中正确透视、阈值并提取给定数字
这是我的模板输入示例
我的问题是没有一种分类方法可以准确地确定所有数字 0-9。我尝试了几种方法
1) Tesseract OCR - 这个总是搞砸 4 并且经常返回奇怪的结果。只需使用命令行版本。如果我真的尝试用“闹钟”字体训练它,我每次都会得到未知字符。
2) 使用 OpenCV 的 kNearest - 我搜索包含我的模板图像 (0-9) 的数据库,并查看哪个是最近的。我经常混淆 3/1 和 7/1
3) cvMatchShapes - 这个相当糟糕,它通常无法区分每个输入数字的两个数字之间的差异
4) 切线距离 - 这是最近的,但输入和我的模板之间的最小切线距离最终每次都将“7”映射到“1”
对于这样一个简单的问题,我真的很茫然。我觉得我已经很好地清理了输入,这是一个相当简单的分类案例,但我无法获得足够可靠的东西来实际使用。任何关于在哪里寻找分类算法或如何正确使用它们的想法都将不胜感激。我没有清理输入吗?那么更好的输入数据库呢?我不知道我还能用什么来输入,此时每个数字和模板看起来都很准确。
【问题讨论】:
【参考方案1】:在这种情况下应该可以正常工作的经典数字识别是裁剪数字周围的图像并将其调整为 4x4 像素。
离散余弦变换 (DCT) 可用于进一步缩小搜索空间。您可以选择前 4-6 个值。
使用这些值,训练分类器。 SVM 是一个很好的,在 OpenCV 中很容易获得。
它不像 emma 或 martin 的建议那么简单,但它更优雅,我认为更健壮。
根据输入的宽/高比,您可以选择不同的分辨率,例如 3x4。选择保留可读数字的最小的。
【讨论】:
我使用了 3x5 的图像(类似于数字显示中的行/列),它与 kNearest 搜索配合得很好。死了。谢谢!【参考方案2】:鉴于您的输入具有高度规则性,您可以定义一组图像的 7 个目标区域进行检查。每个区域应包含显示器的每个数字的 7 个部分之一的某个重要部分,但不能重叠。
然后您可以检查每个区域并对其中像素的颜色/亮度进行平均,以生成给定二进制状态的概率。如果您在所有领域的概率都很高,那么您可以轻松找出数字是什么。
它不像纯 ML 类型的算法那样优雅,但 ML 更适合不规则的输入,在这种情况下似乎不适用 - 所以你用优雅换取准确性。
【讨论】:
【参考方案3】:可能听起来很傻,但您是否尝试过简单地检查黑条垂直然后水平检查上半部分和下半部分 - 中心线的左侧和右侧?
【讨论】:
我针对我正在处理的问题实施了您的简单想法,并且效果很好。只需从左侧垂直检查大黑条,同时捕获第一个垂直条“统计信息”。【参考方案4】:如果您尝试使用 Tesseract 进行文本识别,请尝试传递的不是一个数字,而是多个重复的数字,有时它会产生更好的结果,here's the example。 但是,如果您正在计划一个商业软件,您可能想看看一个商业 OCR SDK。例如,尝试ABBYY FineReader Engine。免费使用的应用程序无法负担得起,但在业务方面,它可以为您的产品带来很好的价值。据我所知,ABBYY 提供最好的 OCR 质量,例如查看http://www.splitbrain.org/blog/2010-06/15-linux_ocr_software_comparison
【讨论】:
【参考方案5】:您希望您的记分卡图像输入 S 提供一个算法,将它们映射到 0,1,2,3,4,5,6,7,8,9。
令 V 表示整数的 n 元组的集合。
构造一个算法α,将每个图像S映射到一个n元组
(k1,k2,...,kn)
可以区分两个不同的记分牌数字。
如果你可以指定 α 的范围,那么你只需要收集 V 中与一个数字对应的向量即可解决问题。
我已经使用 Martin Beckett 的 idea 应用了这个想法,并且它有效。我最初的尝试是通过从左到右的垂直求和简单地注入 2 元组,第一个整数是图像列偏移量,第二个整数是“漂亮”垂直线的长度。
这不起作用 - 6 和 8 的图像将映射到相同的向量。所以我需要另一个 mini-info-capture 用于我的数字输入类型(它们不是记分牌),并且 3 元组信息向量可以解决问题。
【讨论】:
以上是关于使用 OpenCV 进行记分牌数字识别的主要内容,如果未能解决你的问题,请参考以下文章
Python,OpenCV使用KNN来构建手写数字及字母识别OCR
OpenCV-Python实战(番外篇)——利用 SVM 算法识别手写数字