draw_panel_mask.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 根据格子检测结果绘制黑线白底遮罩图片
  5. 用于步骤5: 根据detectComicPanels()函数返回的结果,绘制出黑线白底遮罩图片
  6. """
  7. import os
  8. import sys
  9. import json
  10. import cv2
  11. import numpy as np
  12. from pathlib import Path
  13. def draw_panel_mask(json_path, output_dir):
  14. """
  15. 根据格子检测JSON结果绘制遮罩图
  16. Args:
  17. json_path: 格子检测结果JSON文件路径
  18. output_dir: 输出目录
  19. """
  20. try:
  21. print(f"[INFO] 读取格子检测结果: {json_path}")
  22. # 读取格子检测结果
  23. if not os.path.exists(json_path):
  24. raise FileNotFoundError(f"JSON文件不存在: {json_path}")
  25. with open(json_path, 'r', encoding='utf-8') as f:
  26. panel_data = json.load(f)
  27. # 获取图片信息
  28. image_size = panel_data.get('image_size', {})
  29. width = image_size.get('width', 800)
  30. height = image_size.get('height', 600)
  31. panels = panel_data.get('panels', [])
  32. print(f"[INFO] 图片尺寸: {width}x{height}")
  33. print(f"[INFO] 格子数量: {len(panels)}")
  34. # 创建白色背景的遮罩图 (白底)
  35. mask = np.ones((height, width, 3), dtype=np.uint8) * 255
  36. # 绘制格子边框 (黑线)
  37. line_thickness = 2
  38. line_color = (0, 0, 0) # 黑色
  39. for i, panel in enumerate(panels):
  40. bbox = panel.get('bbox', {})
  41. if not bbox:
  42. continue
  43. x1 = int(bbox.get('x1', 0))
  44. y1 = int(bbox.get('y1', 0))
  45. x2 = int(bbox.get('x2', width))
  46. y2 = int(bbox.get('y2', height))
  47. # 绘制矩形边框
  48. cv2.rectangle(mask, (x1, y1), (x2, y2), line_color, line_thickness)
  49. print(f"[DEBUG] 绘制格子 {i+1}: ({x1}, {y1}) -> ({x2}, {y2})")
  50. # 保存遮罩图
  51. json_filename = Path(json_path).stem
  52. # 移除 _panels 后缀,添加 _panel_mask 后缀
  53. if json_filename.endswith('_panels'):
  54. base_name = json_filename[:-8] # 移除 '_panels'
  55. else:
  56. base_name = json_filename
  57. mask_filename = f"{base_name}_panel_mask.png"
  58. mask_path = os.path.join(output_dir, mask_filename)
  59. cv2.imwrite(mask_path, mask)
  60. print(f"[OK] 遮罩图已保存: {mask_path}")
  61. return {
  62. 'mask_path': mask_path,
  63. 'panels_count': len(panels),
  64. 'image_size': {'width': width, 'height': height}
  65. }
  66. except Exception as e:
  67. print(f"[ERROR] 绘制遮罩图失败: {e}")
  68. import traceback
  69. traceback.print_exc()
  70. raise
  71. def main():
  72. """主函数"""
  73. if len(sys.argv) < 3:
  74. print("用法: python draw_panel_mask.py <json_path> <output_dir>")
  75. print("示例: python draw_panel_mask.py panels.json ./output")
  76. sys.exit(1)
  77. json_path = sys.argv[1]
  78. output_dir = sys.argv[2]
  79. # 确保输出目录存在
  80. os.makedirs(output_dir, exist_ok=True)
  81. try:
  82. result = draw_panel_mask(json_path, output_dir)
  83. print(f"[SUCCESS] 成功绘制遮罩图,包含 {result['panels_count']} 个格子")
  84. sys.exit(0)
  85. except Exception as e:
  86. print(f"[ERROR] 程序执行失败: {e}")
  87. sys.exit(1)
  88. if __name__ == "__main__":
  89. main()