cut_dialog_blocks.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 简单的绿色线框检测和文字块切割脚本
  5. """
  6. import cv2
  7. import numpy as np
  8. import sys
  9. from pathlib import Path
  10. def detect_green_boxes_and_cut(image_path, output_dir):
  11. """检测绿色线框并切割文字块"""
  12. # 读取图片
  13. img_data = np.fromfile(str(image_path), dtype=np.uint8)
  14. img = cv2.imdecode(img_data, cv2.IMREAD_COLOR)
  15. if img is None:
  16. raise ValueError(f"无法读取图片: {image_path}")
  17. print(f"[INFO] 图片尺寸: {img.shape[1]}x{img.shape[0]}")
  18. # 检测绿色线框
  19. # 绿色范围 (BGR格式)
  20. lower_green = np.array([0, 100, 0])
  21. upper_green = np.array([100, 255, 100])
  22. # 创建绿色掩码
  23. mask = cv2.inRange(img, lower_green, upper_green)
  24. # 寻找轮廓
  25. contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  26. if len(contours) == 0:
  27. print("[INFO] 未检测到绿色线框")
  28. return
  29. # 获取边界矩形
  30. boxes = []
  31. for contour in contours:
  32. x, y, w, h = cv2.boundingRect(contour)
  33. if w > 10 and h > 10: # 过滤小框
  34. boxes.append({'x': x, 'y': y, 'w': w, 'h': h})
  35. if len(boxes) == 0:
  36. print("[INFO] 未找到有效的文字框")
  37. return
  38. print(f"[INFO] 检测到 {len(boxes)} 个绿色文字框")
  39. # 按从右到左、从上到下排序
  40. boxes.sort(key=lambda b: (b['y'], -b['x']))
  41. # 确保输出目录存在
  42. Path(output_dir).mkdir(parents=True, exist_ok=True)
  43. # 切割并保存每个文字块
  44. for i, box in enumerate(boxes, 1):
  45. x, y, w, h = box['x'], box['y'], box['w'], box['h']
  46. # 添加少量边距
  47. padding = 5
  48. x = max(0, x - padding)
  49. y = max(0, y - padding)
  50. w = min(w + 2 * padding, img.shape[1] - x)
  51. h = min(h + 2 * padding, img.shape[0] - y)
  52. # 切割区域
  53. dialog_img = img[y:y+h, x:x+w]
  54. # 保存文件
  55. output_file = Path(output_dir) / f"dialog_{i}.png"
  56. success, encoded = cv2.imencode('.png', dialog_img)
  57. if success:
  58. encoded.tofile(str(output_file))
  59. print(f"[{i}/{len(boxes)}] 保存: {output_file.name} ({w}x{h})")
  60. print(f"✅ 文字块切割完成: {len(boxes)} 个")
  61. if __name__ == '__main__':
  62. if len(sys.argv) != 3:
  63. print("用法: python cut_dialog_blocks.py <图片路径> <输出目录>")
  64. sys.exit(1)
  65. try:
  66. detect_green_boxes_and_cut(sys.argv[1], sys.argv[2])
  67. except Exception as e:
  68. print(f"[ERROR] {e}")
  69. sys.exit(1)