Python中的图像分类
我想找一种方法来分类扫描的页面,这些页面主要是文字。
具体来说,我的问题是这样的:我有一大堆扫描的文件,需要在这些文件中检测出某些类型的页面。我打算把这些文件“拆分”成单独的页面(每一页都是一张单独的图片),然后把这些图片分类为“A”或“B”。但是我不知道最好的方法是什么。
更多细节:
- 我有很多“A”和“B”类型的图片(页面)示例,所以我可以进行有监督学习。
- 我不太清楚如何从这些图片中提取特征来进行训练。比如,什么是特征呢?
- 有些页面偶尔会稍微旋转,所以如果分类对旋转不太敏感(缩放影响小一点)就更好了。
- 我希望能有一个跨平台的解决方案,最好是用纯Python或者常见的库。
- 我考虑过使用OpenCV,但感觉这个方案有点“重量级”。
补充:
- “A”和“B”页面的区别在于,“B”页面上有一些结构相似的表单,包括条形码的存在。而“A”页面则是自由文本。
4 个回答
首先,我想说OpenCV是一个非常不错的工具,适合进行这类操作。而且,它有一个描述得很清楚的Python接口,可以在这里找到。
OpenCV经过高度优化,你遇到的问题并不简单。
[全局编辑:重新整理我的想法]
这里有一些可以使用的功能想法:
如果条形码是孤立的,可能可以尝试做一个距离变换(OpenCV中的DistTransform)。这样你可能能更容易找到兴趣点,可以用match或matchShapes来匹配。我觉得这是可行的,因为条形码应该有相同的形状(大小等)。兴趣点的得分可以作为一个特征。
图像的矩(moments)在这里可能会有用,因为你有不同类型的全局结构。这可能足以区分A页和B页(关于OpenCV函数的更多信息可以在这里找到)(顺便说一下,你会得到不变的描述符 :))
你可能还可以尝试计算
垂直梯度
和水平梯度
。条形码是一个特定的地方,在那里垂直梯度
等于0,而水平梯度
不等于0。这个方法的主要优点是这些操作的成本很低,因为你的目标只是检查页面上是否有这样的区域。你可以找到兴趣区域,并用它的得分作为特征。
一旦你有了特征,就可以尝试进行监督学习
并测试泛化能力。你的问题需要尽量少出现假阴性
(因为你会丢弃一些页面),所以你应该用ROC曲线来评估你的表现,并仔细查看灵敏度(应该要高)。在分类方面,你可以使用带有Lasso惩罚的回归来找到最佳特征。whatnick的帖子也提供了一些好的想法和其他描述符(可能更通用)。
我会把这个问题分成三部分来回答,因为你的问题看起来比较复杂。如果你要处理的页面数量不超过1000,我建议你使用人工的方法,找一些便宜的劳动力来帮忙。
第一部分:特征提取 - 在物体检测领域,你可以选择的特征非常多。由于你的需求之一是要对旋转不敏感,我推荐使用SIFT或SURF这类特征。你也可以考虑使用Harris角点等特征。选择哪些特征使用可能需要一些专业知识,如果你的计算能力足够,我建议你把多种特征结合起来,然后通过一个分类器训练来评估它们的重要性。
第二部分:分类器选择 - 我非常喜欢随机森林分类器。这个概念很简单,灵活性也很高,而且不需要太多的参数调整。调优时只需要很少的参数,而且在监督训练时你也可以使用参数选择模式来运行它。
第三部分:实现 - Python本质上是一种“胶水”语言。用纯Python来处理图像的速度通常不会很快。我建议你结合使用OpenCV来进行特征检测,使用R来进行统计分析和分类器的工作。
这个解决方案可能看起来有点复杂,但机器学习从来都不是一件简单的事情,即使页面之间的区别仅仅是它们是一本书的左页和右页。