最近学习了一下opencv,做了个简单的小东西,就是识别图片中的表格,识别完成后再把数据写入到csv中保存起来。

环境准备:

下面先说下我们应该要准备下啥环境:
1.python安装完成(笔者python3.7)
2.tesseract(google的开源cr框架)
3.pytesseract(python对tesseract的封装,调用时是通过pytesseract去调用tesseract)
4.python的一些类库,numpy,matplotlib
5.特别提一下要导入opencv的包,安装的时候名称是opencv-python,使用的时候名称是cv2,
cv2不是说是opencv的版本二哦,意思是在cv的基础上做了提升和优化的意思,跟版本没关系。
这里还有一点要注意的,使用cv2报错的话,可能还要安装一下opencv-python-headless。

识别步骤:

我们先来简单说一下原理,是怎么识别表格的呢?是这样的,如果直接咱们把一张图片用tesseract去识别成中文,它会把表格的横竖线都算进去,
很多汉字都识别不出来,效果也很难看。所以我们要做的前置步骤就是识别出excel图片的一个个单元格,把每个单元格中的信息给识别出来,然后拼接
成一个csv,在最后转为excel只需要通过excel导入csv的数据就可以了。

注意事项:本人水平有限,目前还只能处理比较简单的方方正正的表格,下面的程序是可直接跑的。但是如果有一些图片的表格是拍出来斜着的,或有干扰物
比如有支笔在图片中,或有很复杂的水印,这种目前还处理不了,还在继续研究当中。有兴趣的小伙伴可以一起玩啊,加个微信一起讨论交流。

不过咱们也对这些情况有一些方案,还在处理当中:
1.如果表格是倾斜的咱们可以使用透射变换先将表格处理成正常的矩形;
2.简单的水印,可以通过灰度之后,选个合理的阈值,将图片二值化后,白黑图可以去掉水印。

这里咱们安利一个很好的python-opencv的入门教程:github地址

好了废话说完了,开始教程:
原图:

1.读入图片灰度化:

可以理解为把彩色图片变为灰色图片

raw = cv2.imread(src, 1)
# 灰度图片
gray = cv2.cvtColor(raw, cv2.COLOR_BGR2GRAY)

2.图片二值化:

可以理解为把图片变成只有黑白两种颜色,这样更方便处理,再说咱们处理表格也不需要颜色

binary = cv2.adaptiveThreshold(~gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 35, -5)
# 展示图片
cv2.imshow("binary_picture", binary)

二值化的图片:

3.识别出横线,竖线:

在此之后,如果图像不够清晰或者有小像素点,可以使用腐蚀,膨胀等操作让图片更清晰一点

rows, cols = binary.shape
scale = 40
# 自适应获取核值
# 识别横线:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (cols // scale, 1))
eroded = cv2.erode(binary, kernel, iterations=1)
dilated_col = cv2.dilate(eroded, kernel, iterations=1)
cv2.imshow("excel_horizontal_line", dilated_col)# 识别竖线:
scale = 20
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, rows // scale))
eroded = cv2.erode(binary, kernel, iterations=1)
dilated_row = cv2.dilate(eroded, kernel, iterations=1)
cv2.imshow("excel_vertical_line:", dilated_row)

横线竖线的图:

4.计算出横竖线的焦点,就得到了每个单元格的坐标

# 将识别出来的横竖线合起来
bitwise_and = cv2.bitwise_and(dilated_col, dilated_row)
cv2.imshow("excel_bitwise_and", bitwise_and)# 标识表格轮廓
merge = cv2.add(dilated_col, dilated_row)
cv2.imshow("entire_excel_contour:", merge)# 两张图片进行减法运算,去掉表格框线
merge2 = cv2.subtract(binary, merge)
cv2.imshow("binary_sub_excel_rect", merge2)new_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
erode_image = cv2.morphologyEx(merge2, cv2.MORPH_OPEN, new_kernel)
cv2.imshow('erode_image2', erode_image)
merge3 = cv2.add(erode_image, bitwise_and)
cv2.imshow('merge3', merge3)# 将焦点标识取出来
ys, xs = np.where(bitwise_and > 0)

焦点图:

5.将坐标筛选下,临近的几个算一个:

这里说一下图片的数组中是(y,x)这样的,y在前面

# 横纵坐标数组
y_point_arr = []
x_point_arr = []
# 通过排序,排除掉相近的像素点,只取相近值的最后一点
# 这个10就是两个像素点的距离,不是固定的,根据不同的图片会有调整,基本上为单元格表格的高度(y坐标跳变)和长度(x坐标跳变)
i = 0
sort_x_point = np.sort(xs)
for i in range(len(sort_x_point) - 1):if sort_x_point[i + 1] - sort_x_point[i] > 10:x_point_arr.append(sort_x_point[i])i = i + 1
# 要将最后一个点加入
x_point_arr.append(sort_x_point[i])i = 0
sort_y_point = np.sort(ys)
# print(np.sort(ys))
for i in range(len(sort_y_point) - 1):if (sort_y_point[i + 1] - sort_y_point[i] > 10):y_point_arr.append(sort_y_point[i])i = i + 1
y_point_arr.append(sort_y_point[i])

6.通过坐标把每个单元格图像取出来,然后使用pytesseract识别文字 :去除特殊符号后,data就是处理好的值

# 循环y坐标,x坐标分割表格
data = [[] for i in range(len(y_point_arr))]
for i in range(len(y_point_arr) - 1):for j in range(len(x_point_arr) - 1):# 在分割时,第一个参数为y坐标,第二个参数为x坐标cell = src[y_point_arr[i]:y_point_arr[i + 1], x_point_arr[j]:x_point_arr[j + 1]]cv2.imshow("sub_pic" + str(i) + str(j), cell)# 读取文字,此为默认英文# pytesseract.pytesseract.tesseract_cmd = 'E:/Tesseract-OCR/tesseract.exe'text1 = pytesseract.image_to_string(cell, lang="chi_sim+eng")# 去除特殊字符text1 = re.findall(r'[^\*"/:?\\|<>″′‖ 〈\n]', text1, re.S)text1 = "".join(text1)print('单元格图片信息:' + text1)data[i].append(text1)j = j + 1i = i + 1

6.最后把所有的信息写入csv

path是要写入的文件路径,data是数据

with open(path, "w", newline='') as csv_file:writer = csv.writer(file, dialect='excel')for index, item in enumerate(data):if index != 0 and index != len(data) - 1:writer.writerows([[item[0], item[1], item[2], item[3], item[4], item[5]]])

写入表格数据:

总结:

1.完成之后就大致知道了表格识别的原理,并且对opencv的api有了一定的了解和熟悉,这里放上github的地址:项目地址,觉得还可以点点star,fork啥的哈。
2.不过这个介绍是说完了大致流程,其实过程中还有遇到很多坑,直接运行github的项目有可能跑出的结果和我不一样,
那是因为一个是要下载tesseract的中文数据集,第二是这个里面数学和几个文字竟然识别不出来,需要手动给tesseract增加
一些训练集。这个增加训练数据集应该后面会再出一篇文章。
3.弄完这个表格识别,准备在看下图片矫正和去除水印,复杂的表格识别也会使用到的。

参考资料:

1.https://github.com/tesseract-ocr/tesseract
2.https://pypi.org/project/pytesseract/
3.https://blog.csdn.net/muxiong0308/article/details/80969355
4.https://www.cnblogs.com/HL-space/p/10547259.html

欢迎关注我的公众号,更多干货等着你~

表格识别1-使用python-opencv实现表格识别相关推荐

  1. python读取视频流做人脸识别_基于 Python + OpenCV 进行人脸识别,视频追踪代码全注释...

    1 #-*- coding: utf-8 -*- 2 from __future__ importunicode_literals3 #操作文件 4 importos5 #科学计算 6 importn ...

  2. python+opencv将表格图片按照表格框线分割、识别

    如下小程序为使用python+opencv将表格图片,按照表格进行分割,并识别分割后的子图片中的文字,希望对需要的小伙伴有一些些帮助.具体的实现见如下代码. # -*- coding: utf-8 - ...

  3. 2021-01-07 python opencv实现车牌识别 颜色定位

    python opencv实现车牌识别 颜色定位 主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https ...

  4. Python+Opencv简易车牌识别(二):形态学运算,HSV颜色空间筛选与图像分割

    注:这是依然一个简单的车牌识别demo 1.前言 在上一篇Python+Opencv简易车牌识别(一):基于HSV颜色空间的图像分割中,我们讲了如何仅基于颜色来进行简单粗暴的车牌分割.今天我们考虑对图 ...

  5. Python OpenCv 车牌检测识别(边缘检测、HSV色彩空间判断)

    Python OpenCv 车牌检测识别 背景 车牌识别在交通.停车等方面有着广泛应用,在网上也有很多种基于OpenCV方案进行识别,本文是综合了两种比较流行的方案,首先是提取出疑似车牌区域的轮廓,然 ...

  6. Python OpenCV车道线识别侦测

    Python OpenCV车道线识别侦测 如需安装运行环境或远程调试,可加QQ905733049, 或QQ2945218359由专业技术人员远程协助! 运行结果如下: 代码如下: import cv2 ...

  7. Python opencv进行矩形识别

    Python opencv进行矩形识别 图像识别中,圆形和矩形识别是最常用的两种,上一篇讲解了圆形识别,本例讲解矩形识别,最后的结果是可以识别出圆心,4个顶点,如下图: 左边是原始图像,右边是识别结果 ...

  8. 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)

    亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档

  9. Python人脸识别教程 - 基于Python的开源人脸识别库:离线识别率高达99.38%

    Python人脸识别教程 - 基于Python的开源人脸识别库:离线识别率高达99.38% 仅用 Python 和命令行就可以实现人脸识别的库开源了.该库使用 dlib 顶尖的深度学习人脸识别技术构建 ...

  10. Python OpenCV 实现魔方识别+复原

    简介 本项目运用了基础的 Opencv 图像处理算法 来实现魔方色块的识别并判断颜色. 用户可以通过将魔方举在摄像机的前方来让机器自动将魔方的色块录入数据,然后系统将会依靠用户录入的数据来产生当前魔方 ...

最新文章

  1. 素数推断算法(高效率)
  2. linux中执行jmx脚本,在linux服务器下JMeter如何执行jmx性能脚本
  3. 一次二次开发中的经验与教训(二)
  4. 文件操作模式扩展、游标操作
  5. 王爽 汇编语言第三版 第11章 标志寄存器
  6. 修复漏洞的Istio 1.1.1 发布了
  7. linux写文件操作同步,linux 可执行文件与写操作的同步问题(文件读写操作产生的锁机制)...
  8. zero ecilpse下载_推荐10个免费图片下载网站,助你摆脱找图烦恼!建议收藏
  9. 戴尔电脑安装win 7
  10. 九章算法系列(#2 Binary Search)-课堂笔记
  11. RUP大讲堂(第五讲)-基于用例的需求工程技术
  12. ElasticSearch完结篇------京东搜索实战
  13. 学习scrapy使用
  14. 20160205 - Windows 10 家庭版没有组策略
  15. HTML5视频方案:支持iPad Safari、Firefox、Chrome、IE9876
  16. 正反转信号判别原理以及数字鉴相器原理
  17. 域名转入阿里云操作说明
  18. ACMoi蓝桥杯刷题网站推荐
  19. Java实现 对ip白名单的限制
  20. 访问www.baidu.com的过程

热门文章

  1. 学习工具001:PPT画图配色
  2. [Unity2D入门教程]简单制作仿植物大战僵尸游戏之③完善Defender植物和Attacker的相关细节(脚本,碰撞体)
  3. python单词表首字母排序_python 字母排序不区分大小写
  4. Baidu Expressive TTS《Multi-reference Tacotron by Intercross Training for Style Disentangling...》
  5. 图计算论文笔记--SPARC: Self-Paced Network Representation for Few-Shot Rare Category Characterization
  6. python turtle forward_Python turtle.forward方法代碼示例
  7. Crackme001-Acid_burn(IDA版本)
  8. Tinker 合并及加载补丁过程源码分析 (三)
  9. 几种常见音频编码器的比较
  10. java最早的游戏_回忆S60(塞班)年代的JAVA游戏