如何使用openCV对模糊数字进行分类
How to classify blurry numbers with openCV
我想从这种图片中捕捉数字。
我尝试了以下 link 的多尺度匹配。
http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
我只想知道红色数字。但问题是,对于 openCV recognize/match 模板,红色数字是模糊的。有没有其他可能的方法来检测这个黑色背景上的红色数字?
分类数字
你在评论中澄清说你已经隔离了图像预检测的数字部分,所以我会在这个假设下开始。
或许你可以把数字当作手写数字来近似透视效果和"blurriness"。在这种情况下,有一个著名的用于分类训练的手写数字数据集,称为 mnist。
Yann LeCun 在此处 mnist hand-written dataset 列举了该数据集的最新技术水平。
在频谱的远端,卷积神经网络产生 outrageously low error rates (fractions of 1% error). For a simpler solution, k-nearest neighbours using deskewing, noise removal, blurring, and 2 pixel shift, yielded about 1% error, and is significantly faster to implement. Python opencv has an implementation。具有去偏移功能的神经网络和支持向量机也有一些非常令人印象深刻的性能。
请注意,卷积网络不能让您选择自己的特征,因此此处重要的色差信息可能仅用于缩小感兴趣区域。定义特征 space 的其他方法可能会更精确地包含已知的色差。
Python 在很棒的包 sklearn 中支持很多机器学习技术 - here are examples of sklearn applied to mnist. If you're looking for an tutorialized explanation of machine learning in python, sklearn's own tutorial is very verbose
来自 sklearn link:
如果您学习使用这种方法,这些就是您要尝试分类的项目种类。为了强调开始训练这些基于机器学习的分类器是多么容易,这里是 linked 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! Their demo uses k-nearest-neighbor (listed in the LeCun page), but they also have svms 以及 sklearn 中的许多其他工具。他们使用 SVM 的 ocr 页面使用 deskewing,这可能对您问题中的透视效果有用:
更新: 我在你的图片上使用了上面概述的开箱即用的 skimage 方法,经过大量裁剪,正确分类.需要进行 很多 次测试才能确定这在实践中是否是 rhobust
^^ 这个小图像是您嵌入问题中的图像的 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 看起来对我来说是正确的;您需要对其进行调整以使其在目标范围内或(理想情况下)提供您自己的训练和测试集
对象检测
如果您还没有分离出图像中的数字,您将需要一个物体检测器。关于这个问题的文献 space 是巨大的,我不会从那个兔子洞开始(google Viola 和 Jones,也许吧?)This blog 涵盖了 "sliding window" python 中的检测器。 Adrian Rosebrock 看起来他甚至是 SO 的贡献者,并且该页面有一些很好的 opencv 示例和基于 python 的对象检测器相当教程(你实际上 link 在你的问题中访问了那个博客,我没有'意识到)。
简而言之,对图像进行 windows 分类并选择置信度最高的 window。使用感兴趣的区域缩小搜索 space 当然会在所有性能领域产生巨大的改进
你有一些可以利用的优势:
- 数字在黑色矩形边框和一种颜色内
- 该数字似乎是分段 LCD 类型的显示器,如果是这样的话,只有有限数量的段是关闭或打开的。
所以我建议你:
- 校准相机并对图像进行预处理以消除镜头失真
- 修正显示矩形:
- 使用 hough 的交集检测显示矩形
线,或边缘检测,然后进行轮廓检测,然后选择
最大、最方形的轮廓
- 使用
GetPerspectiveTransform
得到图像坐标和理想矩形之间的变换,然后变换输入图像
使用 WarpPerspective
将图像分成 R、G 和 B 通道并计算 r - avg(g, b)
,这有点依赖于光照,但应该给出如下内容:
- 然后尝试对此进行模式匹配,或者重新分割图像并尝试查找哪些显示段亮起,或者 运行 通过 OCR 包。
我想从这种图片中捕捉数字。
我尝试了以下 link 的多尺度匹配。
http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
我只想知道红色数字。但问题是,对于 openCV recognize/match 模板,红色数字是模糊的。有没有其他可能的方法来检测这个黑色背景上的红色数字?
分类数字
你在评论中澄清说你已经隔离了图像预检测的数字部分,所以我会在这个假设下开始。
或许你可以把数字当作手写数字来近似透视效果和"blurriness"。在这种情况下,有一个著名的用于分类训练的手写数字数据集,称为 mnist。
Yann LeCun 在此处 mnist hand-written dataset 列举了该数据集的最新技术水平。
在频谱的远端,卷积神经网络产生 outrageously low error rates (fractions of 1% error). For a simpler solution, k-nearest neighbours using deskewing, noise removal, blurring, and 2 pixel shift, yielded about 1% error, and is significantly faster to implement. Python opencv has an implementation。具有去偏移功能的神经网络和支持向量机也有一些非常令人印象深刻的性能。
请注意,卷积网络不能让您选择自己的特征,因此此处重要的色差信息可能仅用于缩小感兴趣区域。定义特征 space 的其他方法可能会更精确地包含已知的色差。
Python 在很棒的包 sklearn 中支持很多机器学习技术 - here are examples of sklearn applied to mnist. If you're looking for an tutorialized explanation of machine learning in python, sklearn's own tutorial is very verbose
来自 sklearn link:
如果您学习使用这种方法,这些就是您要尝试分类的项目种类。为了强调开始训练这些基于机器学习的分类器是多么容易,这里是 linked 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! Their demo uses k-nearest-neighbor (listed in the LeCun page), but they also have svms 以及 sklearn 中的许多其他工具。他们使用 SVM 的 ocr 页面使用 deskewing,这可能对您问题中的透视效果有用:
更新: 我在你的图片上使用了上面概述的开箱即用的 skimage 方法,经过大量裁剪,正确分类.需要进行 很多 次测试才能确定这在实践中是否是 rhobust
^^ 这个小图像是您嵌入问题中的图像的 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 看起来对我来说是正确的;您需要对其进行调整以使其在目标范围内或(理想情况下)提供您自己的训练和测试集
对象检测
如果您还没有分离出图像中的数字,您将需要一个物体检测器。关于这个问题的文献 space 是巨大的,我不会从那个兔子洞开始(google Viola 和 Jones,也许吧?)This blog 涵盖了 "sliding window" python 中的检测器。 Adrian Rosebrock 看起来他甚至是 SO 的贡献者,并且该页面有一些很好的 opencv 示例和基于 python 的对象检测器相当教程(你实际上 link 在你的问题中访问了那个博客,我没有'意识到)。
简而言之,对图像进行 windows 分类并选择置信度最高的 window。使用感兴趣的区域缩小搜索 space 当然会在所有性能领域产生巨大的改进
你有一些可以利用的优势:
- 数字在黑色矩形边框和一种颜色内
- 该数字似乎是分段 LCD 类型的显示器,如果是这样的话,只有有限数量的段是关闭或打开的。
所以我建议你:
- 校准相机并对图像进行预处理以消除镜头失真
- 修正显示矩形:
- 使用 hough 的交集检测显示矩形 线,或边缘检测,然后进行轮廓检测,然后选择 最大、最方形的轮廓
- 使用
GetPerspectiveTransform
得到图像坐标和理想矩形之间的变换,然后变换输入图像 使用WarpPerspective
将图像分成 R、G 和 B 通道并计算
r - avg(g, b)
,这有点依赖于光照,但应该给出如下内容:- 然后尝试对此进行模式匹配,或者重新分割图像并尝试查找哪些显示段亮起,或者 运行 通过 OCR 包。