| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> 发票表格检测——传统图像方法 -> 正文阅读 |
|
[人工智能]发票表格检测——传统图像方法 |
前言偶尔整理笔记,发现两三年前写的纯用opencv实现发票图片中的表格检测的笔记。虽然现在已经是深度学习网络的天下,但是回头看看过去的探索,感觉还是有点意思的,主要用来给我自己做个笔记备份,同时分享给踏入图像的初学者们呀~ 0 简介ocr的识别基本实现了通用识别功能之后,还需要实现发票、户口本等的识别,但是想要实现发票等有表格的文件的识别,还需要额外的处理。因为传统的文字框检测工具yolo会将一行文字一起识别。而发票这类表格数据,即使在同一行中,也因为竖线的划分,所以并不能认为是一行是一体的。 对于这种问题,我的思路就是首先将图片按照表格拆分成子图,然后将每个子图放入后续的文字识别框架单独识别,最后将所有的结果整合之后返回给用户。加上前前后后的处理过程,大致可以分为如下几步:
这里主要介绍一下在进行2,3,4图像处理过程中使用的函数工具以及部分拓展阅读。先列出对我帮助非常大的文章
1 判断是否需要小角度的旋转发票中有很多的横线,使用Canny函数获取轮廓+霍夫函数获取直线(这基本上是一个组合拳),然后可以根据这些横线的斜率的均值来确定图像是否有倾斜,以及倾斜之后需要旋转的角度。然后以图像的左下角为坐标中心,完成旋转工作。
首先使用Canny函数得到轮廓形状,如下图一所示。然后使用霍夫函数提取到的直线信息(如下图二),然后通过斜率对直线进行筛选,得到横线的信息(如下图三所示)。 涉及到的图像处理技术1. Canny轮廓提取Canny抽取轮廓信息的原理是首先进行高斯去噪,获得平滑图片; 具体怎么选择梯度大小作为阈值也需要人为设置,在Canny函数中有两个阈值要设定,minVal和maxVal.大于maxVal的则被认为是边界,小于minVal则直接抛弃,不认为拥有这样梯度的点是边界。而在两者之间的像素点,则检查其是否和某个边界相连,如果相连,则认为是边界信息,否则抛弃。 下面是一个简单的示意图,参考opencv边缘检测–Canny和机器学习进阶-边缘检测-Canny边缘检测。可以理解,当两个阈值设置的比较小的时候,那么Canny处理之后的图像会保留更多的轮廓信息。在实际使用中,一般需要三个参数,第一个参数是原图img,第二和第三个参数分别是minVal和maxVal,关键字参数apertureSize是计算图像梯度时使用的卷积核的尺寸信息,默认为3,另一关键字参数L2gradient,它可以用来设定求梯度大小的方程,简单使用的时候,可以先不用理会。 2. 霍夫变化获取直线霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。 霍夫变换于1962年由PaulHough首次提出,最初的Hough变换是设计用来检测直线和曲线,起初的方法要求知道物体边界线的解析方程,但不需要有关区域位置的先验知识。这种方法的一个突出优点是分割结果的Robustness,即对数据的不完全或噪声不是非常敏感。然而,要获得描述边界的解析表达常常是不可能的。 后于1972年由Richard Duda & Peter Hart推广使用,经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。霍夫变换运用两个坐标空间之间的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。 霍夫线变换是一种用来寻找直线的方法. 在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像. 在OpenCV中,我们可以用HoughLines函数来调用标准霍夫变换SHT和多尺度霍夫变换MSHT。而HoughLinesP函数用于调用累计概率霍夫变换PPHT。累计概率霍夫变换执行效率很高,所有相比于HoughLines函数,我们更倾向于使用HoughLinesP函数。
3. 仿射变换仿射变换是指在向量空间中进行一次线性变换(乘以一个矩阵)并加上一个平移(加上一个向量),变换为另一个向量空间的过程。在有限维的情况下,每个仿射变换可以由一个矩阵A和一个向量b给出,它可以写作A和一个附加的列b。一个仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,只要加入一个额外的行到矩阵的底下,这一行全部是0除了最右边是一个1,而列向量的底下要加上一个1. 利用opencv实现仿射变换一般会涉及到warpAffine和getRotationMatrix2D两个函数,其中warpAffine可以实现一些简单的重映射,而getRotationMatrix2D可以获得旋转矩阵。 2. 使用opencv对表格的小矩形框进行提取2.1 图像预处理
首先将图片灰度处理,然后使用cv2.adaptiveThreshold实现二值化处理。在灰度图是将原本的三通道转为单通道,每个像素点的值范围在(0,255)之间,0表示黑色,255表示白色。二值化处理则是将图像完全的变成黑白两种颜色(实际会更加复杂)。常用的二值化函数有cv2.threshold固定阈值二值化处理和adaptiveThreshold自适应阈值二值化。固定阈值的方法就是对高于阈值的则统一变为某个指定颜色,低于阈值的则是另一个颜色。自适应阈值二值化函数根据图片一小块区域的值来计算对应区域的阈值,从而得到也许更为合适的图片。参考文章python-opencv函数总结之(一)threshold、adaptiveThreshold、Otsu 二值化
在这里输入的图片是 2.2 横竖线识别根据得到的二值图,分别识别横线、竖线,并将横竖线结合.
这里或许会有这样的疑惑,既然上面提到的霍夫函数可以用来提取直线,那么为什么这里不使用。我的感觉是,当需要寻找大尺度直线的时候,可以使用霍夫函数。但是对于这种全局的含有各种小线段的图像,就不合适了,首先霍夫函数需要手动的设置阈值,只有超过阈值的才会被认为是直线。我们可以做一个简单实验,下面是阈值为col/20,col/10,col/7,col/5的不同结果。可以看到根本无法得到我们需要的边框线。 因此需要使用腐蚀和膨胀。识别横线和竖线的原理都是一样,通过设置相应的核矩阵kernel,然后进行腐蚀eroded和膨胀操作dilate。这样就可以得到横竖线。横竖线的交点可以通过bitwise_and函数获得,横竖线的交叉图像可以通过add函数实现。 涉及到的图像处理技术这里主要要介绍一下核矩阵以及腐蚀、膨胀、开运算、闭运算,其他的形态选处理可以参考形态学处理(腐蚀、膨胀、开闭运算、边缘检测) 核矩阵本质是一个np.array的数组,比如一个十字核矩阵
其本质是一个这样的矩阵
同理可以知道
其本质是全1矩阵。 我们定义了一个这样的核矩阵之后,就使用他来进行腐蚀和膨胀操作。
我们这里使用的核矩阵形状为(cols // scale, 1),对于上图的发票,其col为1920,scale人为设置成40,也就是(48,1),这是一个长条形的全1矩阵,那么这个矩阵在用于腐蚀的时候, 会将长直线保留,而距离短于48像素的类横线则会被覆盖为黑色。这样就不用担心文字中的横线会被保留下来。膨胀的原理也类似,不做赘述了。腐蚀和膨胀的返回结果依旧是原图大小的image,如上图所示。 开运算和闭运算是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的,即先开后闭并不能得到原先的图像。 为了获取图像中的主要对象:对一副二值图连续使用闭运算和开运算,或者消除图像中的噪声,也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。
2.3 表格划分在获得了横线和竖线的交点图像bitwiseAnd以及获得横线和竖线的交叉图像merge之后,关于如何划分表格,主要有两种不同的思路
我使用的是第一种思路,先把代码附上,后面会说第二种思路的适用场景。
通过上面的代码,可以获得每个表格框了,如果切分一下,得到的结果如下: 第二种思路,关于交点的使用方式,也有两种思路。首先参考 要点初见:Python+OpenCV校正并提取表格中的各个框中的代码,使用了第一种方式,这种方式的思路是通过获得的交点图像,将其中白色交叉点的坐标提取出来;删除坐标位置很近的冗余坐标;将横纵坐标排序之后,分别保存在两个列表中,然后依次遍历纵坐标、横坐标,两重循环的方式进行切割。
这种方式适用于excel那种比较标准的表格。如下图所示,而对于发票这种则会导致多余的切割。 第二种思路的另一个实现可以用下面的图来表示,我没有尝试实现,但是应该是可行的。 备忘
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/28 18:49:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |