_tmp_probe_offset.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. # -*- coding: utf-8 -*-
  2. """量出各页「单位名称文字中心」与「已盖红章中心」的偏差,得出校正量。"""
  3. import io
  4. import os
  5. import sys
  6. import fitz
  7. import numpy as np
  8. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
  9. HERE = os.path.dirname(os.path.abspath(__file__))
  10. PDF = os.path.join(HERE, "_tmp_inspect", "sealed.pdf")
  11. COMPANY = "北京智造易科技有限公司"
  12. PAGES = [1, 5, 6, 7, 9, 12, 46, 61, 62, 65, 76, 79, 91]
  13. d = fitz.open(PDF)
  14. p0 = d[0]
  15. print(f"page.rect {p0.rect} mediabox {p0.mediabox} rotation {p0.rotation}")
  16. print(f"即 {p0.rect.width / 72 * 25.4:.1f}×{p0.rect.height / 72 * 25.4:.1f} mm\n")
  17. print(f"{'页':>4} {'文字中心 x,y':>18} {'红章中心 x,y':>18} "
  18. f"{'Δx':>7} {'Δy':>7} {'章直径mm':>9}")
  19. for pno in PAGES:
  20. pg = d[pno - 1]
  21. hits = pg.search_for(COMPANY)
  22. # 红章:取红色像素连通范围(整页扫描件页会误判,这些页没有扫描件)
  23. pm = pg.get_pixmap(dpi=100)
  24. a = np.frombuffer(pm.samples, dtype=np.uint8).reshape(pm.height, pm.width, pm.n)
  25. r, g, b = a[..., 0].astype(int), a[..., 1].astype(int), a[..., 2].astype(int)
  26. red = (r > 110) & (r - g > 55) & (r - b > 55)
  27. ys, xs = np.nonzero(red)
  28. if not len(ys) or not hits:
  29. print(f"{pno:>4} 未找到(文字 {len(hits)} 处,红像素 {len(ys)})")
  30. continue
  31. sc = 72 / 100
  32. cx = (xs.min() + xs.max()) / 2 * sc
  33. cy = (ys.min() + ys.max()) / 2 * sc
  34. dia = (xs.max() - xs.min() + 1) * sc / 72 * 25.4
  35. # 文字命中可能多处,取与红章最近的
  36. best = min(hits, key=lambda rc: abs((rc.y0 + rc.y1) / 2 - cy))
  37. tx, ty = (best.x0 + best.x1) / 2, (best.y0 + best.y1) / 2
  38. print(f"{pno:>4} {tx:8.1f},{ty:8.1f} {cx:8.1f},{cy:8.1f} "
  39. f"{cx - tx:+7.1f} {cy - ty:+7.1f} {dia:9.1f}")
  40. d.close()