python提取图片中的表格内容

2023-05-16

只提供思路,具体场景核图像有关,需做前期调整

一、处理流程:

1、图像灰度化处理

2、图像二值化处理

3、图像腐蚀处理(若得到的横纵交线不清楚,添加膨胀处理)

4、获取表格交点坐标

5、根据交点集获取单元格轮廓并进行过滤

二、使用案例

在这里插入图片描述

三、代码示例及效果

1、灰度化处理

def gray_img(img:'numpy.ndarray'):
    """
    对读取的图像进行灰度化处理
    :param img: 通过cv2.imread(imgPath)读取的图像数组对象
    :return: 灰度化的图像
    """
    grayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    return grayImage

2、二值化处理

def bin_img(img:'numpy.ndarray'):
    """
    对图像进行二值化处理
    :param img: 传入的图像对象(numpy.ndarray类型)
    :return: 二值化后的图像
    """
    ret,binImage=cv2.threshold(img,180,255,cv2.THRESH_BINARY_INV)
    return binImage

在这里插入图片描述

3、图像腐蚀

def erode_img(img,kernel_args=(2,2),iterations=1):
    """
    对图像进行腐蚀
    @param kernel_args 卷积核参数(2,2)
    @param interations erode的迭代次数
    """

    kernel = np.ones(kernel_args, np.uint8)
    return cv2.erode(img, kernel,iterations=iterations)

(1)纵向腐蚀获取横向线条

    img_transverse = erode_img(img,(1,2),40)

需要调节卷积核参数(kernel_args),迭代次数(iterations)
在这里插入图片描述

(2)横向腐蚀获取纵向线条

    img_vertical = erode_img(img, (2,1), 40)

在这里插入图片描述

4、图像膨胀处理

膨胀处理相当于对线条进行加粗

    img_transverse = dilate_img(img_transverse,(2,2),1)
    img_vertical = dilate_img(img_vertical,(2,2),1)

5、获取交点

def get_points(img_transverse, img_vertical):
    """
    获取横纵线的交点
    :param img_transverse:
    :param img_vertical:
    :return:
    """
    img = cv2.bitwise_and(img_transverse, img_vertical)
    return img

在这里插入图片描述

6、获取单元格

def split_rec(arr):
    """
    切分单元格
    :param arr:
    :return:
    """
    # 数组进行排序
    arr.sort(key=lambda x: x[0],reverse=True)
    # 数组反转
    arr.reverse()
    for i in range(len(arr) - 1):
        if arr[i+1][0] == arr[i][0]:
            arr[i+1][3] = arr[i][1]
            arr[i + 1][2] = arr[i][2]
        if arr[i+1][0] > arr[i][0]:
            arr[i + 1][2] = arr[i][0]
        print(arr[i])
    return arr

def get_rec(img):
    """
    获取单元格
    :param img: 
    :return: 
    """
    contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
    contours_poly = [0] * len(contours)
    boundRect = [0] * len(contours)
    rois = []
    for i in range(len(contours) - 1):
        cnt = contours[i]
        contours_poly[i] = cv2.approxPolyDP(cnt, 1, True)
        boundRect[i] = cv2.boundingRect(contours_poly[i])
        rois.append(np.array(boundRect[i]))
        # img = cv2.rectangle(img_bak, (boundRect[i][0], boundRect[i][1]), (boundRect[i][2], boundRect[i][3]),
        #                     (255, 255, 255), 1, 8, 0)
    rois = split_rec(rois)
    return rois

在这里插入图片描述

四、完整代码

from PIL import Image, ImageOps
import cv2
import numpy as np




def split_rec(arr):
    """
    切分单元格
    :param arr:
    :return:
    """
    # 数组进行排序
    arr.sort(key=lambda x: x[0],reverse=True)
    # 数组反转
    arr.reverse()
    for i in range(len(arr) - 1):
        if arr[i+1][0] == arr[i][0]:
            arr[i+1][3] = arr[i][1]
            arr[i + 1][2] = arr[i][2]
        if arr[i+1][0] > arr[i][0]:
            arr[i + 1][2] = arr[i][0]
        print(arr[i])

    return arr



def get_points(img_transverse, img_vertical):
    """
    获取横纵线的交点
    :param img_transverse:
    :param img_vertical:
    :return:
    """
    img = cv2.bitwise_and(img_transverse, img_vertical)
    return img




def dilate_img(img, kernal_args:tuple, iterations:int):
    """
    dilate image
    @param kernel_args 卷积核参数(2,2)
    @param interations dilate的迭代次数
    """

    kernel = np.ones(kernal_args, np.uint8)
    return cv2.dilate(img, kernel,iterations=iterations)

    pass


def erode_img(img,kernel_args=(2,2),iterations=1):
    """
    对图像进行腐蚀
    @param kernel_args 卷积核参数(2,2)
    @param interations erode的迭代次数
    """

    kernel = np.ones(kernel_args, np.uint8)
    return cv2.erode(img, kernel,iterations=iterations)




def bin_img(img:'numpy.ndarray'):
    """
    对图像进行二值化处理
    :param img: 传入的图像对象(numpy.ndarray类型)
    :return: 二值化后的图像
    """
    ret,binImage=cv2.threshold(img,180,255,cv2.THRESH_BINARY_INV)
    return binImage

def gray_img(img:'numpy.ndarray'):
    """
    对读取的图像进行灰度化处理
    :param img: 通过cv2.imread(imgPath)读取的图像数组对象
    :return: 灰度化的图像
    """
    grayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    return grayImage
    pass

def get_rec(img):
    """
    获取单元格
    :param img:
    :return:
    """
    contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
    contours_poly = [0] * len(contours)
    boundRect = [0] * len(contours)
    rois = []
    for i in range(len(contours) - 1):
        cnt = contours[i]
        contours_poly[i] = cv2.approxPolyDP(cnt, 1, True)
        boundRect[i] = cv2.boundingRect(contours_poly[i])
        rois.append(np.array(boundRect[i]))
        # img = cv2.rectangle(img_bak, (boundRect[i][0], boundRect[i][1]), (boundRect[i][2], boundRect[i][3]),
        #                     (255, 255, 255), 1, 8, 0)
    rois = split_rec(rois)
    return rois

if __name__ == "__main__":
    image  = "D:/cs/ocr/c.png"
    img_bak = cv2.imread(image)
    img = gray_img(img_bak)
    img = bin_img(img)
    img_transverse = erode_img(img,(1,2),40)
    img_vertical = erode_img(img, (2,1), 40)
    # img = img_transverse + img_vertical
    img_transverse = dilate_img(img_transverse,(2,2),1)
    img_vertical = dilate_img(img_vertical,(2,2),1)
    img = get_points(img_transverse,img_vertical)

    rois = get_rec(img)
    for i, r in enumerate(rois):
        cv2.imshow("src" + str(i), img_bak[r[3]:r[1], r[2]:r[0]])
    cv2.waitKey(0)

    cv2.destroyAllWindows()
    pass

五、未解决

1、图像不清楚或倾斜,无法操作

2、若最右侧没有竖线会丢失最后一列

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python提取图片中的表格内容 的相关文章

  • Django REST序列化器:创建对象而不保存

    我已经开始使用 Django REST 框架 我想做的是使用一些 JSON 发布请求 从中创建一个 Django 模型对象 然后使用该对象而不保存它 我的 Django 模型称为 SearchRequest 我所拥有的是 api view
  • Python、Tkinter、更改标签颜色

    有没有一种简单的方法来更改按钮中文本的颜色 I use button text input text here 更改按下后按钮文本的内容 是否存在类似的颜色变化 button color red Use the foreground设置按钮
  • 更改自动插入 tkinter 小部件的文本颜色

    我有一个文本框小部件 其中插入了三条消息 一条是开始消息 一条是结束消息 一条是在 单位 被摧毁时发出警报的消息 我希望开始和结束消息是黑色的 但被毁坏的消息 参见我在代码中评论的位置 插入小部件时颜色为红色 我不太确定如何去做这件事 我看
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • 在 NumPy 中获取 ndarray 的索引和值

    我有一个 ndarrayA任意维数N 我想创建一个数组B元组 数组或列表 其中第一个N每个元组中的元素是索引 最后一个元素是该索引的值A 例如 A array 1 2 3 4 5 6 Then B 0 0 1 0 1 2 0 2 3 1 0
  • IRichBolt 在storm-1.0.0 和 pyleus-0.3.0 上运行拓扑时出错

    我正在运行风暴拓扑 pyleus verbose local xyz topology jar using storm 1 0 0 pyleus 0 3 0 centos 6 6并得到错误 线程 main java lang NoClass
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • Python:字符串不会转换为浮点数[重复]

    这个问题在这里已经有答案了 我几个小时前写了这个程序 while True print What would you like me to double line raw input gt if line done break else f
  • 使用 OpenPyXL 迭代工作表和单元格,并使用包含的字符串更新单元格[重复]

    这个问题在这里已经有答案了 我想使用 OpenPyXL 来搜索工作簿 但我遇到了一些问题 希望有人可以帮助解决 以下是一些障碍 待办事项 我的工作表和单元格数量未知 我想搜索工作簿并将工作表名称放入数组中 我想循环遍历每个数组项并搜索包含特
  • ExpectedFailure 被计为错误而不是通过

    我在用着expectedFailure因为有一个我想记录的错误 我现在无法修复 但想将来再回来解决 我的理解expectedFailure是它会将测试计为通过 但在摘要中表示预期失败的数量为 x 类似于它如何处理跳过的 tets 但是 当我
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • 从 pygame 获取 numpy 数组

    我想通过 python 访问我的网络摄像头 不幸的是 由于网络摄像头的原因 openCV 无法工作 Pygame camera 使用以下代码就像魅力一样 from pygame import camera display camera in
  • 在Python中重置生成器对象

    我有一个由多个yield 返回的生成器对象 准备调用该生成器是相当耗时的操作 这就是为什么我想多次重复使用生成器 y FunctionWithYield for x in y print x here must be something t
  • Python:计算字典的重复值

    我有一本字典如下 dictA unit1 test1 alpha unit1 test2 beta unit2 test1 alpha unit2 test2 gamma unit3 test1 delta unit3 test2 gamm
  • VSCode:调试配置中的 Python 路径无效

    对 Python 和 VSCode 以及 stackoverflow 非常陌生 直到最近 我已经使用了大约 3 个月 一切都很好 当尝试在调试器中运行任何基本的 Python 程序时 弹出窗口The Python path in your
  • 在 Pandas DataFrame Python 中添加新列[重复]

    这个问题在这里已经有答案了 例如 我在 Pandas 中有数据框 Col1 Col2 A 1 B 2 C 3 现在 如果我想再添加一个名为 Col3 的列 并且该值基于 Col2 式中 如果Col2 gt 1 则Col3为0 否则为1 所以
  • 对输入求 Keras 模型的导数返回全零

    所以我有一个 Keras 模型 我想将模型的梯度应用于其输入 这就是我所做的 import tensorflow as tf from keras models import Sequential from keras layers imp
  • 从 Python 中的类元信息对 __init__ 函数进行类型提示

    我想做的是复制什么SQLAlchemy确实 以其DeclarativeMeta班级 有了这段代码 from sqlalchemy import Column Integer String from sqlalchemy ext declar
  • 如何使用google colab在jupyter笔记本中显示GIF?

    我正在使用 google colab 想嵌入一个 gif 有谁知道如何做到这一点 我正在使用下面的代码 它并没有在笔记本中为 gif 制作动画 我希望笔记本是交互式的 这样人们就可以看到代码的动画效果 而无需运行它 我发现很多方法在 Goo
  • 在 Python 类中动态定义实例字段

    我是 Python 新手 主要从事 Java 编程 我目前正在思考Python中的类是如何实例化的 我明白那个 init 就像Java中的构造函数 然而 有时 python 类没有 init 方法 在这种情况下我假设有一个默认构造函数 就像

随机推荐