发票表格检测——传统图像方法

前言

偶尔整理笔记,发现两三年前写的纯用opencv实现发票图片中的表格检测的笔记。虽然现在已经是深度学习网络的天下,但是回头看看过去的探索,感觉还是有点意思的,主要用来给我自己做个笔记备份,同时分享给踏入图像的初学者们呀~

0 简介

ocr的识别基本实现了通用识别功能之后,还需要实现发票、户口本等的识别,但是想要实现发票等有表格的文件的识别,还需要额外的处理。因为传统的文字框检测工具yolo会将一行文字一起识别。而发票这类表格数据,即使在同一行中,也因为竖线的划分,所以并不能认为是一行是一体的。
image.png

对于这种问题,我的思路就是首先将图片按照表格拆分成子图,然后将每个子图放入后续的文字识别框架单独识别,最后将所有的结果整合之后返回给用户。加上前前后后的处理过程,大致可以分为如下几步:

  1. 判断图片是否需要大角度旋转(90,180,270)
  2. 判断是否需要小角度的旋转,保证横线的水平
  3. 使用opencv对表格的小矩形框进行提取
  4. 对表格以外的区域进行划分(如上图所示)
  5. 将所有的子图送入ocr模型进行检测
  6. 拼接结果

这里主要介绍一下在进行2,3,4图像处理过程中使用的函数工具以及部分拓展阅读。先列出对我帮助非常大的文章

  1. 要点初见:Python+OpenCV校正并提取表格中的各个框
  2. OpenCV—python 图像矫正(基于傅里叶变换—基于透视变换)
  3. python 图片中的表格识别
  4. OpenCV—Python 表格提取
  5. OpenCV—python 形态学处理(腐蚀、膨胀、开闭运算、边缘检测)

1 判断是否需要小角度的旋转

发票中有很多的横线,使用Canny函数获取轮廓+霍夫函数获取直线(这基本上是一个组合拳),然后可以根据这些横线的斜率的均值来确定图像是否有倾斜,以及倾斜之后需要旋转的角度。然后以图像的左下角为坐标中心,完成旋转工作。

import cv2
import numpy as np
import pytesseract
import cv2 as cv
import math

image = cv2.imread('C:\\Users\\14192\\Desktop\\7.jpg', 1)
# 灰度图片
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)  # 50,150,3
cv.imwrite('test_3\\edges_whole.jpg', edges)
lines = cv.HoughLinesP(edges, 1, np.pi / 180, 500, 0, minLineLength=50, maxLineGap=50)  # 650,50,20
print("一共检测到{}条直线".format(len(lines)))
pi = 3.1415
theta_total = 0
theta_count = 0
for line in lines:
    x1, y1, x2, y2 = line[0]
    rho = np.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
    theta = math.atan(float(y2 - y1) / float(x2 - x1 + 0.001))
    print(rho, theta, x1, y1, x2, y2)
    if theta < pi / 4 and theta > -pi / 4:
        theta_total = theta_total + theta
        theta_count += 1
        cv.line(image_copy, (x1, y1), (x2, y2), (0, 0, 255), 2)
        # cv.line(edges, (x1, y1), (x2, y2), (0, 0, 0), 2)
theta_average = theta_total / theta_count
print(theta_average, theta_average * 180 / pi)
cv.imwrite('test_3\\line_detect4rotation.jpg', image_copy)
affineShrinkTranslationRotation = cv.getRotationMatrix2D((0, rows), theta_average * 180 / pi, 1)
gray = cv.wa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值