show_mask.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import os
  2. import torch
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. from glob import glob
  6. def save_full_mask(
  7. mask: torch.Tensor,
  8. name="mask",
  9. out_dir="output",
  10. save_png=True,
  11. save_txt=True,
  12. save_npy=False,
  13. max_files=100,
  14. save_all_zero=False,
  15. zero_eps=1e-6,
  16. # ÐÂÔö²ÎÊý
  17. image=None, # PIL.Image »ò numpy(H,W,3)
  18. show_on_image=False, # ÊÇ·ñ±£´æµþ¼ÓµÄͼ
  19. alpha=0.4 # mask͸Ã÷¶È
  20. ):
  21. """
  22. ±£´æÕûÕÅÌØÕ÷ͼ£¬¿ÉÑ¡ÔñÉú³Éµþ¼ÓԭͼºóµÄ¿ÉÊÓ»¯Îļþ
  23. """
  24. # È¥µô batch/channel ¶àÓàά¶È
  25. if mask.dim() == 4:
  26. mask = mask[0, 0]
  27. elif mask.dim() == 3:
  28. mask = mask[0]
  29. # ---------------- È« 0 ÅжϺ¯Êý ----------------
  30. def is_all_zero(t: torch.Tensor):
  31. if t.dtype.is_floating_point:
  32. return torch.all(torch.abs(t) < zero_eps)
  33. else:
  34. return torch.all(t == 0)
  35. # È« 0 Çé¿ö´¦Àí
  36. if is_all_zero(mask):
  37. print(f"? {name} È« 0")
  38. if not save_all_zero:
  39. print(f"¡ú δ±£´æ£¨save_all_zero=False£©")
  40. return
  41. else:
  42. print(f"¡ú °´ÉèÖüÌÐø±£´æ£¨save_all_zero=True£©")
  43. os.makedirs(out_dir, exist_ok=True)
  44. mask_cpu = mask.detach().cpu()
  45. # ------------------- ·ÖÅäÐòºÅ -------------------
  46. pattern = os.path.join(out_dir, f"{name}_*.png")
  47. existing_files = sorted(glob(pattern))
  48. if existing_files:
  49. existing_idx = []
  50. for f in existing_files:
  51. try:
  52. existing_idx.append(int(os.path.basename(f).split("_")[-1].split(".")[0]))
  53. except:
  54. pass
  55. next_idx = max(existing_idx) + 1
  56. else:
  57. next_idx = 0
  58. if next_idx >= max_files:
  59. next_idx = next_idx % max_files
  60. file_idx_str = f"{next_idx:03d}"
  61. # ==========================================================
  62. # ¢Ù ±£´æ mask ±¾Éí
  63. # ==========================================================
  64. # ¡ª¡ª¡ª ±£´æ PNG ¡ª¡ª¡ª
  65. if save_png:
  66. png_path = os.path.join(out_dir, f"{name}_{file_idx_str}.png")
  67. plt.figure()
  68. plt.imshow(mask_cpu, cmap="gray")
  69. plt.colorbar()
  70. plt.title(name)
  71. plt.savefig(png_path, dpi=300)
  72. plt.close()
  73. print(f"?? saved PNG -> {png_path}")
  74. # ¡ª¡ª¡ª ±£´æ TXT ¡ª¡ª¡ª
  75. if save_txt:
  76. txt_path = os.path.join(out_dir, f"{name}_{file_idx_str}.txt")
  77. np.savetxt(txt_path, mask_cpu.numpy(), fmt="%.3f")
  78. print(f"?? saved TXT -> {txt_path}")
  79. # ¡ª¡ª¡ª ±£´æ NPY ¡ª¡ª¡ª
  80. if save_npy:
  81. npy_path = os.path.join(out_dir, f"{name}_{file_idx_str}.npy")
  82. np.save(npy_path, mask_cpu.numpy())
  83. print(f"?? saved NPY -> {npy_path}")
  84. # ==========================================================
  85. # ¢Ú ±£´æµþ¼ÓЧ¹û£¨²»ÏÔʾ£¬Ö»±£´æ£©
  86. # ==========================================================
  87. if show_on_image:
  88. if image is None:
  89. print("? show_on_image=True µ«Î´´«Èë image£¬Ìø¹ýµþ¼Ó±£´æ")
  90. return
  91. # Èç¹ûÈ« 0£¬¾Í²»×öµþ¼Ó±£´æ
  92. if is_all_zero(mask):
  93. print(f"? {name} È« 0 ¡ú ²»Éú³Éµþ¼Ó overlay")
  94. return
  95. # image ¡ú numpy
  96. if hasattr(image, "size"): # PIL.Image
  97. img_np = np.array(image)
  98. else: # numpy array
  99. img_np = image
  100. mask_np = mask_cpu.numpy()
  101. if mask_np.dtype != np.uint8:
  102. mask_np = (mask_np > 0).astype(np.uint8)
  103. # ºìÉ«°ë͸Ã÷µþ¼Ó
  104. colored_mask = np.zeros((*mask_np.shape, 3), dtype=np.uint8)
  105. colored_mask[..., 0] = mask_np * 255 # R channel
  106. overlay_path = os.path.join(out_dir, f"{name}_{file_idx_str}_overlay.png")
  107. plt.figure(figsize=(8, 8))
  108. plt.imshow(img_np)
  109. plt.imshow(colored_mask, alpha=alpha)
  110. plt.title(f"{name} overlay")
  111. plt.title(f"{name} overlay")
  112. plt.axis('off')
  113. # ? ²»µ÷Óà plt.show()£¬Ö±½Ó±£´æ
  114. plt.savefig(overlay_path, dpi=300)
  115. plt.close()
  116. print(f"?? saved overlay -> {overlay_path}")