文章目录

  • 一、功能实现
    • 1.1 resize_img
    • 1.2 四分类方向检测
    • 1.3 表格线的语义分割和提取
    • 1.4 找到图中表格与非表格区域: find_tables
    • 1.5 获得表格内的 cells 位置信息:find_cells
    • 1.6 获得图片中的文本位置信息:find_text
    • 1.7 初始化 json 字典
    • 1.8 文本区域识别:recognize_text
    • 1.9 表格区域识别
    • 1.10 整理成合合 AI 表格 ocr 的返回 json 格式
  • 二、网络结构
  • 三、运行需要的关键性环境说明

一、功能实现

1.1 resize_img

def resize_image(img, pix_max, pix_min):""" 根据图片设置的最大、最小阈值 resize 图片(同比例) """img_size = img.shapeh_mul_w = img_size[0] * img_size[1]im_scale = 1.0if h_mul_w > pix_max:im_scale = float(pix_max) / h_mul_welif h_mul_w < pix_min:im_scale = float(pix_min) / h_mul_wnew_h = int(img_size[0] * im_scale)new_w = int(img_size[1] * im_scale)re_im = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LINEAR)return re_im, (float(new_h) / img_size[0], float(new_w) / img_size[1])

1.2 四分类方向检测

  • step 1: 图像输入的 shape=(224, 224) 且为灰度图。
  • step 2:vgg16 为 backbone 的 4 分类模型 (0, 90°, 180°, 270°),检测后根据结果旋转图片,将图片摆正。 注意这里使用的是一个 onnx 模型,用 onnxruntime 框架执行运算,仅在 cpu 下,速度可达 0.06s/张。
  • step 3: 在方向检测摆正图片后,先对图片进行 makeborder 操作,再输入到接下来的识别逻辑中,copyMakeBorder补上一圈白色的边,防止有的图表格线是顶着边的,不利于 unet 检测。

1.3 表格线的语义分割和提取

  • step 1: 对于已经旋转过的图片,通过一个 Unet 网络做语义分割,得到横线与纵线的概率矩阵,然后利用 measure 模块对两个概率矩阵进行处理分析,从而提取表格中的横线与纵线。
  • step 2: 根据横线的斜率,计算图片倾斜角,并再次旋转图片,使横线正好平行于视图。
  • step 3: 由于 mask 可能出现断线,故用一些形态学算法,补上这些断线,为正确提取单元格做准备。
  • step 4: 此部分返回三个值,同等旋转后的 img, img_seg,以及表格的 Rows_y_merge,以便更好的是实现表格内的 cell 的定位。

1.4 找到图中表格与非表格区域: find_tables

  • step 1: 根据 img_seg 找到图中的大包围框,使用的方法是在 mask 里 “找白色轮廓”
  • step 2: 根据找到的大包围框(表格部分),将原图切成表格、非表格区域,非表格区域按普通 ocr 方法处理。

1.5 获得表格内的 cells 位置信息:find_cells

  • step 1: 用于寻找表格内部每个单元格的位置坐标(xmin, ymin, xmax, ymax),便于之后截取出来识别,注意这一步仅仅是寻找单元格的坐标,至于所处的行列信息以及里面包含的文字内容识别此步不考虑。
  • step 2: 由于白色线分隔出来的小黑块就是单元格位置,因此寻找黑色连通域就可以了,skimage 有个很好的包 measure,可以很方便的完成连通域的寻找以及 bbox 的获取。

1.6 获得图片中的文本位置信息:find_text

根据 tables 的坐标位置信息进行图片分割,返回文本区域位置坐标信息。

1.7 初始化 json 字典

构造形如合合的初始 AI json 字典,可以去合合官网看字典结构和每个字段的含义,以便接下来的识别信息直接填入字典中。

1.8 文本区域识别:recognize_text

  • step 1: 根据文本区域的位置信息,截取 roi 文本图片;
  • step 2: 对该文本区域进行 craft 检测,返回 box 坐标信息,然后根据 box 的坐标来进行排序调整;
  • step 3: 因为 craft 检测的 box 可能导致一行文字被分割开来,为了保持原有的格式,进行同一行文字合并并排序;
  • step 4: 文本 batch 识别
  • step 5: batch_text 解析,返回识别的结果,填入到 josn 字典中。

1.9 表格区域识别

step 1: cell 所处行列的判别

  • 任务是确定每个单元格的 start_column, end_column, start_row, end_row,目前的算法是做四次,依次确定 start_column, end_column, start_row, end_row。以 start_column 为例,将所有单元格按 xmin 排序,那么同一始列的 xmin 一定很接近,不同起始列的 xmin 有明显差异,如果投影在 x 轴上,同一列的会聚在一起,列转换时会有明显的突变。
  • 同样的 end_column 对应 xmax,start_row 对应 ymin,end_row 对应 ymax。
  • 但是在实验中发现,row 更易发生错误,那个跳变的阈值很难定,原因是有可能有下面这样的图:这种情况的行就不能这么做了,直观的想一想 1,2,3 的位置 ymin 的变化量是差不多的。故此,第二版的思路是,记住每条横线的位置(Rows_y)。
  • 起始行是第一行的单元格只能夹在 1,2 之间,依次类推。因为这样相对比较麻烦,而且第一版对列的判别基本没问题,所以用 1.0 思想做 start_column, end_column,2.0 思想做 start_row, end_row。

step 2: cell 内部文字识别

  • 接下来是确定每个单元格里的文字内容,因为有些单元格里面的文字不止一行,crnn 是不具备识别这种图的能力的,并且有的单元格留白太多,也不利于 crnn 识别。如果对每一个单元格都用文字检测模型去定位文字位置,则代价太高,时间耗时太长。针对表格文字比较规整这一特点。因此先做 line_split 算法,快速的将单元格内待识别的内容切割出来,送进 crnn 识别。
  • 表格 cell 内的文字分割后进行 batch 处理,送入 crnnOcr2 进行文字识别。

step 3: batch_text 解析

1.10 整理成合合 AI 表格 ocr 的返回 json 格式

二、网络结构

本项目中一共用了4个网络,作用各不相同

网络名称 框架 作用 模型位置
vgg16 onnx 四分类,0-90-180-270判别 ./onnx
unet darknet 语义分割,二类,一类表格横线,一类纵线 ./darknet
craft pytorch 非表格区域的文字检测 ./craft
crnn pytorch 文字识别 ./crnn

三、运行需要的关键性环境说明

  • python 必须 3.6 版本以上!原因:2.7 不支持 onnxruntime 运算,3.5 对 scikit-image 库支持有限
  • torch 1.4.0 with CUDA 10.0
  • opencv 4.2.0
  • skimage 0.16.2
  • web 0.51
  • onnx 1.6.0
  • onnxruntime 1.2.0

『工程项目实践』表格识别 — V2.0相关推荐

  1. 『工程项目实践』表格识别 — V1.0

    文章目录 前言 一.整体识别流程 二.去印章:remove_mark 三.寻找表格区域:get_pt 四.图片分割:TransformTable 五.文本部分检测 六.文本部分识别 七.表格部分的处理 ...

  2. 『工程项目实践』银行卡识别(CTPN+CRNN)

    银行卡识别 前言 一.数据预处理 1.1 数据准备 1.2 数据增强 二.训练(CRNN) 三.需要修改的内容 3.1 数据增强 3.2 训练 四.CRNN 结构说明 4.1 CNN 4.2 BiLS ...

  3. 『工程项目实践』条形码的检测与识别

    文章目录 前言 一.条形码的检测 1.1 目标 1.2 思路 1.3 代码 二.条形码的识别 2.1 正常角度 2.2 180度旋转 2.3 45度旋转 前言 在日常生活中,经常会看到条形码的应用,比 ...

  4. 『深度应用』人脸识别最新进展及发展方向

    人脸识别最新进展及发展方向 ▌一.人脸识别背景介绍 简单来讲,人脸识别这个问题,就是给定两个人脸,然后判定他们是不是同一个人,这是它最原始的定义.它有很多应用场景,比如银行柜台.海关.手机解锁.酒店入 ...

  5. 锁定行头和列头的表格组件 v2.0

    学到新东西了,对组件进行了修改,简化程序,增加功能. 1.在页面中引入风格单定义 <style> .LockHeadTable {behavior:url(LockHeadTable.ht ...

  6. JavaWeb『Vue.js』快速入门

    Vue快速入门 第一节 准备Vue.js环境 1.开发中的最佳实践 2.Vue框架的js文件获取 3.本地创建vue.js文件 4.创建HTML文档并引入vue.js 第二节 Vue.js基本语法:声 ...

  7. 『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现...

    『实践』VirtualBox 5.1.18+Centos 6.8+hadoop 2.7.3搭建hadoop完全分布式集群及基于HDFS的网盘实现 1.基本设定和软件版本 主机名 ip 对应角色 mas ...

  8. 『AD域攻防实践』第二期学习笔记

    上一周的直播课中,小伙伴们跟随御守实验室的师傅一起了解了"AD域在攻防对抗场景下的安全现状",课程结束后,我们为大家整理了学习笔记,也将录屏和PPT公布在了公众号和微信群,帮助大家 ...

  9. 『实践』Yalmip获取对偶函数乘子

    『实践』Yalmip获取对偶函数乘子 一.sdpsetting设置 Yalmip网站给出的说明 savesolveroutput默认为0,需要设置为1才会保存输出结果. 下面是我模型的约束个数: 二. ...

  10. 用python实现自动填数生成表格v2.0

    这个版本将v1.0中的数据源和填入位置两个excel合并到了一起了. 具体的话请看demo文件: 这里直接给出代码: from openpyxl import Workbook from openpy ...

最新文章

  1. Jsprime——一款JavaScript静态安全分析工具
  2. linux c 通过 /proc 获取 pid 进程 列表
  3. 更新pip到指定版本
  4. 2020年财富金字塔出炉,你距离高净值还有多远?
  5. instance-based与model-based 区别
  6. 你需要知道的nginx304
  7. OpenCV——素描
  8. 告诉我们您想要什么,我们将做到:消费者驱动的合同测试消息传递
  9. 前端学习(2795):实现样式的左侧结构和样式
  10. 安卓button设置背景图_这些安卓源码调试技巧,不懂的人月薪绝对不过 30k !
  11. linux环境下装mq,ActiveMQ下载与安装(Linux环境下进行)
  12. 几道JAVA和分布式系统面试题总结
  13. 在美团,我从暑期实习到转正
  14. TI C6000 TMS320C6678 DSP+ Zynq-7045的PS + PL异构多核案例开发手册(4)
  15. zabbix 清理历史数据
  16. 向量 内积 与 外积
  17. HTML 播放视频的embed标签和Object标签(转)
  18. matlab整流仿真,整流电路MATLAB仿真实验 - 范文中心
  19. 数据库系统概论----设计ER图
  20. Nginx无证书反向代理

热门文章

  1. MATLAB直方图图像去雾算法实现
  2. 西游记中最顶尖的妖怪
  3. 云袭2001's博客地址迁移啦——attacker.cc
  4. ThreadLocal的坑--ThreadLocal跨线程传递问题
  5. vmware应用程序无法正常启动0xc000007b
  6. (转载)消息队列详解
  7. 在word中同时输入上下标设置
  8. 服务器winsxs文件夹怎么清理工具,如何清理Win7系统winsxs文件夹中的垃圾?
  9. CAD的高程注记转成Arcgis点要素(且带高程属性)
  10. (3.8)一个按键所能涉及的:内核按键标准驱动gpio-keys