java-opencv再谈表格识别

前面写过一篇:关于opencv提取表格的方式总结 最近学了个新的技能。

前言

图一简单点:

图二复杂点有合并的:

  1. 表格大概有上面两种,图一是简单的表格,图二可以理解为有合并的,还有一种是无边框的表格这里暂且不讨论。
  2. 但是对于表格识别和EXCEL取数不同它不在乎是否有合并的,因为表格识别得到的是坐标根据坐标提取的。
  3. 之前这里介绍了一种表格提取的方式。java简单的表格识别
  4. 上面的方式可以总结为:Canny或Treshold+HoughLines/HoughLinesP 先二值化然后提取线条
  5. 然后过滤归类处理得坐标点提取上篇文章介绍的有。
  6. 最近又学了一种方式通过腐蚀+膨胀+合并得到 好处比传统的4的做法参数控制比较好只是有长度(像素)的比例。
  7. 方法可以参考:How to extract tables from an image?
  8. 问题就是上面给的图片没倾斜(可以通过矫正处理,之前写过一篇文章:Java调用opencv图片矫正)和干扰(滤波的方式)。
  9. 还有个问题还没想到怎么解决好,图2的回单表格外的:电子回单号码,日期这两个值也是很重要的。如果想特殊处理也是可以处理的(就是用腐蚀膨胀那套流程处理);

新方式

  1. 关键点在于Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontalsize,1)) 的size 宽设置1,高设置1,很高级的想法;
  2. 横线提取方式
ini 复制代码
int sc = 30; //这个值越大,检测到的直线越多
int horizontalsize = clone.cols() / sc;//宽像素点个数比例
//其实是个卷积核 注意 new Size(horizontalsize,1)宽上面得到的比例、高度设置为1
Mat horizontalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontalsize,1));
//腐蚀
Imgproc.erode(horizontal, horizontal, horizontalStructure, new Point(-1, -1), 1);
//膨胀 背景变大 内容变小
Imgproc.dilate(horizontal, horizontal, horizontalStructure, new Point(-1, -1), 1);
  1. 竖线提取方式和上面一样
java 复制代码
int verticalsize  = clone.rows() / sc;//高像素点个数比例
//其实是个卷积核 注意 new Size(horizontalsize,1)宽1、高度上面得到的比例
Mat verticalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1,verticalsize ));
//腐蚀
Imgproc.erode(vertical, vertical, verticalStructure , new Point(-1, -1), 1);
//膨胀 背景变大 内容变小
Imgproc.dilate(vertical, vertical, verticalStructure , new Point(-1, -1), 1);
  1. 合并得到的横线和竖线图Core.add(horizontal, vertical, result);
  2. 接着常规法1:操作 面积、轮廓顶点数过滤、坐标过滤
ini 复制代码
//轮廓提起
Imgproc.findContours(result, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++) {
   //轮廓
   Rect rect1 = Imgproc.boundingRect(contours.get(i));
   //面积过滤
   if(Imgproc.contourArea(contours.get(i))<100){
       continue;
   }
//多边形包围轮廓 后面可以判断顶点个数过滤
//MatOfPoint2f curve = new MatOfPoint2f(contours.get(i).toArray());
//MatOfPoint2f approxCurve = new MatOfPoint2f();
//Imgproc.approxPolyDP(curve, approxCurve, 0.025 * Imgproc.arcLength(curve, true), true);
//得到顶点数
//approxCurve.toArray().length
//
}
  1. 接着常规法2:和前面文章提到的类似,得到交叉坐标点处理Core.bitwise_and(horizontal, vertical, addMat);
  • 1.交叉点像素值是255的或者>0,得到所有的坐标点
  • 2.x坐标一直 竖线坐标,y坐标一直 横线过滤,误差大小过滤
  • 3.横线和竖线进行排序
  • 4.计算交叉点进行切图
  • 5.ocr进行文字识别
相关推荐
吾爱星辰几秒前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
slomay2 分钟前
关于对比学习(简单整理
经验分享·深度学习·学习·机器学习
哎呦没44 分钟前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
jndingxin1 小时前
OpenCV视频I/O(14)创建和写入视频文件的类:VideoWriter介绍
人工智能·opencv·音视频
编程、小哥哥1 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
AI完全体1 小时前
【AI知识点】偏差-方差权衡(Bias-Variance Tradeoff)
人工智能·深度学习·神经网络·机器学习·过拟合·模型复杂度·偏差-方差
卷心菜小温2 小时前
【BUG】P-tuningv2微调ChatGLM2-6B时所踩的坑
python·深度学习·语言模型·nlp·bug
IT学长编程2 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇2 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
陈苏同学2 小时前
4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
linux·服务器·ide·人工智能·python·深度学习·pycharm