十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

dirsfirst.zip:EAST文本检测+Tesseract识别轻量级OCR工程包

dirsfirst.zip:EAST文本检测+Tesseract识别轻量级OCR工程包 简介本资源是一套基于深度学习的端到端文本检测与识别实践方案面向计算机视觉初学者及OCR应用开发者解决自然场景下图文混合图像中的文字定位与内容提取问题。方案采用EAST模型实现高效文本区域检测结合Tesseract引擎完成高精度字符识别全部逻辑封装于Python脚本中开箱即用且便于二次开发与算法对比实验。压缩包共含5个文件2张测试样图jpg、1张示例结果png、1个冻结的EAST检测模型pb文件、1个主执行脚本py总大小86.01MB结构精简聚焦核心流程无冗余依赖。目前已有597人学习下载读者可直接运行text_recognition.py快速验证检测框绘制与识别结果输出效果并基于提供的图像样本和模型文件开展参数调优、识别后处理或模型替换等进阶实践。1. dirsfirst.zip 不是目录排序工具而是 EAST Tesseract 文本识别流水线的轻量级工程包很多人第一次看到dirsfirst.zip这个名字会下意识认为它是个 Linuxls的增强版或 Pythonos.walk()的封装——毕竟dirsfirst听起来就像--dirs-first参数。但实际拆开后你会发现里面没有一行 shell 脚本也没有setup.py或README.md只有frozen_east_text_detection.pb、text_recognition.py和几张测试图11.png,2.jpg,4.jpg。这个压缩包本质是一个「即拷即用」的文本检测与识别最小可行工程它把 TensorFlow 冻结模型EAST和 PyTree/Tesseract 封装进一个 300 行以内的 Python 脚本跳过 OpenCV 编译、模型训练、OCR 配置等全部前置环节。适合需要快速验证 OCR 流程是否跑通的场景——比如扫描件批量提取发票字段、截图转文字做初步校验、或者给非算法同事演示“图像→坐标→文字”的端到端链路。它不追求高精度EAST 检测框偏粗Tesseract 默认引擎对倾斜/模糊文本敏感但胜在依赖少仅需opencv-python,numpy,tesseract、结构透明、参数可调性强。如果你正在调试文本定位失败率高、识别结果乱码、或想搞清 EAST 输出的score_map和geometry_map怎么解码这个包就是最干净的起点。2. EAST 文本检测模型的加载与推理从 frozen.pb 到四边形坐标2.1 为什么选 frozen_east_text_detection.pb 而不是 Keras/H5 模型EASTEfficient and Accurate Scene Text detector原始实现基于 TensorFlow 1.x其推理阶段核心是score_map文本区域置信度和geometry_map旋转矩形的几何参数。frozen_east_text_detection.pb是将训练好的模型通过freeze_graph工具导出的冻结图Frozen Graph特点是所有权重已固化为常量节点无需tf.train.Saver恢复输入输出节点名固定常见为input_image:0,feature_fusion/Conv_7/Sigmoid:0,feature_fusion/concat_3:0便于tf.import_graph_def直接加载兼容 TensorFlow 1.15 及部分 2.x启用tf.compat.v1模式避免版本兼容陷阱。相比.h5或 SavedModel.pb在此场景下更轻量——dirsfirst.zip中该文件仅 92MB而完整 SavedModel 目录通常超 200MB 且含冗余变量。2.2 text_recognition.py 中 EAST 推理的关键代码解析import cv2 import numpy as np import tensorflow as tf def detect_text(image_path, net_pathfrozen_east_text_detection.pb, min_confidence0.5, width320, height320): # 1. 加载冻结模型 graph tf.Graph() with graph.as_default(): od_graph_def tf.GraphDef() with tf.gfile.GFile(net_path, rb) as fid: serialized_graph fid.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name) # 2. 构建输入张量BGR → RGB → 归一化 → NHWC image cv2.imread(image_path) orig image.copy() (H, W) image.shape[:2] rW W / float(width) rH H / float(height) image cv2.resize(image, (width, height)) image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image image.astype(np.float32) / 127.5 - 1.0 # [-1, 1] 归一化 # 3. 获取输入/输出节点 input_tensor graph.get_tensor_by_name(input_image:0) score_map graph.get_tensor_by_name(feature_fusion/Conv_7/Sigmoid:0) geo_map graph.get_tensor_by_name(feature_fusion/concat_3:0) # 4. 执行推理 with tf.Session(graphgraph) as sess: (score, geometry) sess.run([score_map, geo_map], feed_dict{input_tensor: np.expand_dims(image, axis0)}) # 5. 解析 score_map 和 geometry_map 得到文本框 return decode_predictions(score[0], geometry[0], min_confidence, rW, rH) def decode_predictions(scores, geometry, min_confidence, rW, rH): # scores: (H/4, W/4, 1), geometry: (H/4, W/4, 5) → [x1,y1,x2,y2,x3,y3,x4,y4,angle] (num_rows, num_cols) scores.shape[:2] rects [] confidences [] for y in range(num_rows): scores_row scores[y] geometry_row geometry[y] for x in range(num_cols): if scores_row[x] min_confidence: continue # 提取几何参数dx1, dy1, dx2, dy2, angle offset_x, offset_y x * 4.0, y * 4.0 dx1, dy1, dx2, dy2, angle geometry_row[x] # 计算四边形顶点逆时针顺序 cos_a, sin_a np.cos(angle), np.sin(angle) x_center offset_x 0.5 * (dx1 dx2) * cos_a - 0.5 * (dy1 dy2) * sin_a y_center offset_y 0.5 * (dx1 dx2) * sin_a 0.5 * (dy1 dy2) * cos_a # 四点坐标已缩放回原图尺寸 pts np.array([ [x_center - dx1 * cos_a dy1 * sin_a, y_center - dx1 * sin_a - dy1 * cos_a], [x_center dx2 * cos_a dy1 * sin_a, y_center dx2 * sin_a - dy1 * cos_a], [x_center dx2 * cos_a - dy2 * sin_a, y_center dx2 * sin_a dy2 * cos_a], [x_center - dx1 * cos_a - dy2 * sin_a, y_center - dx1 * sin_a dy2 * cos_a] ]) * np.array([rW, rH]) rects.append(pts.astype(int)) confidences.append(float(scores_row[x])) return rects, confidences提示decode_predictions中的dx1/dy1/dx2/dy2并非直接像素偏移而是相对于 anchor 点offset_x, offset_y的归一化距离需结合angle旋转计算真实顶点。EAST 原论文中geometry_map第 5 通道输出的是sin(2θ)和cos(2θ)但此冻结模型已做后处理直接输出angle弧度制简化了角度解码逻辑。2.3 关键参数调优表影响检测召回率与误检率的核心变量参数作用推荐范围调整效果min_confidencescore_map 阈值低于此值的候选框被丢弃0.3 ~ 0.7↓ 降低 → 增加小文本/低对比度文本召回但误检增多↑ 升高 → 框更精准但漏检率上升width/height输入网络的图像尺寸必须是 32 的倍数320×320,640×640↑ 增大 → 分辨率提升小字检测能力增强但显存占用翻倍↓ 减小 → 速度加快但易漏检密集文本rW/rH宽高缩放比用于将预测坐标映射回原图自动计算必须严格匹配cv2.resize的缩放比例否则坐标偏移注意EAST 对长文本行如横幅、表格标题检测稳定但对单字符10px 高度、弯曲文本如商标弧形排列或强透视变形如斜拍文档效果有限。若11.png中的发票抬头未被框出优先检查min_confidence是否设为0.5以上并确认图像是否已做直方图均衡化预处理。3. Tesseract 文本识别的集成与定制从图像 ROI 到结构化字符串3.1 为什么不用 PyTorch CRNN 或 PaddleOCRTesseract 的不可替代性dirsfirst.zip选择 Tesseract而非深度学习 OCR 模型作为识别后端根本原因在于零训练成本Tesseract 4.0 默认启用 LSTM 引擎对中英文混合、数字、符号有成熟词典支持无需标注数据微调内存友好单次识别仅需 100~200MB RAM远低于 CRNN需 GPU 显存或 PaddleOCR依赖 PaddlePaddle 运行时可控性强通过--psmPage Segmentation Mode和--oemOCR Engine Mode参数可精确控制识别粒度如--psm 8强制单行文本--psm 13视为单字符。这与dirsfirst.zip的定位完全契合——它要解决的是「拿到 EAST 框出的 ROI 后如何快速得到可读字符串」而非构建端到端 OCR 系统。3.2 text_recognition.py 中 Tesseract 调用的健壮性封装import pytesseract from PIL import Image def recognize_text(image, boxes, langchi_simeng, psm8): 对每个文本框 ROI 调用 Tesseract 识别 :param image: 原始 BGR 图像 (cv2.imread 返回) :param boxes: EAST 输出的四边形坐标列表每项为 np.array([[x1,y1], [x2,y2], [x3,y3], [x4,y4]]) :param lang: 语言包chi_simeng 表示简体中文英文混合 :param psm: Page Segmentation Mode8单行文本7单行强制13单字符 results [] for i, box in enumerate(boxes): # 1. 用四点坐标裁剪 ROI抗锯齿仿射变换 rect np.zeros((4, 2), dtypefloat32) s box.sum(axis1) rect[0] box[np.argmin(s)] rect[2] box[np.argmax(s)] diff np.diff(box, axis1) rect[1] box[np.argmin(diff)] rect[3] box[np.argmax(diff)] # 计算目标矩形宽高保持长宽比 (tl, tr, br, bl) rect widthA np.sqrt(((br[0] - bl[0]) ** 2) ((br[1] - bl[1]) ** 2)) widthB np.sqrt(((tr[0] - tl[0]) ** 2) ((tr[1] - tl[1]) ** 2)) maxWidth max(int(widthA), int(widthB)) heightA np.sqrt(((tr[0] - br[0]) ** 2) ((tr[1] - br[1]) ** 2)) heightB np.sqrt(((tl[0] - bl[0]) ** 2) ((tl[1] - bl[1]) ** 2)) maxHeight max(int(heightA), int(heightB)) dst np.array([ [0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1] ], dtypefloat32) M cv2.getPerspectiveTransform(rect, dst) warped cv2.warpPerspective(image, M, (maxWidth, maxHeight)) # 2. 预处理灰度化 二值化 去噪 gray cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY) _, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) denoised cv2.fastNlMeansDenoising(binary, None, 10, 7, 21) # 3. 转 PIL.Image 并调用 Tesseract pil_img Image.fromarray(denoised) try: text pytesseract.image_to_string( pil_img, langlang, configf--psm {psm} --oem 3 -c tessedit_char_whitelist0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ).strip() except Exception as e: text results.append({ box: box.tolist(), text: text, confidence: 0.0 # Tesseract 无内置置信度此处留空 }) return results # 示例调用 if __name__ __main__: image_path 11.png boxes, _ detect_text(image_path) # 上一节函数 ocr_results recognize_text(cv2.imread(image_path), boxes) for res in ocr_results: print(f检测框: {res[box]}, 识别结果: {res[text]})逻辑说明recognize_text的核心是ROI 透视矫正 → 二值化 → Tesseract 识别三步闭环。其中cv2.getPerspectiveTransform将任意四边形映射为矩形消除文本倾斜cv2.THRESH_OTSU自适应阈值避免手动设127tessedit_char_whitelist参数强制只识别字母数字大幅降低乱码率尤其对发票号、订单号等结构化字段。3.3 Tesseract 语言包与配置参数实战对照表场景lang参数--psm--oem效果说明发票金额、日期纯数字符号digits83仅识别0-9 . , ¥ $ €速度最快中文营业执照含汉字英文数字chi_simeng63自动分栏适合多行文本块身份证姓名单行中文chi_sim73强制单行减少换行符干扰商品条码下方文字细小字体eng101--oem 1启用 Legacy Tesseract对小字号更鲁棒注意chi_sim语言包需单独下载sudo apt-get install tesseract-ocr-chi-sim或pip install tesseract-lang若运行时报错TesseractError: (1, Error opening data file...)说明语言包缺失。Windows 用户需在安装 Tesseract 时勾选Chinese (Simplified)选项。4. 端到端流程串联与典型问题排错从 2.jpg 到可落地的识别结果4.1 完整 pipeline 执行命令与输出验证假设你已解压dirsfirst.zip到当前目录执行以下命令启动全流程# 1. 安装必要依赖Python 3.7 pip install opencv-python4.8.1.78 numpy1.24.4 tensorflow1.15.5 pillow10.0.1 pytesseract0.3.10 # 2. 确认 Tesseract 可执行路径Linux/macOS which tesseract # 若返回空需添加路径export PATH/usr/local/bin:$PATH # 3. 运行识别以 2.jpg 为例 python text_recognition.py --image 2.jpg --min-conf 0.4 --width 640 --height 640 --lang chi_simeng --psm 6预期输出应包含控制台打印每个检测框的坐标及识别文本如检测框: [[120, 45], [280, 45], [280, 72], [120, 72]], 识别结果: 北京某某科技有限公司生成2.jpg_result.png原图叠加绿色检测框 黄色文字标签生成2.jpg_result.txt纯文本结果每行一个识别项。参数说明--min-conf 0.4降低置信度阈值以捕获更多文本--width 640 --height 640提升分辨率应对2.jpg中较小字号--psm 6启用自动页面分割适配多行公司信息。4.2 三大高频问题与根因定位法问题 1EAST 检测无任何框输出rects为空列表根因score_map全为 0 或低于min_confidence排查步骤用cv2.imshow查看image是否为全黑/全白cv2.imread失败返回None在decode_predictions函数开头插入print(Max score:, scores.max())若输出 0.1说明模型未加载成功或输入图像格式错误如传入了灰度图检查frozen_east_text_detection.pb文件完整性ls -la frozen_east_text_detection.pb应显示92M若仅1KB则下载损坏。问题 2Tesseract 识别结果为空字符串或乱码如 根因ROI 图像质量差或语言包不匹配排查步骤将warped图像保存为debug_roi_0.png肉眼确认是否清晰若模糊检查cv2.warpPerspective的maxWidth/maxHeight是否过小导致拉伸失真运行tesseract debug_roi_0.png stdout -l chi_sim --psm 7若终端输出乱码证明chi_sim未正确安装尝试--psm 10单字符模式并增加--oem 1对极小字体更有效。问题 3检测框严重偏移如框住空白区域或只框住文字一半根因rW/rH缩放比计算错误或geometry_map解码偏差排查步骤在detect_text函数中打印print(Original size:, (H,W), Resized to:, (width,height), rW/rH:, rW, rH)确认rW W/width严格成立将decode_predictions中pts乘以[rW, rH]前后的坐标打印出来对比是否数量级异常如x_center为1e5则geometry_row[x]未归一化替换为官方 EAST 实现的east_decode函数GitHub:argman/EAST交叉验证。4.3 一个关键技巧用 EAST 的score_map可视化定位低质量区域EAST 的score_map本质是文本区域热力图直接可视化能快速定位问题根源# 在 detect_text 函数中推理后插入 import matplotlib.pyplot as plt plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) plt.title(Score Map) plt.imshow(scores, cmaphot, interpolationnearest) plt.axis(off) plt.subplot(1, 2, 2) plt.title(Original Image with Boxes) for box in rects: cv2.polylines(orig, [box], True, (0, 255, 0), 2) plt.imshow(cv2.cvtColor(orig, cv2.COLOR_BGR2RGB)) plt.axis(off) plt.tight_layout() plt.savefig(debug_scoremap.png, dpi150, bbox_inchestight) plt.show()若score_map中热点与文字位置明显错位如文字在左上角热点却在右下角说明geometry_map的dx1/dy1等参数方向反了——此时需检查geometry_row[x]的索引顺序EAST 原始输出顺序为[x1, y1, x2, y2, angle]但某些冻结模型可能为[dx1, dy1, dx2, dy2, angle]需调整解码逻辑。提示debug_scoremap.png是诊断文本检测失效的黄金快照。当2.jpg中的印章区域被误检为文本时score_map会显示印章边缘的伪热点此时应在decode_predictions中增加形态学过滤对scores做cv2.morphologyEx(scores, cv2.MORPH_CLOSE, kernel)kernel np.ones((3,3))消除孤立噪声点。本文还有配套的精品资源点击获取
返回列表