Python中的图像分类

16 投票
4 回答
7885 浏览
提问于 2025-04-16 05:19

我想找一种方法来分类扫描的页面,这些页面主要是文字。

具体来说,我的问题是这样的:我有一大堆扫描的文件,需要在这些文件中检测出某些类型的页面。我打算把这些文件“拆分”成单独的页面(每一页都是一张单独的图片),然后把这些图片分类为“A”或“B”。但是我不知道最好的方法是什么。

更多细节:

  • 我有很多“A”和“B”类型的图片(页面)示例,所以我可以进行有监督学习。
  • 我不太清楚如何从这些图片中提取特征来进行训练。比如,什么是特征呢?
  • 有些页面偶尔会稍微旋转,所以如果分类对旋转不太敏感(缩放影响小一点)就更好了。
  • 我希望能有一个跨平台的解决方案,最好是用纯Python或者常见的库。
  • 我考虑过使用OpenCV,但感觉这个方案有点“重量级”。

补充:

  • “A”和“B”页面的区别在于,“B”页面上有一些结构相似的表单,包括条形码的存在。而“A”页面则是自由文本。

4 个回答

3

你想要区分两种页面,主要是通过特定的元素来判断——也就是条形码的存在。这个过程可以分为两个步骤:

  1. 特征提取(计算机视觉):找到一些特定的点或线,这些是条形码的特征,而不是普通的文字。

  2. 二分类(统计学习):根据提取出来的特征,判断页面上是否有条形码。


在第一步中,你可以看看霍夫变换。这个方法特别适合识别图像中的线条,对于条形码检测也很有帮助。你可以参考这两页内容。另外,这里有一些使用OpenCV的示例


关于第二步,最常用的分类方法有:

  • k近邻算法
  • 逻辑回归
  • 随机森林(在R语言中实现得很好,但我对Python不太了解)
4

首先,我想说OpenCV是一个非常不错的工具,适合进行这类操作。而且,它有一个描述得很清楚的Python接口,可以在这里找到

OpenCV经过高度优化,你遇到的问题并不简单。

[全局编辑:重新整理我的想法]

这里有一些可以使用的功能想法:

  • 如果条形码是孤立的,可能可以尝试做一个距离变换(OpenCV中的DistTransform)。这样你可能能更容易找到兴趣点,可以用match或matchShapes来匹配。我觉得这是可行的,因为条形码应该有相同的形状(大小等)。兴趣点的得分可以作为一个特征。

  • 图像的矩(moments)在这里可能会有用,因为你有不同类型的全局结构。这可能足以区分A页和B页(关于OpenCV函数的更多信息可以在这里找到)(顺便说一下,你会得到不变的描述符 :))

  • 你可能还可以尝试计算垂直梯度水平梯度。条形码是一个特定的地方,在那里垂直梯度等于0,而水平梯度不等于0。这个方法的主要优点是这些操作的成本很低,因为你的目标只是检查页面上是否有这样的区域。你可以找到兴趣区域,并用它的得分作为特征。

一旦你有了特征,就可以尝试进行监督学习并测试泛化能力。你的问题需要尽量少出现假阴性(因为你会丢弃一些页面),所以你应该用ROC曲线来评估你的表现,并仔细查看灵敏度(应该要高)。在分类方面,你可以使用带有Lasso惩罚的回归来找到最佳特征。whatnick的帖子也提供了一些好的想法和其他描述符(可能更通用)。

9

我会把这个问题分成三部分来回答,因为你的问题看起来比较复杂。如果你要处理的页面数量不超过1000,我建议你使用人工的方法,找一些便宜的劳动力来帮忙。

第一部分:特征提取 - 在物体检测领域,你可以选择的特征非常多。由于你的需求之一是要对旋转不敏感,我推荐使用SIFT或SURF这类特征。你也可以考虑使用Harris角点等特征。选择哪些特征使用可能需要一些专业知识,如果你的计算能力足够,我建议你把多种特征结合起来,然后通过一个分类器训练来评估它们的重要性。

第二部分:分类器选择 - 我非常喜欢随机森林分类器。这个概念很简单,灵活性也很高,而且不需要太多的参数调整。调优时只需要很少的参数,而且在监督训练时你也可以使用参数选择模式来运行它。

第三部分:实现 - Python本质上是一种“胶水”语言。用纯Python来处理图像的速度通常不会很快。我建议你结合使用OpenCV来进行特征检测,使用R来进行统计分析和分类器的工作。

这个解决方案可能看起来有点复杂,但机器学习从来都不是一件简单的事情,即使页面之间的区别仅仅是它们是一本书的左页和右页。

撰写回答