yolo_crop.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """YOLO 裁剪卡牌区域"""
  4. import os, sys, csv, hashlib, json
  5. import numpy as np
  6. sys.stdout.reconfigure(encoding="utf-8")
  7. sys.path.insert(0, "/home/martin/顾工交接/wzj")
  8. import config
  9. import cv2
  10. DATA = config.DATA_DIR
  11. def md5n(u): return hashlib.md5(u.encode()).hexdigest() + ".jpg"
  12. print("[YOLO] 初始化裁剪器...", flush=True)
  13. from modules.ultralytics_compat import import_yolo # 规避框架根下同名目录遮蔽 ultralytics
  14. YOLO = import_yolo()
  15. yolo = YOLO(config.YOLO_MODEL_PATH, task="segment")
  16. print("[YOLO] 加载完成", flush=True)
  17. CROP_DIR = os.path.join(DATA, "query_crops")
  18. os.makedirs(CROP_DIR, exist_ok=True)
  19. txs = list(csv.DictReader(open(os.path.join(DATA, "transactions_ebay.csv"), encoding="utf-8-sig")))
  20. print("[YOLO] 处理 %d 张图片" % len(txs), flush=True)
  21. cropped = {}
  22. no_crop = 0
  23. for i, tx in enumerate(txs):
  24. tid = tx["tx_id"]
  25. img_path = os.path.join(config.QUERY_IMG_DIR, md5n(tx["img_url"]))
  26. if not os.path.exists(img_path):
  27. continue
  28. try:
  29. results = yolo.predict(img_path, conf=config.YOLO_CONF_THRESHOLD,
  30. imgsz=config.YOLO_IMG_SIZE, verbose=False)
  31. if not results:
  32. no_crop += 1
  33. continue
  34. res = results[0]
  35. orig = res.orig_img
  36. boxes = res.boxes
  37. if boxes is None or len(boxes) == 0:
  38. # 没检测到卡牌,用原图
  39. crop_path = os.path.join(CROP_DIR, md5n(tx["img_url"]))
  40. cv2.imwrite(crop_path, orig)
  41. cropped[tid] = crop_path
  42. continue
  43. xyxy = boxes.xyxy.cpu().numpy()
  44. areas = (xyxy[:, 2] - xyxy[:, 0]) * (xyxy[:, 3] - xyxy[:, 1])
  45. max_idx = int(np.argmax(areas))
  46. x1, y1, x2, y2 = xyxy[max_idx]
  47. h, w = orig.shape[:2]
  48. x1, y1 = max(0, int(x1)), max(0, int(y1))
  49. x2, y2 = min(w, int(x2)), min(h, int(y2))
  50. if x2 <= x1 or y2 <= y1:
  51. cv2.imwrite(os.path.join(CROP_DIR, md5n(tx["img_url"])), orig)
  52. cropped[tid] = os.path.join(CROP_DIR, md5n(tx["img_url"]))
  53. continue
  54. crop = orig[y1:y2, x1:x2]
  55. crop_path = os.path.join(CROP_DIR, md5n(tx["img_url"]))
  56. cv2.imwrite(crop_path, crop)
  57. cropped[tid] = crop_path
  58. if (i+1) % 10 == 0:
  59. print("[YOLO] %d/%d 裁剪完成" % (i+1, len(txs)), flush=True)
  60. except Exception as e:
  61. no_crop += 1
  62. print("[YOLO] 完成! 成功裁剪 %d 张, 失败 %d 张" % (len(cropped), no_crop), flush=True)
  63. print("[YOLO] 裁剪图保存于: %s" % CROP_DIR, flush=True)