"""样本初探:检查 mark alpha 通道、尺寸,生成可视化素材到 try/visual/。""" from pathlib import Path import cv2 import numpy as np ROOT = Path(__file__).resolve().parent.parent CAP = ROOT / "captchas" OUT = ROOT / "try" / "visual" OUT.mkdir(parents=True, exist_ok=True) def mark_stats(path): """读取 mark 图,返回 (形状, 通道数, alpha>128 占比, 有效bbox) 或 None。""" try: m = cv2.imread(str(path), cv2.IMREAD_UNCHANGED) if m is None: return None ch = m.shape[2] if m.ndim == 3 else 1 a = m[..., 3] if ch == 4 else np.full(m.shape[:2], 255, np.uint8) ys, xs = np.where(a > 128) if len(xs) == 0: return m.shape, ch, 0.0, None bbox = (int(xs.min()), int(ys.min()), int(xs.max()) + 1, int(ys.max()) + 1) return m.shape, ch, float((a > 128).mean()), bbox except Exception as e: # 坏文件不中断批次 print(f" 读取失败: {e}") return None def main(): pairs = sorted({p.name.replace("-mark.png", "") for p in CAP.glob("*-mark.png")}) print(f"共 {len(pairs)} 对样本\n") for name in pairs: st = mark_stats(CAP / f"{name}-mark.png") if st is None: print(f"{name[:12]} 跳过") continue shape, ch, ratio, bbox = st print(f"{name[:12]} mark={shape[:2]} ch={ch} alpha>128占比={ratio:.2f} 有效bbox={bbox}") try: m = cv2.imread(str(CAP / f"{name}-mark.png"), cv2.IMREAD_UNCHANGED) if m is None or m.ndim < 2: print(" 读取失败,跳过可视化") continue a = m[..., 3] if m.ndim == 3 and m.shape[2] == 4 else np.full(m.shape[:2], 255, np.uint8) cv2.imwrite(str(OUT / f"{name[:12]}-alpha.png"), a) except Exception as e: print(f" 可视化失败: {e}") print(f"\nalpha 预览已写入 {OUT}/") if __name__ == "__main__": main()