infer_test.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # -*- coding: utf-8 -*-
  2. """在测试集上推理并按真实类别(文件夹名)统计识别结果,同时保存标注图。"""
  3. import glob
  4. import json
  5. import os
  6. from collections import Counter
  7. from ultralytics import YOLO
  8. ROOT = "/home/martin/顾工交接/wzj/test" # 4 个子文件夹 BGS/CGC/PSA/SGC
  9. OUT = "/home/martin/顾工交接/wzj/test_predict" # 标注图输出(保留子目录)
  10. BEST = "/home/martin/顾工交接/wzj/ultralytics/runs/detect/card_v1/weights/best.pt"
  11. CONF = 0.25
  12. FOLDERS = ["BGS", "CGC", "PSA", "SGC"]
  13. model = YOLO(BEST)
  14. matrix = {f: Counter() for f in FOLDERS}
  15. total = {f: 0 for f in FOLDERS}
  16. records = [] # 每张图: {true, pred, conf, file}
  17. for f in FOLDERS:
  18. imgs = []
  19. for ext in ("*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG"):
  20. imgs += glob.glob(os.path.join(ROOT, f, ext))
  21. imgs = sorted(set(imgs))
  22. total[f] = len(imgs)
  23. print(f"推理 {f}: {len(imgs)} 张 ...", flush=True)
  24. outdir = os.path.join(OUT, f)
  25. os.makedirs(outdir, exist_ok=True)
  26. for imgpath in imgs:
  27. r = model(imgpath, conf=CONF, verbose=False, imgsz=640)[0]
  28. name = os.path.basename(imgpath)
  29. if r.boxes is None or len(r.boxes) == 0:
  30. matrix[f]["(无检测)"] += 1
  31. records.append({"true": f, "pred": "(无检测)", "conf": 0.0, "file": name})
  32. continue
  33. i = int(r.boxes.conf.argmax())
  34. pred = model.names[int(r.boxes.cls[i])]
  35. conf = float(r.boxes.conf[i])
  36. matrix[f][pred] += 1
  37. records.append({"true": f, "pred": pred, "conf": round(conf, 4), "file": name})
  38. r.save(filename=os.path.join(outdir, name))
  39. # 汇总
  40. print("\n================ 识别结果 ================")
  41. tot = tot_correct_family = tot_correct_exact = 0
  42. for f in FOLDERS:
  43. n = total[f]
  44. tot += n
  45. print(f"\n真实类别 {f} (共 {n} 张):")
  46. for pred, c in matrix[f].most_common():
  47. print(f" 预测 {pred:16} {c:4} ({c / n * 100:5.1f}%)")
  48. fam = sum(c for p, c in matrix[f].items() if p.startswith(f))
  49. ex = matrix[f].get(f, 0)
  50. tot_correct_family += fam
  51. tot_correct_exact += ex
  52. print(f" -> {f} 系列正确: {fam}/{n} = {fam / n * 100:.1f}% 完全相等: {ex}/{n} = {ex / n * 100:.1f}%")
  53. print("\n================ 总体 ================")
  54. print(f"主类(系列)正确: {tot_correct_family}/{tot} = {tot_correct_family / tot * 100:.2f}%")
  55. print(f"完全相等: {tot_correct_exact}/{tot} = {tot_correct_exact / tot * 100:.2f}%")
  56. os.makedirs(OUT, exist_ok=True)
  57. with open(os.path.join(OUT, "test_predictions.json"), "w", encoding="utf-8") as fp:
  58. json.dump({"totals": {f: total[f] for f in FOLDERS},
  59. "matrix": {f: dict(matrix[f]) for f in FOLDERS},
  60. "overall_family_acc": tot_correct_family / tot,
  61. "overall_exact_acc": tot_correct_exact / tot,
  62. "records": records}, fp, ensure_ascii=False, indent=2)
  63. print(f"\n逐图预测明细已存: {OUT}/test_predictions.json")
  64. print(f"标注图已存: {OUT}/<类别>/")