grading_ocr_step2.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. """
  3. grading_ocr_step2.py - 对裁剪出的评级标签条跑 PaddleOCR,输出分行文本
  4. 运行:
  5. conda activate paddleocr
  6. python grading_ocr_step2.py
  7. 输出:
  8. - ocr_result.json: 每张图的 OCR 分行文本列表
  9. - ocr_summary.csv: 汇总表(文件名,真实类别,评级框,置信度,OCR分行文本)
  10. """
  11. import os
  12. import sys
  13. import json
  14. import csv
  15. sys.stdout.reconfigure(encoding="utf-8")
  16. OUT = "/home/martin/顾工交接/wzj/grading_ocr"
  17. CROP_DIR = os.path.join(OUT, "crops")
  18. RECORDS = os.path.join(OUT, "crop_records.json")
  19. print("[OCR] 初始化 PaddleOCR ...")
  20. from paddleocr import PaddleOCR
  21. ocr = PaddleOCR(
  22. use_doc_orientation_classify=True, # 开启方向分类,旋转卡文本识别更准
  23. use_doc_unwarping=False,
  24. use_textline_orientation=True,
  25. )
  26. print("[OCR] 加载完成\n")
  27. # 读裁剪记录
  28. with open(RECORDS, "r", encoding="utf-8") as f:
  29. records = json.load(f)
  30. ocr_results = {}
  31. rows_csv = []
  32. print(f"[OCR] 处理 {len(records)} 张裁剪图 ...\n")
  33. for i, rec in enumerate(records):
  34. crop_path = rec["crop_path"]
  35. name = rec["file"]
  36. true_label = rec["true_label"]
  37. box = rec["box"]
  38. conf = rec["conf"]
  39. try:
  40. result = ocr.predict(crop_path)
  41. except Exception as e:
  42. print(f"[{i+1}/{len(records)}] {name} OCR失败: {e}")
  43. ocr_results[name] = {"lines": [], "error": str(e)}
  44. rows_csv.append([name, true_label, str(box) if box else "", conf or "", ""])
  45. continue
  46. # 提取分行文本
  47. lines = []
  48. for res in result:
  49. if isinstance(res, dict):
  50. texts = res.get("rec_texts")
  51. if texts:
  52. lines.extend(list(texts))
  53. elif hasattr(res, "rec_texts") and res.rec_texts:
  54. lines.extend(list(res.rec_texts))
  55. # 合并分行文本(用 | 分隔,便于CSV查看)
  56. text_joined = " | ".join(lines) if lines else ""
  57. ocr_results[name] = {"lines": lines, "text": text_joined}
  58. rows_csv.append([name, true_label, str(box) if box else "", conf or "", text_joined])
  59. # 打印前20条示例
  60. if i < 20:
  61. print(f"[{i+1}] {true_label}/{name}")
  62. for ln in lines:
  63. print(f" {ln}")
  64. print()
  65. # 保存 JSON
  66. with open(os.path.join(OUT, "ocr_result.json"), "w", encoding="utf-8") as f:
  67. json.dump(ocr_results, f, ensure_ascii=False, indent=2)
  68. print(f"\n[OCR] JSON 已保存: {OUT}/ocr_result.json")
  69. # 保存 CSV
  70. csv_path = os.path.join(OUT, "ocr_summary.csv")
  71. with open(csv_path, "w", encoding="utf-8-sig", newline="") as f:
  72. w = csv.writer(f)
  73. w.writerow(["filename", "true_label", "box_xyxy", "conf", "ocr_text_lines"])
  74. w.writerows(rows_csv)
  75. print(f"[OCR] CSV 已保存: {csv_path}")
  76. # 统计
  77. n_empty = sum(1 for v in ocr_results.values() if not v.get("lines"))
  78. print(f"\n统计: 共 {len(records)} 张, OCR空文本 {n_empty} 张")