暑假都在弄这个,一开始以为是要弄一个通用的对表格进行分块和把内容全部识别,所以又分块又分行又把横线上的内容单独弄出来,后来说是对于已知的特定表格,所以最后都用python来写了,比较方便。在网上只找到一个比较巧妙的提取表格框架的方法,用横向和竖向的细长的条去腐蚀膨胀可以得到横线和竖线,拼在一起就是完整的表格框架,而且这样正好把一些小点和文字去除了。
这样的话因为有些线太细,就检测所有轮廓再加粗一次,上图为加粗后的表格框架和找到的表格块(这图有点问题。。。好的找不到了)。但这个方法有个问题就是表格位置必须比较正,如果倾斜角度较大则不行。所以要先对表格进行透视变换后摆正。这里使用的方法是用上图找到的表格框架,找到表格的四个顶点,再和其轮廓的外接矩形的四个顶点得到变换矩阵。这里还有个问题,就四个顶点和变换后的四个顶点必须是对应的,所以要对四个顶点进行排序,怎么对矩形的四个顶点进行排序,在网上也找到了一个比较好的方法,就是将得到的四个顶点先按照y坐标分成上下A、B两部分,再对A部分按x坐标从小到大排序,对B部分按x坐标降序排序,这样四个点就能按照顺时针排列了,对于没有定位标识的表格,只要表格不是倒着摆放或者过分倾斜都可以正确变换。然后还有一个问题就是这是用外接矩形作为变换后的表格,这样不同的表格则变换后的大小不一样,所以最后都resize到一个固定大小。
因为图片的表格可能不是矩形,所以是用opencv的cv2.approxPolyDP,拟合表格的四边形,找轮廓cv2.findcontours时选择SIMPLE的方式,轮廓存储的就是顶点。拟合多边形时为了尽量拟合出来的是四边形为不是多于四条边,可以把epsilon的值设置的较大些,官网的方式是用cv2.arclength计算轮廓的周长来设置epsilon。
整个项目目录如图:
全部由python写的,为了统一,把之前C++写的一些函数用python重写了。
densenet包含印刷体中文字符识别densenet+ctc模型
MnistRec包含使用mnist训练的简单手写数字识别模型和多个数字分割的函数
preprocess包含提取表格框等一些预处理函数,roiblock类文件
test_image包含表单照片,roi区域截图,coordinates各roi的相对坐标及类型
test_result识别结果输出
demo_new.py入口程序
ocr.py包含三种类型的roi识别函数
主程序demo_new.py流程:
步骤1:
table_transform_roi可以对自动识别的表格区域进行手动动态调整,四个顶点
已按顺时针方向排序过(分成左上、右上、左下、右下四个顶点),table_roi
为透视变换后的表格图像,改变左侧顶点位置,可以在右侧窗口实时查看变换后
效果,大部分情况不需要手动调整。例如在表单照片倒置或者旋转90°,则可以
点击非顶点区域,四个顶点会循环交换一次。拖拽顶点可以调整顶点位置。
步骤2:
调整完选取区域后,会把表格部分resize到一个固定的大小,然后读取
coordinates中的相对坐标信息实例化多个roiblock对象,识别区域会显示在
表格上,在此窗口可以手动调整各个识别区域的大小和位置,拖拽区域左上绿
色点则可以改变框的大小,直接拖拽框则可以调整位置,在已知识别类容的类型
情况下,每个框都有特定的序号,故不可以随意更改摆放顺序。
对于定位和识别区域的问题暂时是可以这样了,识别的部分存在的问题是,印刷体可以很好的识别(网上找的训练好的汉字识别模型),关键是手写数字识别的问题,一是比如那个是粘连在一起的要先分开,二是手写数字的mnist数据集是国外的手写体与中国人写的数字差别比较大,识别效果不理想。手写汉字话暂时不考虑识别,只判断有没有签名即可,就根据二值化后的像素占比判断。
如果觉得《表格内容识别(python-opencv)(一)【9/8】》对你有帮助,请点赞、收藏,并留下你的观点哦!