python实现excel表格图片识别,并转换成excel文件

这个过程有点多,一步一步来。

一、文字识别

本人采用的是腾讯的云识别技术,所以先在腾讯完成一系列的注册、申请工作。

首先打开腾讯云的官网:https://cloud.tencent.com/

点击“入门”,这里面有大概需要的步骤:

https://cloud.tencent.com/product/generalocr/getting-started

开通文字识别的服务后:

这个按官方的说法是每个月可以免费使用1000次,还是很不错的。

开通服务后,还需要访问API的密钥,这个也需要申请,我这个是已申请好的:

二、实现效果

一张图片:

实现后的效果:

 

三、预安装相应的包

首先,要安装腾讯的组件包:tencentcloud-sdk-python。直接在线安装好像不得行,于是可以安装离线版,我这里下载后再安装的,包的名字叫:

pip install tencentcloud_sdk_python-3.0.330-py2.py3-none-any.whl

然后还安装了一个包:

pip install xlutils-2.0.0-py2.py3-none-any.whl

这两个包我已经上传了:

https://download.csdn.net/download/qiuqiuit/14927294

我的机子只安装了这两个,如果控制台有提示缺少包,可以自行再安装。

四、python实现

经过前面准备工作,下面把相应的代码贴出来:

image2excel.py:

# -*- coding: utf-8 -*-
import sys
import ocr
import xlrd
import yaml_class
from xlutils.copy import copy

pic_path = sys.argv[1]

print('doing...',pic_path)
# 使用ocr进行转换
config = yaml_class.get_yaml_data("config.yml")

trans = ocr.OCR()
path_excel = trans.img_to_excel(
    pic_path,
    image_path=pic_path,
    secret_id=config['secret_id'],
    secret_key=config['secret_key'],
)

old_excel = xlrd.open_workbook('output.xlsx')
new_excel = copy(old_excel)
ws = new_excel.get_sheet(0)
new_excel.save(pic_path+'.xls')

ocr.py:

# -*- coding: utf-8 -*-
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.ocr.v20181119 import ocr_client, models

import base64

# OCR识别封装
class OCR(object):

    def img_to_excel(self,
                     output_file_name,
                     image_path,
                     secret_id,
                     secret_key):
        # 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey
        cred = credential.Credential(
            secret_id,
            secret_key
        )
        # 实例化client对象
        httpProfile = HttpProfile()
        httpProfile.endpoint = "ocr.tencentcloudapi.com"
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        clientProfile.signMethod = "TC3-HMAC-SHA256"
        client = ocr_client.OcrClient(cred, "ap-shanghai", clientProfile)
        # 实例化一个请求对象
        req = models.GeneralFastOCRRequest()
        # 读取图片数据,使用Base64编码
        with open(image_path, 'rb') as f:
            image = f.read()
            image_base64 = str(base64.b64encode(image), encoding='utf-8')
        req.ImageBase64 = image_base64
        # 通过client对象调用访问接口,传入请求对象
        resp = client.TableOCR(req)
        # 获取返回数据(Data为Base64编码后的Excel数据)
        data = resp.Data
        # 转换为Excel
        output_file_name = str(output_file_name)
        path_excel = output_file_name+".xlsx"
        with open(path_excel, 'wb') as f:
            f.write(base64.b64decode(data))
        return path_excel

yaml读取配置文件(yaml_class.py):

# -*- coding: utf-8 -*-
import yaml

def get_yaml_data(yaml_file):
    # 打开yaml文件
    file = open(yaml_file, 'r', encoding="utf-8")
    file_data = file.read()
    file.close()
    # 将字符串转化为字典或列表
    data = yaml.load(file_data)
    return data

config.yml:

# -*- coding: utf-8 -*-
secret_id: AKIDPzLSHRK3bZUCSyCF3Z45Bj0LRHs0Ynzb
secret_key: Qa5QeYKwIQI4ZxDQFq663jIs********

虽然没得讲得很详细,但基本步骤就是这些,这样就可以利用腾讯的云服务,把excel图片识别出来,再转换成excel文件。

(2021.2.1更新)

上面ocr.py代码更详细的解释,可以看官方的例子:TencentCloud / tencentcloud-sdk-python

ocr.py是改装的关键,所以最近又深入了解了一下,甚至可以看看源代码:ocr_client.py与models.py源代码

文字识别,也分很多种接口,通用文字、卡证文字、票据单据、汽车相关、行业文档等多场景下的印刷体、手写体文字识别:https://cloud.tencent.com/document/product/866/49525

每个人的需求不同,所以很有必要深入学习下。比如表格识别,就有两个版本:

而我们上面的ocr.py采用的是V1版本,现在已经不推荐使用了,可以改成V2版本。V2版本的公共接口是RecognizeTableOCR,对应上面的代码改动如下:

# 通过client对象调用访问接口,传入请求对象
resp = client.RecognizeTableOCR(req)

另外,还有一个比较关键的东西,那就是识别对象是哪种,印刷体,还是手写体、英文体?上面的ocr.py用的是GeneralFastOCR,即印刷体。

总的来说,ocr.py作用的就是通过GeneralFastOCR识别印刷字体,然后通过RecognizeTableOCR转换成excel表格。如果需要识别手写体怎么办?

需要修改models.GeneralFastOCRRequest:

# 实例化一个请求对象
req = models.GeneralHandwritingOCRRequest()
...
# 通过client对象调用访问接口,传入请求对象
resp = client.RecognizeTableOCR(req)
data = resp.Data

还有那个服务器地域,可以取以下值:

华北地区(北京)ap-beijing
华南地区(广州)ap-guangzhou
港澳台地区(中国香港)ap-hongkong
亚太东北(首尔)ap-seoul
华东地区(上海)ap-shanghai
亚太东南(新加坡)ap-singapore
北美地区(多伦多)

na-toronto

也就是离哪个服务器近就选哪个。

 

  • 18
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
实现这个任务,需要使用Python的OpenCV和Pandas库。具体步骤如下: 1. 首先,使用OpenCV读取图片,将其转换为灰度图像并进行阈值处理,以便于检测表格线。 ```python import cv2 import numpy as np # 读取图片并转换为灰度图像 img = cv2.imread('image.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 应用阈值处理,以便于检测表格线 thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] ``` 2. 检测表格线。我们可以使用HoughLinesP函数来检测直线,然后筛选出水平和垂直线。 ```python # 检测表格线 horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 1)) vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 25)) horizontal_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel) vertical_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel) # 筛选出水平和垂直线 lines = cv2.HoughLinesP(horizontal_lines + vertical_lines, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10) ``` 3. 将检测到的表格线画出来,并将表格线的坐标存储在列表。 ```python # 画出检测到的表格线 for line in lines: x1, y1, x2, y2 = line[0] cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2) # 存储表格线的坐标 horizontal_points = [] vertical_points = [] for line in lines: x1, y1, x2, y2 = line[0] if abs(x1 - x2) < 10: vertical_points.append((x1, y1)) elif abs(y1 - y2) < 10: horizontal_points.append((x1, y1)) ``` 4. 根据表格线的坐标,将表格分割成单元格。 ```python # 对表格线的坐标进行排序 horizontal_points = sorted(horizontal_points, key=lambda x: x[1]) vertical_points = sorted(vertical_points, key=lambda x: x[0]) # 将表格分割成单元格 cells = [] for i in range(len(horizontal_points) - 1): for j in range(len(vertical_points) - 1): x1, y1 = vertical_points[j] x2, y2 = vertical_points[j+1] x3, y3 = horizontal_points[i] x4, y4 = horizontal_points[i+1] cell = img[y3:y4, x1:x2] cells.append(cell) ``` 5. 使用Pandas库将单元格数据转换为Excel文件。 ```python import pandas as pd # 将单元格数据转换为DataFrame data = [] for cell in cells: gray_cell = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY) text = pytesseract.image_to_string(gray_cell, lang='eng', config='--psm 6') data.append(text.strip()) df = pd.DataFrame(np.array(data).reshape(len(horizontal_points) - 1, len(vertical_points) - 1)) # 将DataFrame写入Excel文件 df.to_excel('table.xlsx', index=False, header=False) ``` 完整代码如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值