paddle ocr

ops/2025/4/1 0:33:33/

paddle ocr

  • paddle ocr笔记
    • 准备工作
    • reference
    • to onnx
    • 文本检测
    • 文本检测
    • 文字识别

paddle_ocr_2">paddle ocr笔记

准备工作

  1. 下载字典ppocr_keys_v1.txt,下标从1开始
  2. 模型转换

reference

to onnx

下载模型,或者直接使用python跑一下并且把本地模型拿过来用,一共三个模型:文本检测,文本方向校准,文字识别模型

paddle2onnx --model_dir ./det/ch/ch_PP-OCRv4_det_infer --model_filename inference.pdmodel  --params_filename inference.pdiparams  --save_file ./det-model.onnx  --opset_version 11  --enable_onnx_checker Truepaddle2onnx --model_dir ./rec/ch/ch_PP-OCRv4_rec_infer --model_filename inference.pdmodel  --params_filename inference.pdiparams  --save_file ./rec-model.onnx  --opset_version 11  --enable_onnx_checker Truepaddle2onnx --model_dir ./cls/ch_ppocr_mobile_v2.0_cls_infer --model_filename inference.pdmodel  --params_filename inference.pdiparams  --save_file ./cls-padmodel.onnx  --opset_version 11  --enable_onnx_checker True

文本检测

import onnxruntime
import cv2
import numpy as np# 读取图片
# image = cv2.imread("chinese.png")
image = cv2.imread("none.png")# 加载 ONNX 文本检测模型
det_session = onnxruntime.InferenceSession("./onnx/det-model.onnx")# 预处理
det_input = cv2.resize(image, (640, 640)) / 255.0  # 归一化
det_input = np.transpose(det_input, (2, 0, 1))[np.newaxis, :, :, :].astype(np.float32)# 推理
input_name = det_session.get_inputs()[0].name
output_name = det_session.get_outputs()[0].name
det_output = det_session.run([output_name], {input_name: det_input})[0]# 获取非零值的索引(文本区域)
non_zero_indices = np.nonzero(det_output)print(f'--------------------------')
print(f'len:{len(non_zero_indices[0])}')
# 打印非零值的索引及对应的值
for i in range(len(non_zero_indices[0])):print(f'--------------------------')coords = tuple(non_zero_indices[j][i] for j in range(len(non_zero_indices)))print(f"坐标: {coords}, 值: {det_output[coords]}")

文本检测

import onnxruntime
import cv2
import numpy as np# 读取图片
# image = cv2.imread("chinese.png")
# image = cv2.imread("none.png")
image = cv2.imread("oneline.png")# 加载 ONNX 文本检测模型
det_session = onnxruntime.InferenceSession("./onnx/det-model.onnx")# 预处理
det_input = cv2.resize(image, (640, 640)) / 255.0  # 归一化
# det_input = image / 255.0  # 归一化
det_input = np.transpose(det_input, (2, 0, 1))[np.newaxis, :, :, :].astype(np.float32)# 推理
input_name = det_session.get_inputs()[0].name
output_name = det_session.get_outputs()[0].name
det_output = det_session.run([output_name], {input_name: det_input})[0]#
#
#
# 获取非零值的索引(文本区域)
# non_zero_indices = np.nonzero(det_output)# print(f'--------------------------')
# print(f'len:{len(non_zero_indices[0])}')
# # 打印非零值的索引及对应的值
# for i in range(len(non_zero_indices[0])):
#     print(f'--------------------------')
#     coords = tuple(non_zero_indices[j][i] for j in range(len(non_zero_indices)))
#     print(f"坐标: {coords}, 值: {det_output[coords]}")# 5. 确保 `det_output` 是 4D (batch, channels, height, width)
print("det_output shape:", det_output.shape)# 6. 获取二值化文本区域
box_thresh = 0.3
text_mask = (det_output[0, 0, :, :] > box_thresh).astype(np.uint8) * 255# 7. 确保 `text_mask` 是单通道 2D 图像
print("text_mask shape:", text_mask.shape)  # 应该是 (height, width)# 8. 显示二值化结果(可选)
cv2.imshow("Text Mask", text_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()# 9. 确保 `text_mask` 兼容 OpenCV
if len(text_mask.shape) == 3:text_mask = cv2.cvtColor(text_mask, cv2.COLOR_BGR2GRAY)# 10. 轮廓检测
contours, _ = cv2.findContours(text_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 11. 打印检测到的文本框
for contour in contours:x, y, w, h = cv2.boundingRect(contour)print(f"检测到的文本框: x={x}, y={y}, w={w}, h={h}")

文字识别

import onnxruntime
import cv2
import numpy as np# 读取图片
image = cv2.imread("rec-cv2.imread.png")target_height = 48
h, w = image.shape[:2]
new_w = int(w * (target_height / h))
new_w = max(32, (new_w // 32) * 32)
image = cv2.resize(image, (new_w, target_height));
print(f'resize: {image.shape}')# image = cv2.imread("none.png")# 加载 ONNX 文本检测模型
rec_session = onnxruntime.InferenceSession("./onnx/rec-model.onnx")# 预处理
# rec_input = cv2.resize(image, (640, 640)) / 255.0  # 归一化
rec_input = image / 255.0  # 归一化
rec_input = np.transpose(rec_input, (2, 0, 1))[np.newaxis, :, :, :].astype(np.float32)print(f'shape: {rec_input.shape}')# 推理
input_name = rec_session.get_inputs()[0].name
output_name = rec_session.get_outputs()[0].name
print(f'input_name: {input_name}')
print(f'output_name: {output_name}')
rec_output = rec_session.run([output_name], {input_name: rec_input})[0]with open('onnx/dict.txt', 'r', encoding='utf-8') as f:dict_list = f.readlines()dict_list = [line.strip() for line in dict_list]# 返回下标的字典dict_index = {i + 1: char for i, char in enumerate(dict_list)}print(rec_output[0].shape)# 假设 rec_output[0] 的 shape 为 (60, 6625)
probabilities = rec_output[0]  # 取出 (60, 6625)# Step 1: 找到每个时间步概率最高的索引
max_indices = np.argmax(probabilities, axis=1)  # shape: (60,)# print(f'--dict: {dict_index}')
# Step 2: CTC 处理(去重)
decoded_text = []
prev_index = -1  # 记录前一个索引,避免重复
for index in max_indices:if index != prev_index and index in dict_index:  # 避免重复 & 确保索引合法print(f'--index: {index}, dict[{index}] = dict_index[{index}]')decoded_text.append(dict_index[index])prev_index = index# Step 3: 转换为字符串
decoded_text = "".join(decoded_text)print("识别结果:", decoded_text)

http://www.ppmy.cn/ops/170745.html

相关文章

怎么简单设计一个文件上传系统?

关于文件上传系统有几个最主要的核心点需要解决: 如何支持超大文件上传 避免重复文件存储,节省空间 限流问题 大文件上传 假设有个 10 G 的文件需要上传,正常情况下是将文件转成流传到后端,如果不做任何处理,前端直传&#x…

k8s基础知识总结node+pod(上)

一、概念: k8s(Kubernetes )是一个开源的容器编排平台,用于容器化应用程序的部署、扩展和管理。使运维人员能够轻松地管理容器化应用的整个生命周期,包括容器的调度、资源分配、服务发现、负载均衡、自动伸缩以及故障…

ChatBI的流程图

Created with Raphal 2.3.0 用户输入 问题是否含预设关键字 预设关键字对应的参数 传入相应参数,调用查数 API 输出 把问题传给大语言模型 yes no Created with Raphal 2.3.0 用户输入 把 预设关键字 作为提示词一并传给大语言模型 大语言模型决定调用 API &#xf…

使用 WSL + Ubuntu + Go + GoLand(VSCode) 开发环境配置指南

1. 安装和配置 WSL 与 Ubuntu 启用 WSL 功能(以管理员身份运行 PowerShell): wsl --install 或手动启用: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachi…

搜广推校招面经五十八

小红书推荐算法 一、BN(Batch Normalization)在训练和测试的区别 Batch Normalization(批归一化,BN)是一种加速深度神经网络训练的技术,它通过对每个 mini-batch 计算均值和方差来归一化输入特征&#xf…

unittest自动化测试实战

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 为什么要学习unittest 按照测试阶段来划分,可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程…

[特殊字符]《多商户家政系统技术解析:SpringBoot+MyBatisPlus+UniApp高效实战指南》

🛠️ 引言:多商户家政系统的技术挑战与价值 在数字化时代,家政行业逐渐向线上迁移,从传统的线下预约转向平台化管理。多商户家政系统具备复杂的角色体系,包括: 🛎️ 商户端:管理订单…

计算机三级网络技术大题总结

网络技术大题方法总结 一、大题必备基础 IP 地址由网络位和主机位组成,并有 4 个段、32 个二进制位。十进制、二进制相互转换表: 二进制11111111指数 2 7 2^7 27 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20十进制…