

代码没封装,要自己调试一下,因为会产生临时文件,可以自己不删除文件然后去多尝试一些ocr,尝试过最后用微信ocr识别率最高,但是如果找到好的中文包,tesseract理论上才是最好的
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
def main(args):
pass
from xbot_extensions import we_chat
import cv2
import numpy as np
import math
import re
import os
from openpyxl import load_workbook
# 文件路径不要有中文
output_path = r"D:\opencv_test\test.xlsx" #文件保存路径
src=r"D:\opencv_test\test.png" #图片路径
temp_path = r"D:\opencv_test" #切割图片临时存放
# 创建一个新的 Excel 工作簿
wb = load_workbook(output_path)
# 选择默认的工作表
ws = wb.active
# 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)
# 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])
print(y_point_arr)
# 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 = binary[y_point_arr[i]:y_point_arr[i + 1], x_point_arr[j]:x_point_arr[j + 1]]
# 微信离线ocr识别文本
# 将二值化图像保存为本地的 JPG 文件
# {'taskId': 1, 'ocrResult': [{'text': '序号', 'location': {'left': 8.326155, 'top': 11.921338, 'right': 68.00881, 'bottom': 45.424667}, 'pos': {'x': 9.287486, 'y': 11.921338}}]}
file_path = f'{temp_path}\\{i}{j}.png'
cv2.imwrite(file_path, cell)
text1 = we_chat.wechat_ocr(file_path,0)
print(text1)
if len(text1['ocrResult']) == 0:
text1 = ''
else:
text1 = text1['ocrResult'][0]['text']
# 删除临时文件
os.remove(file_path)
# 去除特殊字符
text1 = re.findall(r'[^\*"/:?\\|<>″′‖ 〈\n]', text1, re.S)
text1 = "".join(text1)
# print('单元格图片信息:' + text1)
data[i].append(text1)
j = j + 1
i = i + 1
# 数据写入表格
for row in data:
ws.append(row)
# 保存修改后的 Excel 文件
wb.save(output_path)安装一下python-docx,
import docx
def ReadDocx(file):
doc = docx.Document(file)
data = []
for table in doc.tables:
data.append([])
for row in table.rows:
data[-1].append([])
for cell in row.cells:
data[-1][-1].append(cell.text)
return data