# -*- coding: utf-8 -*- """定标授权书扫描件:找纸张/版心边界,反推公章、印鉴、签名的真实毫米数。""" import io import os import sys import numpy as np from PIL import Image sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") HERE = os.path.dirname(os.path.abspath(__file__)) SRC = os.path.join(HERE, "_bid_assets", "seal_src", "p1_img1.png") SEAL = os.path.join(HERE, "_bid_assets", "seal") OUT = os.path.join(HERE, "_tmp_inspect") os.makedirs(OUT, exist_ok=True) im = Image.open(SRC).convert("RGB") a = np.asarray(im.convert("L")) h, w = a.shape print(f"扫描件 {w}×{h} px,宽高比 {w / h:.4f}" f"(A4 竖版应为 {210 / 297:.4f})") # 纸张边界:扫描仪底色通常明显暗于纸面 row_med = np.median(a, axis=1) col_med = np.median(a, axis=0) print(f"行中位亮度:首 {row_med[:8].astype(int)} … 末 {row_med[-8:].astype(int)}") print(f"列中位亮度:首 {col_med[:8].astype(int)} … 末 {col_med[-8:].astype(int)}") # 版心(印刷内容)边界:按暗像素投影 dark = a < 170 cols = dark.sum(axis=0) rows = dark.sum(axis=1) thr_c, thr_r = max(6, h // 400), max(6, w // 400) xs = np.nonzero(cols > thr_c)[0] ys = np.nonzero(rows > thr_r)[0] print(f"\n内容范围 x[{xs.min()}, {xs.max()}] y[{ys.min()}, {ys.max()}]" f" 即 {xs.max() - xs.min() + 1}×{ys.max() - ys.min() + 1} px") # 假定纸张为 A4 且扫描件已裁到纸张边缘 for label, paper_w in (("按整幅=A4宽210mm", 210.0), ("按整幅=A4高297mm定标", 297.0 * w / h)): mm_px = paper_w / w print(f"\n【{label}】1 px = {mm_px:.4f} mm → 整幅 " f"{w * mm_px:.0f}×{h * mm_px:.0f} mm") for name in ("gongzhang", "yinjian", "signature"): p = os.path.join(SEAL, f"{name}.png") if not os.path.exists(p): continue al = np.asarray(Image.open(p))[..., 3] ys2, xs2 = np.nonzero(al > 8) bw, bh = xs2.max() - xs2.min() + 1, ys2.max() - ys2.min() + 1 print(f" {name:10s} {bw:4d}×{bh:4d} px = " f"{bw * mm_px:5.1f}×{bh * mm_px:5.1f} mm") im.resize((w // 3, h // 3), Image.LANCZOS).save( os.path.join(OUT, "seal_src_thumb.jpg"), quality=80) print(f"\n缩略图 → {os.path.join(OUT, 'seal_src_thumb.jpg')}")