如何使用openCV对模糊数字进行分类

时间:2016-06-05 18:52:27

标签: python opencv edge-detection number-recognition

我想从这种图片中捕捉数字。

enter image description here

我尝试从以下链接进行多尺度匹配。

http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/

我想知道的只是红色数字。但问题是,openCV识别/匹配模板的红色数字模糊。是否有其他可能的方法可以在黑色背景上检测到这个红色数字?

2 个答案:

答案 0 :(得分:19)

分类数字

您在评论中澄清说您已经隔离了图像预检测的数字部分,因此我将从该假设开始。

也许您可以通过将其视为手写数字来近似数字的透视效果和“模糊”。在这种情况下,有一个名为mnist的分类训练的手写数字的着名数据集。

Yann LeCun在此mnist hand-written dataset列举了此数据集的最新技术。

在光谱的远端,卷积神经网络产生outrageously low error rates(1%误差的分数)。对于更简单的解决方案,使用去偏移,噪声消除,模糊和2像素移位的k-最近邻居产生大约1%的误差,并且实现起来要快得多。 Python opencv has an implementation。具有偏斜校正的神经网络和支持向量机也具有一些非常令人印象深刻的性能。

请注意,卷积网络没有您选择自己的功能,因此这里重要的色差信息可能仅用于缩小感兴趣区域。您定义特征空间的其他方法可能更精确地包含已知的色差。

Python在极好的软件包sklearn中支持了很多机器学习技术 - here are examples of sklearn applied to mnist如果您正在寻找python中机器学习的教程解释,sklearn's own tutorial is very verbose

从sklearn链接: Classifying mnist

如果您学习使用此方法,那些是您尝试分类的项目。为了强调开始训练这些基于机器学习的分类器是多么容易,这里是链接sklearn包中示例代码的简略部分:

digits = datasets.load_digits() # built-in to sklearn!
data = digits.images.reshape((len(digits.images), -1))

# Create a classifier: a support vector classifier
classifier = svm.SVC(gamma=0.001)

# We learn the digits on the first half of the digits
classifier.fit(data[:n_samples / 2], digits.target[:n_samples / 2])

如果您与openCv结合(可能是因为您希望将来移植到实时系统),opencv3 / python has a tutorial on this exact topic too!他们的演示使用k-nearest-neighbor(在LeCun页面中列出),但他们也have svms以及sklearn中的许多其他工具。他们使用SVM的ocr页面使用了deskewing,这可能对您的问题中的透视效果有用:

Deskewed digit

更新:我在您的图片上使用了上面概述的开箱即用的滑雪图像方法,严重裁剪,正确分类很多需要更多测试才能确定这是否是实践中的rhobust

enter image description here

^^这个微小的图像是您在问题中嵌入的8x8裁剪图像。 mnist是8x8图像。这就是为什么它在不到一秒的时间内用skimage中的默认参数进行训练。

我通过使用

将其缩放到mnist范围,将其转换为正确的格式
number = scipy.misc.imread("cropped_image.png")
datum  =  (number[:,:,0]*15).astype(int).reshape((64,))
classifier.predict(datum) # returns 8

我没有改变示例中的任何其他内容;在这里,我只使用第一个通道进行分类,没有智能特征计算。 15看起来对我来说是正确的;你需要调整它以达到目标范围或(理想情况下)提供你自己的训练和测试集

对象检测

如果您没有隔离图像中的数字,则需要一个物体探测器。关于这个问题的文献空间是巨大的,我不会开始那个兔子洞(谷歌中提琴和琼斯,也许?)This blog涵盖了python中“滑动窗口”探测器的基本原理。 Adrian Rosebrock看起来他甚至都是SO的贡献者,那个页面有一些很好的例子,基于opencv和基于python的对象探测器相当教化(你实际上在你的问题中链接到那个博客,我没有意识到)。

简而言之,在整个图像中对窗口进行分类,然后选择信心最高的窗口。缩小与感兴趣区域的搜索空间当然会在所有性能领域产生巨大的改进

答案 1 :(得分:2)

您可以使用以下几项优势:

  • 数字在黑色矩形边框内,颜色为
  • 该数字似乎是一个分段的LCD型显示器,如果是这样,只有有限数量的段关闭或打开。

所以我建议你:

  • 校准相机并预处理图像以消除镜头失真
  • 整理显示矩形:
    • 使用霍夫的交叉点检测显示矩形 线条,或边缘检测,然后轮廓检测,然后选择 最大,最方便的轮廓
    • 使用GetPerspectiveTransform获取图像坐标和理想矩形之间的变换,然后变换输入图像 使用WarpPerspective
  • 将图像分割为R,G和B通道并计算r - avg(g, b),这有点依赖于照明,但应该给出类似的结果:

    cleaned up number image

  • 然后尝试对此进行模式匹配,或者重新分段图像并尝试查找哪些显示段被点亮,或者通过OCR包运行。