HyOCR-1.5 读图报错时

HyOCR-1.5 读图报错时

2026-10-20 18:07:04 0点赞 0收藏 0评论

同一批图片里有的能识别、有的直接报错,先不要急着把问题归到 HyOCR-1.5 的模型能力上。读图报错通常落在三段里:输入图片本身的格式与通道、预处理链路(解码、缩放、旋转、格式转换)、以及调用时传的参数。最快的排查顺序是抽一张报错图做最小复现,再把预处理每一步的中间图落盘,和同批能跑通的样本逐项比对。多数“有的行有的不行”的情况,能在预处理环节看到图片被改了通道数、被二次有损压缩、被自动旋转,或者被转成了模型不接受的位深与色彩模式。

判断方向:先确认预处理链路有没有把图改坏,再讨论模型或参数。操作上抽单张报错图建最小复现目录,预处理每步落盘中间图,用格式、通道、位深、EXIF 方向与同批正常样本对比。验证方式是比较中间图与原始图的元信息和肉眼观感。边界:如果原始图不经任何预处理直接送模型仍报错,问题在输入形态或调用参数,不在预处理;异常兜底只能隔离坏图,不能代替修复。

把报错样本单独抽出来,做成最小复现目录

批量脚本里同时存在遍历、预处理、并发、重试等因素,直接跑整批很难判断报错来自哪一步。先把报错的那张图原样复制出来,不要用图片查看器另存,另存会改变编码和元信息。目录建议按下面组织,原始样本与中间产物分开,日志单独存放:

repro/ input/ bad_001.png # 报错样本,原样拷贝 good_001.jpg # 同批能跑通的对照样本 steps/ # 预处理各步中间图 fails/ # 兜底逻辑捕获的失败样本 logs/ run.log traceback.txt run_repro.py

复现命令固定为单图、单进程、关闭重试,把标准输出和标准错误一起留存。下面的写法可以直接替换成你项目里的入口脚本:

python run_repro.py `--image` input/bad_001.png `--steps` steps/bad_001 2>&1 | tee logs/run.log sha256sum input/bad_001.png input/good_001.jpg >> logs/run.log python -c "from PIL import Image; im=Image.open('input/bad_001.png'); print(im.format, im.mode, im.size, im.info)" >> logs/run.log

报错文本要完整记录,不要只留最后一行。需要保留的内容包括:完整 traceback、实际执行的命令行、输入文件的 sha256、图片的 format/mode/size 与 info 字段(EXIF、ICC、transparency 等)、以及 HyOCR-1.5 运行环境的版本信息。同一张图重复跑两次,如果报错位置一致,基本可以排除偶发的 IO 或并发问题。

HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图

在预处理每一步后落盘中间图,确认哪一步改了数据

预处理通常是解码、缩放、旋转、通道转换、格式保存几段的串联,报错往往发生在最后一步才知道,但根因在前面。做法是在每段之后把当前图像落盘为 PNG,PNG 无损,能避免因保存 JPEG 再次引入压缩差异。下面是通用骨架,函数名按你项目的实际接口替换:

import os from PIL import Image def dump(tag, img, outdir): os.makedirs(outdir, exist_ok=True) name = f"{tag}_{img.width}x{img.height}_{img.mode}.png" img.save(os.path.join(outdir, name)) print(tag, img.mode, img.size, img.info.get("exif") is not None) raw = Image.open(src) dump("01_decode", raw, outdir) img = raw.convert("RGB") if raw.mode not in ("RGB", "L") else raw.copy() dump("02_channel", img, outdir) img = img.resize((target_w, target_h), Image.BICUBIC) dump("03_resize", img, outdir) img = img.rotate(angle, expand=True) dump("04_rotate", img, outdir)

命名规则建议固定为“序号_步骤_宽x高_模式.扩展名”,例如 02_channel_1240x1754_RGB.png。这样在目录里按名称排序就是执行顺序,肉眼和脚本都能快速定位。检查分两类:肉眼检查方向是否正确、是否被截断、透明区域是否变成黑底、文字边缘是否被过度锐化或糊化;元信息检查尺寸、模式、通道数、位深、EXIF Orientation 是否被消费掉、ICC 配置是否丢失、是否从 P 模式或 CMYK 转成了别的形态。两类检查都要做,只靠肉眼容易漏掉通道与方向问题。

校验输入格式与色彩通道,和能跑通的样本对比

当中间图看起来正常、报错仍然出现时,需要确认这张图的形态是不是模型不支持的输入。写一个小脚本把整批图的格式、模式、通道数、尺寸和异常标记列出来,正常样本与报错样本放在同一张表里对照:

HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图

from PIL import Image import numpy as np, sys for p in sys.argv[1:]: with Image.open(p) as im: arr = np.asarray(im) print(p, im.format, im.mode, im.size, arr.shape, arr.dtype, im.info.get("exif") is not None, "transparency" in im.info)

对比记录表按行记录样本,按列记录形态特征,便于看出差异集中在哪一列:

样本formatmode通道/位深EXIF 方向结果bad_001PNGRGBA4ch/8bit有报错good_001JPEGRGB3ch/8bit无正常

常见需要进入转换清单的样本包括:带 alpha 通道的 PNG、P 模式或含 transparency 的图、CMYK 的 JPEG、16 位灰度、带 EXIF 方向的手机照片、扩展名与实际编码不一致的文件。整理出清单后统一走同一条转换规则,而不是在调用处零散修补。

在调用处加输入校验与异常兜底,避免整批中断

确认坏图形态之后,调用处需要做两件事:进入 HyOCR-1.5 之前先校验,失败时捕获并隔离。下面的骨架是通用写法,OCR 函数替换成实际调用即可:

HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图HyOCR-1.5 读图报错时 / 先确认预处理链路有没有改坏图

import os, shutil, traceback ALLOWED = {"RGB", "L"} def check_image(path): from PIL import Image with Image.open(path) as im: im.verify() with Image.open(path) as im: if im.mode not in ALLOWED: im = im.convert("RGB") return im.copy() fails = [] for path in batch: try: img = check_image(path) result = ocr(img) # 替换为 HyOCR-1.5 调用 except Exception as e: dst = os.path.join("fails", os.path.basename(path)) os.makedirs("fails", exist_ok=True) shutil.copy(path, dst) fails.append((path, type(e).__name__, str(e)[:200])) continue

失败样本统一落到 fails/,并单独写一份失败清单,记录路径、异常类型和异常首行。跳过还是重试要看原因:解码失败、格式或通道不支持,属于确定性问题,直接跳过并记录,重试通常没有意义;文件读取超时、临时占用这类问题可以有限次重试,重试次数要封顶并记录每次尝试。不要在异常分支里静默 pass,那会让坏图在结果里无声消失。

重跑原批次,确认报错样本被隔离而不是被吞掉

兜底加上之后必须重跑原批次验证。命令与正式任务保持一致,只把输出目录指向验证用的位置,避免覆盖既有结果:

python run_batch.py `--input` batch/ `--out` out_check/ 2>&1 | tee logs/rerun.log wc -l logs/fails.tsv

核对方式做数量对账:输入文件总数应等于成功数、失败数、跳过数之和,差额为 0 才算没有静默丢失。再逐条打开 fails.tsv,确认之前的 bad_001 出现在失败清单里,而不是出现在成功结果里,也不是两边都没有。日志里需要保留的字段至少包括:时间、输入绝对路径、sha256、预处理步骤名、异常类型、traceback 首行、处理耗时、最终状态。保留这些字段,下一次再遇到同类报错时,可以直接从日志判断是同一类形态问题还是新问题。

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
京东京享红包
距结束::
领京东现金红包 天天领3次 最高26888元
红包按钮
最新文章 热门文章
0
扫一下,分享更方便,购买更轻松