Files
ocr_data/tools/查合成图尺寸.py
2026-09-28 16:09:31 +08:00

94 lines
3.2 KiB
Python

# -*- coding: utf-8 -*-
"""
统计合成图的【像素尺寸】, 看有多少张超大(最长边>阈值) → 判断是不是OCR超时的根因。
纯标准库, 不依赖 PIL / cv2 / 项目代码。只读JPEG文件头, 不解码, 很快。
用法:
python3 tools/查合成图尺寸.py # 默认扫 ./split/**/composite/, 阈值4000
python3 tools/查合成图尺寸.py --dir ./split --max 4000
"""
import argparse
import glob
import os
def jpeg_size(path):
"""只读 JPEG 文件头拿 (宽,高), 不解码。失败返回 None。"""
try:
with open(path, 'rb') as f:
if f.read(2) != b'\xff\xd8':
return None
while True:
b = f.read(1)
while b and b != b'\xff':
b = f.read(1)
marker = f.read(1)
while marker == b'\xff':
marker = f.read(1)
if not marker:
return None
m = marker[0]
if 0xC0 <= m <= 0xCF and m not in (0xC4, 0xC8, 0xCC):
f.read(3)
h = int.from_bytes(f.read(2), 'big')
w = int.from_bytes(f.read(2), 'big')
return w, h
seg = int.from_bytes(f.read(2), 'big')
if seg < 2:
return None
f.seek(seg - 2, 1)
except Exception:
return None
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--dir', default='./split')
ap.add_argument('--max', type=int, default=4000, help='超大阈值(最长边像素)')
args = ap.parse_args()
pats = [os.path.join(args.dir, '**', 'composite', '*.jpg'),
os.path.join(args.dir, '**', '*.jpg')]
files = []
for p in pats:
files = glob.glob(p, recursive=True)
if files:
break
files = [f for f in files if 'composite' in f]
if not files:
print(f"在 {args.dir} 下没找到 composite/*.jpg")
return
tot = over = mx = 0
sizes = []
for f in files:
sz = jpeg_size(f)
if sz:
tot += 1
m = max(sz)
mx = max(mx, m)
sizes.append((os.path.getsize(f), sz, f))
if m > args.max:
over += 1
print("=" * 56)
print(f"合成图 {tot} 张 | 最长边>{args.max} 的 {over} 张 "
f"({over/tot*100:.0f}%) | 最大最长边 {mx}px")
print("=" * 56)
print("最大的 8 张:")
for fsize, (w, h), f in sorted(sizes, reverse=True)[:8]:
flag = ' <== 超大' if max(w, h) > args.max else ''
print(f" {fsize//1024:5d}KB {w}x{h} 最长边={max(w,h)}{flag}")
print()
if over > tot * 0.3:
print(f"⚠ {over}/{tot} 张超大 → 实锤: 超大合成图就是OCR超时根因。")
print(f" 部署 ocr_max_image_side={args.max} 后, 这些缩到 {args.max}px, OCR 从30s降到几秒。")
elif over == 0:
print("✓ 没有超大图(尺寸都正常) → 超时不是图大, 是端点问题(共享/波动)。")
else:
print(f"部分超大({over}张), 部署尺寸上限能缓解这部分。")
if __name__ == '__main__':
main()